mcp-stdio
v0.1.0
Published
Zero-dependency MCP server for stdio transport. Just tools, nothing else.
Maintainers
Readme
mcp-stdio
Zero-dependency MCP server for stdio transport. Just tools, nothing else.
Why
The official MCP SDK has 17 dependencies (Express, Hono, OAuth, JWT...). Most MCP servers just need stdio + tools. This package is 222 lines, zero runtime dependencies.
| | @modelcontextprotocol/sdk | mcp-stdio |
|---|---|---|
| Dependencies | 17 | 0 |
| Transport | stdio, HTTP, SSE | stdio |
| Features | tools, resources, prompts, sampling, auth | tools |
| Lines | ~5000+ | 222 |
Install
npm install mcp-stdioUsage
import { createMcpServer } from 'mcp-stdio';
createMcpServer({
name: 'my-server',
version: '1.0.0',
tools: {
greet: {
description: 'Say hello',
parameters: {
type: 'object',
properties: { name: { type: 'string' } },
required: ['name'],
},
handler: async ({ name }) => `Hello ${name}!`,
},
add: {
description: 'Add two numbers',
parameters: {
type: 'object',
properties: {
a: { type: 'number' },
b: { type: 'number' },
},
required: ['a', 'b'],
},
handler: async ({ a, b }) => `${Number(a) + Number(b)}`,
},
},
});Configure in Claude Code
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["my-server.js"]
}
}
}API
createMcpServer(options)
Starts an MCP server reading JSON-RPC from stdin, writing to stdout.
Options:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | yes | Server name (shown to clients) |
| version | string | no | Server version (default: '0.1.0') |
| tools | Record<string, ToolDefinition> | yes | Tool definitions |
ToolDefinition:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| description | string | yes | What the tool does |
| parameters | JsonSchema | no | JSON Schema for input |
| handler | (params) => Promise<string \| ToolContent[]> | yes | Implementation |
Handler return types:
string— wrapped as[{ type: 'text', text: '...' }]ToolContent[]— returned as-is (supportstext,image,resource)
Errors in handlers are caught and returned as { isError: true, content: [{ type: 'text', text: 'Error: ...' }] } — the server never crashes.
What it implements
- JSON-RPC 2.0 over stdio (newline-delimited)
initializewith capability negotiationtools/listwith JSON Schema input schemastools/callwith structured content responsesping- Proper error codes (-32700, -32600, -32601, -32603)
- Notification handling (no response for messages without
id) - Logs to stderr (stdout is protocol-only)
What it doesn't implement
- HTTP/SSE/Streamable HTTP transport
- Resources, Prompts, Sampling
- OAuth, authentication
- Schema validation (trusts the caller — your handler validates)
These are intentional omissions. If you need them, use the official SDK.
License
MIT
