Composite MCP Server for Godot Engine. TypeScript, Node.js >= 24, bun, ESM.
bun install # Install dependencies
bun run build # tsc --build && esbuild CLI bundle
bun run check # Biome check + tsc --noEmit (CI command)
bun run check:fix # Auto-fix Biome issues
bun run test # vitest run (all tests)
bun run test:watch # vitest in watch mode
bun run dev # tsx watch dev server
# Run a single test file
bun x vitest run tests/helpers/errors.test.ts
# Run a single test by name
bun x vitest run -t "test name pattern"
# Mise shortcuts
mise run setup # Full dev environment setup
mise run lint # bun run check
mise run test # bun run test (vitest)
mise run fix # bun run check:fix- Indent: 2 spaces
- Line width: 120
- Quotes: Single quotes
- Semicolons: As needed (omit when possible)
- Trailing commas: All (JS/TS), None (JSON)
- Arrow parens: Always
(x) => ... - Line endings: LF
- Node.js builtins with
node:prefix (import { join } from 'node:path') - External packages (
@modelcontextprotocol/sdk,zod) - Internal modules (relative paths
./,../) - Use
import typefor type-only imports (enforced byverbatimModuleSyntax) - Always use
.jsextension in import paths (ESM/NodeNext requirement)
import { execSync } from 'node:child_process'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import type { GodotConfig } from './godot/types.js'
import { registerTools } from './tools/registry.js'strict: true,verbatimModuleSyntax: true,isolatedModules: true- Target: ES2024, Module: NodeNext
- Schema validation: Zod v4
| Element | Convention | Example |
|---|---|---|
| Functions/variables | camelCase | detectGodot(), envPath |
| Module constants | UPPER_SNAKE_CASE | SERVER_NAME, DEFAULT_TIMEOUT_MS |
| Interfaces/Types | PascalCase | GodotConfig, DetectionResult |
| Classes | PascalCase | GodotMCPError |
| Files/directories | kebab-case | scene-parser.ts, composite/ |
| Tool names/params | snake_case | input_map, project_path |
- Custom
GodotMCPErrorclass withcode,suggestion,detailsfields formatError()converts errors to MCP{ content, isError }response formatformatSuccess()andformatJSON()for consistent success responses- Bare
catch {}blocks only for expected failures (e.g., binary not found)
noUnusedImports: erroruseConst: erroruseTemplate: errornoExplicitAny: warn (not error)noUnusedVariables: warnnoNonNullAssertion: warn
src/
init-server.ts # Entry point
godot/ # Godot binary detection, headless execution, types
tools/
registry.ts # Tool definitions (P0-P3 priority) + routing
composite/ # One file per mega-tool (17 tools)
helpers/ # errors.ts, scene-parser.ts, godot-types.ts, project-settings.ts
tests/
fixtures.ts # Shared test fixtures
helpers/ # Unit tests for helper modules
composite/ # Integration tests for composite tools
/** */JSDoc on every exported function- File-level doc comment at top of every file describing the module
- No
@param/@returnstags -- rely on TypeScript types
Conventional Commits: type(scope): message. Only feat: and fix: are accepted (enforced by the commit-message hook).
- Biome check (
--diagnostic-level=error) - TypeScript check (
tsc --noEmit) - Tests on pre-push (
bun test)