Build MCP servers in minutes, not hours. One TypeScript function = one MCP tool. Zero boilerplate.
Next.js for MCP — a framework on top of the Model Context Protocol that prioritizes developer experience.
npm install mcpx-frameworkThe official MCP SDK requires managing transports, handling JSON-RPC, importing Zod, and writing repetitive boilerplate for every tool. MCPX reduces all of that to a single function per tool.
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: 'my-server', version: '1.0.0' });
server.tool(
'add',
'Add two numbers',
{ a: z.number().describe('First number'), b: z.number().describe('Second number') },
async ({ a, b }) => ({
content: [{ type: 'text', text: `${a} + ${b} = ${a + b}` }],
})
);
server.tool(
'greet',
'Greet someone',
{ name: z.string().describe('Name to greet') },
async ({ name }) => ({
content: [{ type: 'text', text: `Hello, ${name}!` }],
})
);
const transport = new StdioServerTransport();
await server.connect(transport);import { mcpx } from 'mcpx-framework';
const server = mcpx({ name: 'my-server', version: '1.0.0' });
server
.tool({
name: 'add',
description: 'Add two numbers',
parameters: { a: { type: 'number' }, b: { type: 'number' } },
handler: async ({ a, b }) => `${a} + ${b} = ${a + b}`,
})
.tool({
name: 'greet',
description: 'Greet someone',
parameters: { name: { type: 'string' } },
handler: async ({ name }) => `Hello, ${name}!`,
});
server.start();60% less code. Zero protocol knowledge. No Zod imports. Full type inference.
# Scaffold a new project
npx mcpx init my-server
cd my-server
npm install
# Dev mode with hot reload
npx mcpx devYour MCP server is ready. Connect it to Claude:
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["dist/index.js"],
"cwd": "/path/to/my-server"
}
}
}| Example | Tools | Description |
|---|---|---|
| Calculator | 2 | add, multiply — minimal hello-world |
| Filesystem | 3 | read_file, write_file, list_dir |
| GitHub | 2 | search_repos, get_issue |
| Web Fetch | 2 | fetch_url, fetch_headers |
mcpx init [name] # Scaffold a new project
mcpx dev # Hot-reload dev mode (watches src/, auto-restarts)
mcpx build # Production build → dist/Create a new MCP server instance.
const server = mcpx({
name: 'my-server', // Required — displayed in Claude
version: '1.0.0', // Required
description: '...', // Optional
});Register a tool. Returns the instance for chaining.
server.tool({
name: 'do_thing', // snake_case recommended
description: 'Does a thing', // Be specific — Claude reads this
parameters: {
input: {
type: 'string', // string | number | boolean | array | object
description: 'The input', // Optional
required: false, // Optional — defaults to true
},
},
handler: async ({ input }) => {
return 'done'; // string | object | CallToolResult
},
});Expose data to Claude as contextual content.
server.resource({
name: 'config',
description: 'Application configuration',
uri: 'config://app', // Optional — auto-generated if omitted
handler: async () => ({
content: JSON.stringify(config),
mimeType: 'application/json',
}),
});| Return type | Result |
|---|---|
string |
Sent as text content |
object / array |
JSON-stringified (pretty-printed) |
{ content: [...] } |
Passed through as raw MCP content |
If a handler throws, the error message is automatically returned as an MCP error result — no silent failures.
Starts the server via stdio transport. Call once, at the end.
MIT