@AGENTS.local.md
ADRs (docs/adr/NNN-slug.md): Architectural decisions (reference as ADR-NNN)
SPECs (docs/specs/slug.md): Design specifications (reference as SPEC-slug)
# URL mode (primary)
npx mcp-client-gen <url> # Generate to stdout
npx mcp-client-gen <url> -o <file> # Generate to file
npx mcp-client-gen <url> <file> # Shorthand
# Config mode (uses .mcp.json, .cursor/, .vscode/)
npx mcp-client-gen # Interactive
npx mcp-client-gen -y # Quick defaultsbun test # Unit tests only (src/)
bun test:e2e # E2E tests only (test/e2e/)
bun test:all # Run all tests
bun typecheck # TypeScript check
bun format # Format code with Prettier
bun format:check # Check code formatting
bun validate # Full validation (format, typecheck, tests)bun capture:notion # Capture fixtures + generate example
bun capture:notion --fixtures-only # Capture fixtures only
bun smoke:notion # Smoke test generated client (no server)
bun e2e:notion # E2E test with real Notion servermcp-client-gen/
├── src/
│ ├── index.ts # Public API exports
│ ├── internal.ts # Internal API exports (mcp-client-gen/internal)
│ │
│ # CLI & User Interface
│ ├── cli.ts # CLI entry - argument parsing, execution modes
│ ├── prompts.ts # Interactive prompts (@clack/prompts)
│ │
│ # Configuration
│ ├── config.ts # MCP config loading (.mcp.json, .cursor/, .vscode/)
│ ├── types.ts # Core type definitions (McpServerConfig)
│ │
│ # MCP Protocol
│ ├── mcp-client.ts # MCP connection (HTTP/SSE), OAuth via oauth-callback
│ ├── introspection.ts # Server capability discovery and caching
│ │
│ # Code Generation
│ ├── codegen/
│ │ ├── index.ts # Codegen module exports
│ │ ├── file-builder.ts # Assembles complete TypeScript file
│ │ ├── class-generator.ts # Client class with tool/resource methods
│ │ ├── tool-input-generator.ts # Tool input interfaces
│ │ ├── schema-to-typescript.ts # JSON Schema → TypeScript types
│ │ └── utils.ts # camelCase, pascalCase helpers
│ │
│ ├── pipeline.ts # Pipeline orchestrator - coordinates all steps
│ └── utils.ts # Shared utilities
│
├── docs/
│ ├── adr/ # Architecture Decision Records
│ └── specs/ # Design specifications
│
├── test/
│ ├── e2e/ # End-to-end tests (.spec.ts)
│ ├── fixtures/ # Test fixtures
│ │ ├── notion/ # Real Notion server data
│ │ └── synthetic/ # Minimal/edge-case schemas
│ └── manual/ # Manual capture scripts
│
├── examples/ # Example generated clients
│ └── notion-client.ts
│
└── package.jsonCLI → Config → Connect → Introspect → Generate → Output
Keep module DAG clean: lower modules must not import from higher ones.
- Runtime: Always use Bun (not Node.js/NPM). Bun auto-loads .env files
- MCP SDK: OAuth/auth implementation in
node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js,node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.d.ts - Generated Client: Must be tree-shakable for optimal bundle size
- Design Philosophy: Prioritize ideal design over backward compatibility
- Throw errors for unrecoverable failures (missing config, all servers failed)
- Discriminated unions for per-item failures (introspection returns
{ ok: true, ... } | { ok: false, error }) - Console.warn for non-fatal issues (single capability fetch failure)
- Error messages: include context ("Tool 'search' error: ..."), never stack traces to users
- Files:
kebab-case.ts - Constants:
SCREAMING_SNAKE_CASE - Private fields:
_underscorePrefix
What to test:
- Pure functions (schema conversion, name extraction)
- Error conditions and edge cases
- Config parsing with various formats
What to mock:
- MCP server connections (use fixtures)
- File system for config discovery
- OAuth flows (use in-memory store)
Test file naming:
- Unit tests:
{module}.test.tsin same directory - E2E tests:
test/e2e/{feature}.spec.ts
import { generateClient, browserAuth } from "mcp-client-gen";generateClient(servers, options?)— generate TypeScript clientwriteGeneratedClient(path, code)— write generated code to filecreateMcpConnection(server, config?)— establish MCP connectionresolveConfigFiles(options?)— resolve config paths (explicit or discovery)getMcpServers(paths)— parse config files, returns{ servers, warnings }formatConfigWarning(warning)— format a config warning for displayfindMcpConfigFiles(cwd?)— discover config filesformatTypeScript(code, configPath?)— format code with PrettierbrowserAuth(),inMemoryStore(),fileStore()— OAuth helpers
Types: McpServerConfig, ConfigWarning, ParseServersResult, McpConnection, McpClientConfig, GenerationOptions, GenerationResult, IntrospectionResult, ResolveConfigOptions, Tool, Resource, Prompt, ServerCapabilities
import {
introspectServer,
jsonSchemaToTypeScript,
} from "mcp-client-gen/internal";Not covered by semver — use for custom pipelines:
introspectServer(),introspectServers()generateClientFile(),generateClientClass(),generateToolInterface(),generateToolOutputInterface()jsonSchemaToTypeScript(),hasOutputSchema(),MCP_CONFIG_PATHS,extractServerName()