Skill: mcp-codegen

Understand and work with the TypeScript and Python code generated by mcp-server-builder.

7 stars

Best use case

Skill: mcp-codegen is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Understand and work with the TypeScript and Python code generated by mcp-server-builder.

Teams using Skill: mcp-codegen should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/mcp-codegen/SKILL.md --create-dirs "https://raw.githubusercontent.com/heldernoid/agentic-build-templates/main/projects/ai-llm-tools/mcp-server-builder/skills/mcp-codegen/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/mcp-codegen/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How Skill: mcp-codegen Compares

Feature / AgentSkill: mcp-codegenStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Understand and work with the TypeScript and Python code generated by mcp-server-builder.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# Skill: mcp-codegen

Understand and work with the TypeScript and Python code generated by mcp-server-builder.

---

## What Gets Generated

mcp-server-builder generates a single-file MCP server in TypeScript or Python. The generated file is a complete, runnable server that only needs stub functions filled in with real implementation logic.

---

## TypeScript Output Structure

Generated file: `<server-name>.ts`

```
1. File header comment (name, version, generator info)
2. Imports: @modelcontextprotocol/sdk
3. Server instantiation: new Server({ name, version })
4. TOOLS array: all tool definitions with inputSchema
5. ListToolsRequestSchema handler: returns TOOLS
6. CallToolRequestSchema handler: switch on tool name
7. Per-tool stub async functions with typed args
8. RESOURCES array: all resource definitions
9. ListResourcesRequestSchema handler
10. ReadResourceRequestSchema handler
11. Transport setup + server.connect()
```

### TypeScript tool stub signature

For a tool with input schema:
```json
{
  "properties": {
    "query": { "type": "string" },
    "limit": { "type": "integer" }
  },
  "required": ["query"]
}
```

The generated stub is:
```typescript
async function web_search(args: { query: string; limit?: number }) {
  // TODO: implement web_search logic
  throw new Error("Not implemented");
}
```

JSON Schema types map to TypeScript:
- `string` -> `string`
- `integer` / `number` -> `number`
- `boolean` -> `boolean`
- `array` -> `unknown[]`
- `object` -> `Record<string, unknown>`

Optional properties (not in `required`) get `?` suffix.

### Running TypeScript output

```bash
# Install deps
npm install @modelcontextprotocol/sdk zod

# Run (ts-node)
npx ts-node my-server.ts

# Or compile first
npx tsc my-server.ts --module commonjs --target es2020 --outDir dist
node dist/my-server.js
```

---

## Python Output Structure

Generated file: `<server_name>.py`

```
1. Module docstring (name, version, generator info)
2. Imports: asyncio, typing, mcp, mcp.server, mcp.types
3. server = Server("name")
4. @server.list_tools() handler returning list[types.Tool]
5. @server.call_tool() handler with if/elif dispatch
6. Per-tool stub async functions with type hints
7. @server.list_resources() handler
8. @server.read_resource() handler
9. async def main() with stdio_server context manager
10. if __name__ == "__main__": asyncio.run(main())
```

### Python tool stub signature

For the same schema:
```python
async def web_search(query: str, limit: int = 10) -> list[types.TextContent]:
    # TODO: implement web_search logic
    raise NotImplementedError()
```

JSON Schema types map to Python:
- `string` -> `str`
- `integer` -> `int`
- `number` -> `float`
- `boolean` -> `bool`
- `array` -> `list`
- `object` -> `dict`

Optional properties get default value `None` (or schema `default` if provided).

### Running Python output

```bash
# Install deps
pip install mcp

# Run
python my_server.py
```

---

## Claude Desktop Integration

After running the server, add it to Claude Desktop's `claude_desktop_config.json`:

### stdio transport (most common)

```json
{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["/absolute/path/to/my-server.js"]
    }
  }
}
```

For Python:
```json
{
  "mcpServers": {
    "my-server": {
      "command": "python",
      "args": ["/absolute/path/to/my_server.py"]
    }
  }
}
```

### sse transport

```json
{
  "mcpServers": {
    "my-server": {
      "url": "http://localhost:8080/sse"
    }
  }
}
```

### http transport

```json
{
  "mcpServers": {
    "my-server": {
      "url": "http://localhost:8080/mcp"
    }
  }
}
```

Config file locations:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`

---

## Filling in Stub Functions

The generated stubs have `throw new Error("Not implemented")` (TypeScript) or `raise NotImplementedError()` (Python). Replace them with real logic.

### TypeScript example: read_file

Generated stub:
```typescript
async function read_file(args: { path: string; encoding?: string }) {
  throw new Error("Not implemented");
}
```

Implemented:
```typescript
import { readFile as fsReadFile } from "node:fs/promises";

async function read_file(args: { path: string; encoding?: string }) {
  const encoding = (args.encoding ?? "utf-8") as BufferEncoding;
  const content = await fsReadFile(args.path, { encoding });
  const stat = await import("node:fs/promises").then(m => m.stat(args.path));
  return {
    content: [{ type: "text" as const, text: JSON.stringify({ content, size: stat.size }) }]
  };
}
```

### Python example: read_file

Generated stub:
```python
async def read_file(path: str, encoding: str = "utf-8") -> list[types.TextContent]:
    raise NotImplementedError()
```

Implemented:
```python
import aiofiles
import json
import os

async def read_file(path: str, encoding: str = "utf-8") -> list[types.TextContent]:
    async with aiofiles.open(path, encoding=encoding) as f:
        content = await f.read()
    size = os.path.getsize(path)
    result = json.dumps({"content": content, "size": size, "encoding": encoding})
    return [types.TextContent(type="text", text=result)]
```

---

## Tool Return Format

MCP tools return a list of content blocks. The generated code uses `TextContent` by default:

TypeScript:
```typescript
return {
  content: [{ type: "text", text: JSON.stringify(result) }]
};
```

Python:
```python
return [types.TextContent(type="text", text=json.dumps(result))]
```

For image content:
```typescript
return {
  content: [{ type: "image", data: base64Data, mimeType: "image/png" }]
};
```

---

## Adding to the Generated Code

After exporting, you may need to add:
- Environment variable reading (`process.env.API_KEY` / `os.environ["API_KEY"]`)
- HTTP client imports (`node-fetch`, `axios`, `httpx`, `aiohttp`)
- Database connections
- Authentication headers

The generated file is yours to modify. Re-export from mcp-server-builder if you add new tools or change schemas (not for implementation logic).

---

## Validation Rules

The code generator enforces these rules before generating:

| Rule | Detail |
|------|--------|
| Tool name | snake_case, no spaces, no hyphens |
| Schema depth | Max 3 levels of nested objects |
| Required fields | `name`, `description` per tool |
| URI template | Valid RFC 6570 syntax |
| Version | Semver format (1.0.0) |
| Transport | One of: stdio, sse, http |

If any rule is violated, the export endpoint returns a 400 error with a structured error list.

---

## Common Patterns

### Tool that calls an external API

```typescript
async function fetch_stock_price(args: { symbol: string }) {
  const resp = await fetch(`https://api.example.com/quote/${args.symbol}`);
  const data = await resp.json();
  return {
    content: [{ type: "text", text: JSON.stringify({
      symbol: args.symbol,
      price: data.price,
      change: data.change
    })}]
  };
}
```

### Tool that reads from a database

```typescript
import Database from "better-sqlite3";
const db = new Database("./data.db");

async function query_users(args: { name_filter?: string }) {
  const rows = name_filter
    ? db.prepare("SELECT * FROM users WHERE name LIKE ?").all(`%${args.name_filter}%`)
    : db.prepare("SELECT * FROM users").all();
  return {
    content: [{ type: "text", text: JSON.stringify(rows) }]
  };
}
```

### Resource handler

```typescript
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const uri = request.params.uri;
  // Match uri pattern and return content
  if (uri.startsWith("file://")) {
    const path = uri.replace("file://", "");
    const content = await readFile(path, "utf-8");
    return { contents: [{ uri, mimeType: "text/plain", text: content }] };
  }
  throw new Error(`Unknown resource: ${uri}`);
});
```

Related Skills

Skill: Uptime Monitoring

7
from heldernoid/agentic-build-templates

## Overview

Skill: Status Page

7
from heldernoid/agentic-build-templates

## Overview

Skill: unit-conversion

7
from heldernoid/agentic-build-templates

## Overview

Skill: recipe-scaler

7
from heldernoid/agentic-build-templates

## Overview

reading-list

7
from heldernoid/agentic-build-templates

Operate the reading-list API to save, manage, tag, search, and export articles.

email-digest

7
from heldernoid/agentic-build-templates

Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.

websocket-realtime

7
from heldernoid/agentic-build-templates

Use the WebSocket connection in poll-builder to receive live vote updates. Use when you need to stream real-time poll results, monitor a poll for new votes, or build a live dashboard. Triggers include "live results", "real-time updates", "stream votes", "watch poll", or "WebSocket".

poll-builder

7
from heldernoid/agentic-build-templates

Self-hosted poll creation tool with real-time results. Use when you need to create a poll, check vote counts, close a poll, export results, or get the shareable link for a poll. Triggers include "create poll", "vote", "poll results", "survey", "collect votes", "share poll", or any task involving polling or voting.

Skill: personal-finance

7
from heldernoid/agentic-build-templates

## Overview

Skill: csv-import

7
from heldernoid/agentic-build-templates

## Overview

Skill: Syntax Highlighting

7
from heldernoid/agentic-build-templates

## Purpose

Skill: Pastebin Core

7
from heldernoid/agentic-build-templates

## Purpose