Skip to content

Commit 77a7bd5

Browse files
jirispilkaMQ37
andauthored
feat: Add eslint from apify-core, add AGENTS.md (#351)
* feat: Add eslint config from apify-core --------- Co-authored-by: Jakub Kopecký <[email protected]>
1 parent a534789 commit 77a7bd5

25 files changed

+694
-205
lines changed

.editorconfig

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,32 @@
1+
# EditorConfig is a file format and collection of text editor plugins
2+
# for maintaining consistent coding styles between different editors and IDEs
3+
# See https://editorconfig.org for more information
4+
15
root = true
26

7+
# Apply to all files
38
[*]
49
indent_style = space
510
indent_size = 4
611
charset = utf-8
712
trim_trailing_whitespace = true
813
insert_final_newline = true
914
end_of_line = lf
15+
# Maximum line length (160 characters)
16+
# Note: editorconfig-tools is unable to ignore long strings or URLs, so this is informational
17+
# ESLint will enforce this limit with its max-len rule
18+
max_line_length = 160
19+
20+
# IntelliJ IDEA / WebStorm specific settings
21+
# These settings configure code formatting behavior in JetBrains IDEs
22+
# They ensure consistent formatting when using IDE auto-format features
23+
# - Adds spaces within TypeScript import braces: import { a, b } instead of import {a,b}
24+
ij_typescript_spaces_within_imports = true
25+
# - Adds spaces within JavaScript import braces: import { a, b } instead of import {a,b}
26+
ij_javascript_spaces_within_imports = true
27+
# - Adds spaces within TypeScript union types: string | number instead of string|number
28+
ij_typescript_spaces_within_union_types = true
29+
30+
# YAML files use 2-space indentation (YAML standard)
31+
[{*.yaml, *.yml}]
32+
indent_size = 2

AGENTS.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Apify MCP server development instructions
2+
3+
## Overview
4+
5+
The codebase is built with TypeScript using ES modules and follows a modular architecture with clear separation of concerns.
6+
7+
The server can run in multiple modes:
8+
- **Standard Input/Output (stdio)**: For local integrations and command-line tools like Claude Desktop
9+
- **HTTP Streamable**: For hosted deployments and web-based MCP clients
10+
- **Legacy SSE over HTTP**: Legacy version of the protocol for hosted deployments and web-based clients (deprecated and will be removed in the future)
11+
12+
### Root directories
13+
- `src/`: Main TypeScript source code
14+
- `tests/`: Unit and integration tests
15+
- `dist/`: Compiled JavaScript output (generated during build)
16+
- `evals/`: Evaluation scripts and test cases for AI agent interactions
17+
18+
### Core architecture (`src/` directory)
19+
20+
The codebase is organized into logical modules:
21+
22+
- `src/mcp/` - Core MCP protocol implementation
23+
- `src/tools/` - MCP tool implementations
24+
- `src/utils/` - Shared utility modules
25+
- `src/actor/` - Actor-specific implementation (for Apify platform deployment) (only used for testing)
26+
27+
- Entry points:
28+
- `src/index.ts` - Main library export (`ActorsMcpServer` class)
29+
- `src/index-internals.ts` - Internal exports for testing and advanced usage
30+
- `src/stdio.ts` - Standard input/output entry point (CLI, used for Docker)
31+
- `src/main.ts` - Actor entry point (for Apify platform)
32+
- `src/input.ts` - Input processing and validation
33+
34+
## Validating TypeScript changes
35+
36+
MANDATORY: Always check for TypeScript compilation errors before running tests or declaring work complete.
37+
38+
### TypeScript compilation steps
39+
40+
- Run `npm run type-check` to check for TypeScript errors without building
41+
- Run `npm run build` to compile TypeScript files and check for errors
42+
- Fix all compilation errors before running tests or committing changes
43+
44+
## Testing
45+
46+
### Running tests
47+
48+
- **Unit tests**: `npm run test:unit` (runs `vitest run tests/unit`)
49+
- **Integration tests**: `npm run test:integration` (requires build first, requires `APIFY_TOKEN`)
50+
51+
### Test structure
52+
53+
- `tests/unit/` - Unit tests for individual modules
54+
- `tests/integration/` - Integration tests for MCP server functionality
55+
- `tests/helpers.ts` - Shared test utilities
56+
- `tests/const.ts` - Test constants
57+
58+
### Test guidelines
59+
60+
- Write tests for new features and bug fixes
61+
- Use descriptive test names that explain what is being tested
62+
- Follow existing test patterns in the codebase
63+
- Ensure all tests pass before submitting a PR
64+
65+
## Coding guidelines
66+
67+
### Indentation
68+
69+
We use **4 spaces** for indentation (configured in `.editorconfig`).
70+
71+
### Naming conventions
72+
73+
- **Constants**: Use uppercase `SNAKE_CASE` for global, immutable constants (e.g., `ACTOR_MAX_MEMORY_MBYTES`, `SERVER_NAME`)
74+
- **Functions & Variables**: Use `camelCase` format (e.g., `fetchActorDetails`, `actorClient`)
75+
- **Classes, Types, Interfaces**: Use `PascalCase` format (e.g., `ActorsMcpServer`, `ActorDetailsResult`)
76+
- **Files & Folders**: Use lowercase `snake_case` format (e.g., `actor_details.ts`, `key_value_store.ts`)
77+
- **Booleans**: Prefix with `is`, `has`, or `should` (e.g., `isValid`, `hasFinished`, `shouldRetry`)
78+
- **Units**: Suffix with the unit of measure (e.g., `intervalMillis`, `maxMemoryBytes`)
79+
- **Date/Time**: Suffix with `At` (e.g., `createdAt`, `updatedAt`)
80+
- **Zod Validators**: Suffix with `Validator` (e.g., `InputValidator`)
81+
82+
### Types and interfaces
83+
84+
- Prefer `type` for flexibility.
85+
- Use `interface` only when it's required for class implementations (`implements`).
86+
87+
### Comments
88+
89+
- Use JSDoc style comments (`/** */`) for functions, interfaces, enums, and classes
90+
- Use `//` for generic inline comments
91+
- Avoid `/* */` multiline comments (single asterisk)
92+
- Use proper English (spelling, grammar, punctuation, capitalization)
93+
94+
### Code structure
95+
96+
- **Avoid `else`**: Return early to reduce indentation and keep logic flat
97+
- **Keep functions small**: Small, focused functions are easier to understand and test
98+
- **Minimal parameters**: Functions should only accept what they actually use
99+
- Use comma-separated parameters for up to 3 parameters
100+
- Use a single object parameter for more than 3 parameters
101+
- **Declare variables close to use**: Variables should be declared near their first use
102+
- **Extract reusable logic**: Extract complex or reusable logic into named helper functions
103+
104+
### Async functions
105+
106+
- Use `async` and `await` over `Promise` and `then` calls
107+
- Use `await` when you care about the Promise result or exceptions
108+
- Use `void` when you don't need to wait for the Promise (fire-and-forget)
109+
- Use `return await` when returning Promises to preserve accurate stack traces
110+
111+
### Imports and import ordering
112+
113+
- Imports are automatically ordered and grouped by ESLint:
114+
- Groups: builtin → external → parent/sibling → index → object
115+
- Alphabetized within groups
116+
- Newlines between groups
117+
- Use `import type` for type-only imports
118+
- Do not duplicate imports - always reuse existing imports if present
119+
- Do not use dynamic imports unless explicitly told to do so
120+
121+
### Error handling
122+
123+
- **User Errors**: Use appropriate error codes (4xx for client errors), log as `softFail`
124+
- **Internal Errors**: Use appropriate error codes (5xx for server errors), log with `log.exception` or `log.error`
125+
- Always handle and propagate errors clearly
126+
- Use custom error classes from `src/errors.ts` when appropriate
127+
128+
### Code quality
129+
130+
- All files must follow ESLint rules (run `npm run lint` before committing)
131+
- Prefer readability over micro-optimizations
132+
- Avoid mutating function parameters (use immutability when possible)
133+
- If mutation is necessary, clearly document and explain it with a comment
134+
- Clean up temporary files, scripts, or helper files created during development
135+
136+
## External dependencies
137+
138+
### Important relationship: apify-mcp-server-internal
139+
140+
**IMPORTANT**: This package (`@apify/actors-mcp-server`) is imported and used in the private repository `~/apify/apify-mcp-server-internal` for the hosted server implementation.
141+
142+
**Key points:**
143+
- Changes to this repository may affect the hosted server
144+
- Breaking changes must be coordinated between both repositories
145+
- The hosted server uses this package as a dependency
146+
- Canary releases can be created using the `beta` tag on PR branches (see README.md)
147+
148+
**Before making changes:**
149+
- Consider the impact on the hosted server
150+
- Test changes locally before submitting PRs
151+
- Coordinate breaking changes with the team
152+
- Check if changes require updates in `apify-mcp-server-internal`
153+
154+
## Development workflow
155+
156+
### Setup
157+
158+
1. Clone the repository
159+
2. Install dependencies: `npm install`
160+
3. Build the project: `npm run build`
161+
162+
### Development commands
163+
164+
- `npm run start:dev` - Start development server (uses `tsx` for direct TypeScript execution)
165+
- `npm run build` - Build TypeScript to JavaScript
166+
- `npm run lint` - Run ESLint
167+
- `npm run lint:fix` - Fix ESLint issues automatically
168+
- `npm run type-check` - Type check without building
169+
- `npm run test` - Run unit tests
170+
- `npm run test:integration` - Run integration tests (requires build)
171+
- `npm run clean` - Clean build artifacts

0 commit comments

Comments
 (0)