Building MCP servers for Claude & Cursor? Here's a starting point.
Most MCP servers I see in the wild start as a quick script and stay that way - no validation, no structured logging, no tests, and a deploy story that means shipping node_modules around. I got tired of rebuilding the same scaffolding every time a client project needed a Model Context Protocol server, so I open-sourced the template I now start every one from: ๐ mcp-server-template.
It's a production-ready TypeScript/Node.js foundation for building MCP servers that connect AI agents like Claude Desktop and Cursor to your tools, data, and workflows.
Getting started takes four commands
git clone https://github.com/qmmughal/mcp-server-template.git
cd mcp-server-template && npm install
cp .env.example .env
npm run dev
That spins up a working server in watch mode. npm test runs the Vitest suite, npm run build bundles everything into a single dist/index.js with esbuild - no node_modules to deploy.
What a tool actually looks like
Every tool gets a Zod schema, a definition, and a handler - so a malformed AI payload gets rejected with a clean error instead of crashing your process:
const schema = z.object({
text: z.string().describe("The text to process"),
repeat: z.number().int().min(1).max(10).optional()
});
export async function handleExampleTool(args: unknown, service: ExampleService) {
return withErrorHandling("process_text", async () => {
const { text, repeat } = validateArgs(schema, args);
const result = await service.processText(text, repeat);
return { content: [{ type: "text", text: result }] };
});
}
Extending it for your own tools
- Drop a new file in
src/tools/following the same schema โ definition โ handler shape. - Register it in
src/tools/index.ts- add your definition to the tools list and a case to the switch statement that routesCallToolRequestto your handler. - Put your real logic in
src/services/so the protocol layer stays thin and your business logic stays unit-testable in isolation. - Resources (data the AI can read) and Prompts (reusable templates) follow the exact same pattern in their own folders - copy the example, rename, adjust the schema.
Structured pino logging routes safely to stderr throughout, so it never corrupts the MCP stdio transport regardless of what you add.
When you're ready to ship, tag a release and a GitHub Actions workflow publishes to both npm and the MCP Registry automatically:
git tag v1.0.0 && git push origin v1.0.0
The goal is simple - spend your time on the logic that makes your MCP server useful, not on re-solving logging, validation, and bundling for the fifth time.
It's MIT licensed and live on GitHub now. If you're building agentic AI integrations, I'd love feedback or a star: ๐ github.com/qmmughal/mcp-server-template
MCP #ModelContextProtocol #AgenticAI #TypeScript #OpenSource #AIEngineering #ClaudeAI
Comments
No comments yet. Start the discussion.