4. Coding Rules
File Naming
- File names: Use
kebab-case(e.g.,update-readme.mjs,case-convert.ts) - Interface/type files: Use
kebab-case - Test files: Use
*.test.tsconvention - Build config files: Located under
packages/common/build/with.mjsextension
TypeScript Strong Typing Rules
- No
any: Avoid usingany. Thetool.tshandler type allowsanyfor MCP SDK interface compatibility only. For new code, preferunknownwith type guards. - Zod schemas: All tool input schemas are typed as
z.ZodRawShape - Generics: Use
toolDef<const TSchema extends z.ZodRawShape>()pattern for type-safe schema definitions consttype parameters: Preserve literal types when defining Zod schemas
Tool Writing Pattern
All tools must follow this structure:
toolDef(): Helper function with type inference (simple pass-through)defineTool(): Casts toAnyToolDeftype (used when converting to arrays in server.ts)text(): MCP ToolResult helper producing{ content: [{ type: "text", text: content }] }
Maximum File Length
- Tool definition files: Maximum 200 lines recommended (split into separate files when too many tools)
- Handler logic: Inline within tool definition files when possible. Extract shared logic into separate utility functions.
Documentation Helpers
packages/common/kit/skill.ts provides 3 helpers for generating README and Skill documents:
update-readme.mjs uses generateReadmeApiDocs() to generate API docs in README.md with tool signatures, parameters, return types, type definitions, CLI usage, and examples.
Import/Export Rules
- Named exports only (no default exports)
- Path alias:
@common→ thecommon/module (mapped to../common/index.ts)@/*→ the current package's ownsrc/*(self-reference). Defined in each package'stsconfig.jsonpaths; for tests the rootrstest.config.tsmaps@per package viaprojects.
- Relative vs alias: Use
@/for cross-directory imports (e.g.,server.ts→@/tools/index). Keep relative paths for same-directory siblings (e.g.,./system). - File extensions: Omit them (
moduleResolution: "Bundler"— tsc, tsup/esbuild, and rstest all resolve the.tsfile). Everything is bundled, so no runtime extension is required. - Re-export: Use
export { tools } from "./tools/system"to selectively re-export only what's needed
Comment Guidelines
- Tool descriptions: Write concisely in the
descriptionfield (rendered directly in README/Skill docs) - Zod describe: Add
.describe()for each parameter (displayed in README tables) - Code comments: Only use when explaining essential reasoning (always include a reason for
eslint-disablecomments) - Guidelines: Add usage notes to the
guidelinesarray as strings
Async Handling
- All tool handlers must be
asyncfunctions - Handle errors with
try/catchinside handlers, or usehandleCliError()for Zod error auto-formatting in CLI - The MCP SDK handles async errors internally for server mode
Global Error Handling
- CLI:
handleCliError()catchesZodErrorand converts to user-friendly messages - MCP Server: Top-level
catchinserver.tsterminates the process - Exceptions inside tool handlers are automatically converted to
CallToolResulterror responses by the MCP SDK