From claude-code-toolkit
Guides MCP server development with tool design, resource endpoints, prompt templates, and transport configuration using the MCP SDK.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-code-toolkit:mcp-developmentThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "project-tools",
version: "1.0.0",
});
server.tool(
"search_files",
"Search for files matching a glob pattern in the project directory",
{
pattern: z.string().describe("Glob pattern (e.g., '**/*.ts')"),
directory: z.string().optional().describe("Base directory to search from"),
},
async ({ pattern, directory }) => {
const files = await glob(pattern, { cwd: directory ?? process.cwd() });
return {
content: [
{
type: "text",
text: files.length > 0
? files.join("\n")
: `No files found matching ${pattern}`,
},
],
};
}
);
server.tool(
"run_query",
"Execute a read-only SQL query against the application database",
{
query: z.string().describe("SQL SELECT query to execute"),
limit: z.number().default(100).describe("Maximum rows to return"),
},
async ({ query, limit }) => {
if (!query.trim().toUpperCase().startsWith("SELECT")) {
return {
content: [{ type: "text", text: "Only SELECT queries are allowed" }],
isError: true,
};
}
const rows = await db.query(`${query} LIMIT ${limit}`);
return {
content: [{ type: "text", text: JSON.stringify(rows, null, 2) }],
};
}
);
server.resource(
"schema",
"db://schema",
"Current database schema with all tables, columns, and relationships",
async () => {
const schema = await db.query(`
SELECT table_name, column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'public'
ORDER BY table_name, ordinal_position
`);
return {
contents: [
{
uri: "db://schema",
mimeType: "application/json",
text: JSON.stringify(schema, null, 2),
},
],
};
}
);
server.resource(
"config",
"config://app",
"Application configuration (secrets redacted)",
async () => {
const config = await loadConfig();
const safe = redactSecrets(config);
return {
contents: [
{
uri: "config://app",
mimeType: "application/json",
text: JSON.stringify(safe, null, 2),
},
],
};
}
);
server.prompt(
"review-code",
"Review code changes for bugs, security issues, and style",
{
diff: z.string().describe("Git diff or code to review"),
focus: z.enum(["security", "performance", "style", "all"]).default("all"),
},
async ({ diff, focus }) => ({
messages: [
{
role: "user",
content: {
type: "text",
text: `Review this code diff. Focus: ${focus}\n\n${diff}`,
},
},
],
})
);
{
"mcpServers": {
"project-tools": {
"command": "node",
"args": ["./mcp-server/dist/index.js"],
"env": {
"DATABASE_URL": "postgres://localhost:5432/app"
}
},
"remote-server": {
"url": "https://mcp.example.com/sse",
"headers": {
"Authorization": "Bearer ${MCP_TOKEN}"
}
}
}
}
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const transport = new StdioServerTransport();
await server.connect(transport);
For HTTP-based servers, use the SSE transport for streaming responses to clients.
isError: true flag on error responsesisError: true with user-friendly messagesnpx claudepluginhub rohitg00/awesome-claude-code-toolkitBuilds MCP servers with Node/TypeScript SDK: register tools/resources/prompts, Zod validation, stdio/Streamable HTTP transports, debugging.
Provides patterns, architecture diagrams, and decision trees for building, testing, and deploying Model Context Protocol (MCP) servers in Python and TypeScript with tools, resources, prompts, and transports like stdio, SSE, streamable HTTP.
Builds MCP servers using Node/TypeScript SDK: tools, resources, prompts, Zod validation, stdio vs Streamable HTTP.