MCP Server Starter Kit
Allows an AI agent to interact with GitHub for repository, issue, and pull request management.
Allows an AI agent to interact with Notion pages, databases, and workspaces.
Allows an AI agent to interact with Redis data structures like strings, hashes, and lists.
Allows an AI agent to interact with Slack workspaces, send messages, and manage channels.
Allows an AI agent to interact with SQLite databases, executing queries and transactions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Server Starter Kitfetch https://example.com"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
π MCP Server Starter Kit
Production-ready Model Context Protocol (MCP) server boilerplate.
Ship your first MCP server in minutes, not days.
π Premium edition with Python (FastMCP) version, Railway/Render deploy configs, auth patterns, and 1-on-1 setup support β Get it on Gumroad β
What's included
Feature | Status |
TypeScript with strict mode | β |
Proper stderr logging (won't break MCP stdio) | β |
Token-bucket rate limiter | β |
Environment variable validation (Zod) | β |
Centralized error handling | β |
2 example tools (echo + fetch_url) | β |
Docker + docker-compose | π Premium |
Claude Desktop auto-config script | π Premium |
Unit test setup (Vitest) | β |
Python/FastMCP version | π Premium |
Railway one-click deploy | π Premium |
API key auth middleware | π Premium |
OAuth 2.0 integration pattern | π Premium |
Webhook receiver tool | π Premium |
Database connection pattern | π Premium |
Related MCP server: TypeScript MCP Server Boilerplate
Why this starter kit?
Every MCP server tutorial shows you a 30-line "hello world." Then you try to build something real and discover:
Logging to stdout breaks MCP β the protocol uses stdout for communication; your
console.logcorrupts itNo rate limiting β a runaway AI agent can hammer your APIs
No input validation β AI can send malformed arguments and crash your server
No error handling β unhandled exceptions crash the whole server
No deploy story β how do you actually run this in production?
This starter kit solves all of that from day one.
Quick start
Option 1: Use as a template
# Clone and rename
git clone https://github.com/srmcguirt/mcp-server-starter-kit my-mcp-server
cd my-mcp-server
# Install dependencies
npm install
# Copy env file and fill in your values
cp .env.example .env
# Start in dev mode (hot reload)
npm run devOption 2: Scaffold with npx
npx @srmcguirt/mcp-server-starter init my-server-name
cd my-server-name
npm install && npm run devOption 3: Install as a library
npm install @srmcguirt/mcp-server-starterAdd your first tool
Open src/tools/ and create a new file:
// src/tools/my-tool.ts
import { z } from 'zod';
import { toolResult } from '../lib/error-handler.js';
import type { MCPTool } from '../types.js';
const MyInputSchema = z.object({
query: z.string().min(1).max(500),
limit: z.number().int().positive().max(100).default(10),
});
export const myTool: MCPTool = {
name: 'my_tool',
description: 'Search for something and return results. Be specific about what this does β the AI reads this description.',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string', description: 'The search query' },
limit: { type: 'number', description: 'Max results to return', default: 10 },
},
required: ['query'],
},
async execute(args) {
const { query, limit } = MyInputSchema.parse(args);
// Your implementation here
const results = await myApi.search(query, { limit });
return toolResult(JSON.stringify(results, null, 2));
},
};Then register it in src/tools/index.ts:
import { myTool } from './my-tool.js';
export const tools: MCPTool[] = [
echoTool,
fetchUrlTool,
myTool, // π Add here
];Connect to Claude Desktop
# Build and add to Claude Desktop config automatically
chmod +x scripts/add-to-claude.sh
./scripts/add-to-claude.sh my-server-name
# Then restart Claude DesktopOr manually add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"my-server-name": {
"command": "node",
"args": ["/absolute/path/to/my-mcp-server/dist/index.js"],
"env": {
"MY_API_KEY": "your-key-here"
}
}
}
}Connect to Cursor / Cline / Windsurf
Add to your editor's MCP settings:
{
"mcp": {
"servers": {
"my-server-name": {
"command": "node",
"args": ["/absolute/path/to/my-mcp-server/dist/index.js"]
}
}
}
}Deploy with Docker
The Dockerfile, docker-compose config, and the Claude Desktop auto-register script ship with the premium edition:
Project structure
mcp-server-starter/
βββ src/
β βββ index.ts # Server entry point β wire everything together here
β βββ types.ts # MCPTool interface and shared types
β βββ lib/
β β βββ logger.ts # Winston logger β always logs to stderr
β β βββ rate-limiter.ts # Token-bucket rate limiter
β β βββ env.ts # Environment variable validation (Zod)
β β βββ error-handler.ts # Centralized error handling + toolResult helpers
β βββ tools/
β βββ index.ts # Tool registry β add your tools here
β βββ echo.ts # Example: simple string echo
β βββ fetch-url.ts # Example: HTTP fetch with timeout + size limit
βββ docker/
β βββ Dockerfile # Multi-stage production build
β βββ docker-compose.yml # Local development + production compose
βββ scripts/
β βββ add-to-claude.sh # Auto-add to Claude Desktop config
βββ .env.example # Required environment variables
βββ tsconfig.json # Strict TypeScript config
βββ package.jsonKey patterns
β Always log to stderr
// β WRONG β corrupts MCP protocol
console.log('something happened');
// β
CORRECT β logs to stderr, leaves stdout clean
logger.info('something happened');β Validate all input with Zod
// β WRONG β trusting AI-provided args
const { query } = args as { query: string };
// β
CORRECT β parse and validate
const { query } = MySchema.parse(args); // throws McpError on invalid inputβ Use withErrorHandling for every tool
// β WRONG β unhandled exceptions crash the server
async execute(args) {
return await riskyOperation(args);
}
// β
CORRECT β errors logged + safe message returned to AI
return withErrorHandling('my_tool', () => riskyOperation(args));π Premium Edition β $49
The open source version is a solid foundation. The Gumroad premium download adds:
β Python/FastMCP version (same patterns, same quality)
β API key authentication middleware
β OAuth 2.0 integration pattern (GitHub, Google, etc.)
β Railway + Render one-click deploy configs
β Database connection patterns (Postgres, SQLite, Redis)
β Webhook receiver tool template
β Streaming responses pattern
β MCP resources and prompts examples
β 30-min video walkthrough: building a real production MCP server
β 6 real-world example servers (GitHub, Notion, Slack, Postgres, filesystem, web search)
β Commercial license (use in client work and products)
FAQ
Q: Why TypeScript and not JavaScript?
A: MCP tool schemas need to match your implementation exactly. TypeScript catches mismatches at build time, not at 2am when an AI passes unexpected input.
Q: Why log to stderr?
A: MCP uses stdio transport β stdout carries the JSON-RPC protocol. Anything you write to stdout that isn't valid MCP JSON will corrupt the connection. The logger in this kit always writes to stderr.
Q: Can I use this with Python?
A: The Python/FastMCP version is in the premium edition. The patterns are identical β just in Python.
Q: Is this compatible with all MCP clients?
A: Yes. Uses the official @modelcontextprotocol/sdk. Tested with Claude Desktop, Cursor, Cline, and Windsurf.
Contributing
PRs welcome. See CONTRIBUTING.md.
License
MIT β free for personal and open source use.
Commercial license (client work, products, resale) included in the Premium Edition on Gumroad.
π¬ Stay Updated
Get a free sample prompt + updates when new tools ship:
β srmcguirt.dev
Available Tools
2 toolsechoA
Echo back a message. Use to verify the MCP server is working.
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | The message to echo back |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It states the core behavior ('Echo back a message') but does not add context about side effects, authentication, or limits. For a simple echo tool, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, with the purpose front-loaded and the usage context in the second sentence. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (one parameter, no output schema), and the description covers what it does and when to use it. The 'echo back' phrasing implies the return value, making it sufficiently complete for a test/debugging tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (the only parameter 'message' is described in the schema). The description adds no extra parameter info, aligning with the baseline 3 when the schema covers parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Echo back a message' clearly states the tool's function with a specific verb and resource. It is distinct from the sibling tool fetch_url, which fetches URLs, so there is no ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear context: 'Use to verify the MCP server is working.' It tells when to use the tool but does not explicitly mention alternatives or when-not-to-use cases, though these are not critical for an echo utility.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_urlA
Fetch the text content of a URL. Returns up to 100KB of content. Useful for reading web pages, APIs, or any HTTP endpoint.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | The URL to fetch | |
| max_bytes | No | Maximum response size in bytes (default: 100000, max: 1000000) | |
| timeout_ms | No | Request timeout in milliseconds (default: 10000, max: 30000) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavioral traits. It does mention the return size limit ('up to 100KB'), but this conflicts with the schema's max_bytes property which allows up to 1MB, creating ambiguity. The description also does not address response format, error behavior, redirects, or authentication, leaving key behavioral characteristics undefined.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is just two sentences, with the action front-loaded. Every sentence adds value: the first states the core function, the second notes the size limit and common use cases. There is no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple fetch tool with a documented schema and no output schema, the description is mostly adequate. However, it omits details about what 'text content' means (raw HTML vs extracted text), how errors are surfaced, and the fact that the 100KB limit is only the default and can be increased. These omissions, combined with the size-limit ambiguity, prevent a higher score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides descriptions for all three parameters, with 100% coverage. The description does not add any parameter-specific detail beyond what is already in the schema; it only generalizes about the return size. Per the rubric, with high schema coverage, the baseline score is 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb+resource pair: 'Fetch the text content of a URL.' This clearly distinguishes the tool from its sibling 'echo', which simply echoes input. The mention of HTTP endpoints further clarifies the tool's scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides usage context by stating it is 'Useful for reading web pages, APIs, or any HTTP endpoint.' However, it does not explicitly state when not to use the tool or mention alternatives beyond the sibling 'echo', which is clearly not an alternative. This earns a 4 for clear context without explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v1.0.0- First observed
echo - First observed
fetch_url
TDQS
Scored across 2 tools
Echo and fetch_url are completely distinct in purposeβone verifies connectivity, the other retrieves web content. There is no overlap or ambiguity between them.
Both names are imperative and lowercase, but one is a bare verb (echo) while the other follows a verb_noun pattern (fetch_url). This mixed convention, while readable, is not fully consistent.
Two tools is appropriate for a starter kit that aims to demonstrate basic MCP functionality, but the count feels thin compared to typical servers that offer more comprehensive operations.
The tool set covers the intended purpose of a starter kit: verifying server operation and fetching URL content. There are no obvious gaps for this narrow scope, though it lacks broader capabilities.
Maintenance
Related MCP Connectors
A simple Typescript MCP server built using the official MCP Typescript SDK and smithery/cli. Thisβ¦
- ArcjetOAuthcom.arcjet
An MCP server for Arcjet - the runtime security platform that ships with your AI code.
MCP-first toolbox for agents: KV storage, auth, queue, and utility tools. Free in early access.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA boilerplate project for quickly developing MCP servers with TypeScript, featuring example tools (calculator, greeting, time) and resources with Zod schema validation.-
- FlicenseNot gradedqualityDmaintenanceA boilerplate project for quickly developing MCP servers using TypeScript SDK, featuring example tools (calculator, greeting) and resources with Zod schema validation.-
- FlicenseNot gradedqualityDmaintenanceA boilerplate project for quickly developing MCP servers using TypeScript, featuring example implementations of tools (calculator, greetings) and resources (server info) with Zod schema validation.-
- FlicenseNot gradedqualityDmaintenanceA boilerplate project for quickly developing Model Context Protocol (MCP) servers using TypeScript SDK, with example implementations of tools (calculator, greetings) and resources (server info) using Zod schema validation.47 npm-