Note: If you're using Claude Code specifically, see CLAUDE.md instead. This file is for general AI coding assistants (Cursor, Continue, Aider, Copilot, etc.).
This is an MCP (Model Context Protocol) server that gives AI assistants access to Mapbox documentation and reference materials. No Mapbox access token is required for most tools β it is a documentation-only server.
- Runtime: Node.js 22+
- Language: TypeScript (strict mode)
- Build:
tshy(dual ESM/CJS output) - Testing: Vitest
- Package Manager: npm
src/
βββ index.ts # MCP server entry point
βββ config/toolConfig.ts # CLI argument parser
βββ constants/ # Static data (API endpoint definitions)
βββ resources/ # MCP resource implementations
β βββ BaseResource.ts # Abstract base class
β βββ resourceRegistry.ts # Resource registration
β βββ utils/docParser.ts # Shared doc parsing utilities
β βββ */ # Individual resource implementations
βββ tools/ # MCP tool implementations
β βββ BaseTool.ts # Abstract base class
β βββ toolRegistry.ts # Tool registration
β βββ */ # Individual tool implementations
βββ utils/
βββ httpPipeline.ts # HTTP pipeline (User-Agent, caching, retry)
βββ types.ts # Shared types
βββ versionUtils.ts
test/ # Mirrors src/ structure
- All tools extend
BaseTool<InputSchema, OutputSchema>(notMapboxApiBasedToolβ that is in a different repo) execute(input)receives only the validated input β noaccessTokenorcontextparameters- If a tool needs a Mapbox token, it must be a field in the input schema
- Register tools in
src/tools/toolRegistry.ts
export class MyTool extends BaseTool<typeof MyInputSchema> {
readonly name = 'my_tool';
constructor({ httpRequest }: { httpRequest: HttpRequest }) {
super({ inputSchema: MyInputSchema });
this.httpRequest = httpRequest;
}
protected async execute(
input: z.infer<typeof MyInputSchema>
): Promise<CallToolResult> { ... }
}- Never patch
global.fetchβ use the injectedhttpRequestfunction - Pass
httpRequestvia constructor so tools can be tested without network access - The shared
httpRequestfromsrc/utils/httpPipeline.tsadds User-Agent, 1-hour caching, and retry
- Use Vitest exclusively
- Mock all HTTP calls β no real network requests in tests
- Place tests in
test/mirroring thesrc/structure
npm install # Install dependencies
npm test # Run tests
npm run build # Compile TypeScript
npm run lint # ESLint
npm run format # Prettier check
npm run inspect:build # Test with MCP Inspector- Don't use
MapboxApiBasedToolβ it doesn't exist here, useBaseTool - Don't patch
global.fetchβ use thehttpRequestpipeline - Don't make real network calls in tests β mock
httpRequestwith a stub - Don't read the access token from an env variable β accept it as an input field if needed
- Don't commit without updating
CHANGELOG.mdβ add an entry underUnreleased
- Update
CHANGELOG.mdunder theUnreleasedsection - All tests must pass:
npm test - Lint and format must pass:
npm run lint && npm run format
- CLAUDE.md β detailed patterns and architecture
- CONTRIBUTING.md β contribution standards and code examples