@forgedevstack/forge-mcp
by yaghobieh
README.md
# @forgedevstack/forge-mcp
Tiny helper for building API-key-protected stdio [MCP](https://modelcontextprotocol.io) servers. Wraps the official `@modelcontextprotocol/sdk` so you define tools with plain JSON schemas — no zod, no boilerplate — and get a working server with one call.
Part of the [ForgeStack](https://github.com/yaghobieh) family of libraries.
## Install
```bash
npm install @forgedevstack/forge-mcp
```
## A working MCP server in under 20 lines
```ts
import { createMcpServer, textResult } from '@forgedevstack/forge-mcp';
const { start } = createMcpServer({
name: 'my-server',
version: '1.0.0',
apiKey: { envVar: 'MY_API_KEY' },
tools: [
{
name: 'echo',
description: 'Echo a message',
inputSchema: { type: 'object', properties: { message: { type: 'string' } }, required: ['message'] },
handler: (args) => textResult(String(args.message)),
},
],
});
start();
```
## API
### `createMcpServer(options): ForgeMcpServer`
| Option | Type | Description |
|---|---|---|
| `name` | `string` | Server name reported to MCP clients |
| `version` | `string` | Server version reported to MCP clients |
| `tools` | `McpToolDefinition[]` | Tools exposed via `tools/list` and `tools/call` |
| `apiKey` | `ApiKeyConfig` (optional) | API key resolution; omit if no key is needed |
Returns `{ server, apiKey, start }`:
- `server` — the underlying SDK `Server` instance for advanced use
- `apiKey` — the resolved API key (pass it to your API clients inside handlers)
- `start()` — connects a `StdioServerTransport` and begins serving
The API key is resolved eagerly, so a misconfigured server fails fast at startup instead of on the first tool call.
### Tool definition
```ts
interface McpToolDefinition {
name: string;
description: string;
inputSchema: JsonSchema;
handler: (args: Record<string, unknown>) => Promise<McpToolResult> | McpToolResult;
}
```
`inputSchema` is a plain JSON schema object (`type`, `properties`, `required`, `items`, `enum`, ...). Handler exceptions are caught and returned as `isError` results, and calls to unknown tool names return an `isError` result instead of crashing the server.
### API key config
```ts
interface ApiKeyConfig {
envVar?: string;
value?: string;
required?: boolean;
}
```
Precedence: `value` first, then `process.env[envVar]` (default env var: `MCP_API_KEY`). When `apiKey` is passed and the key is missing, `createMcpServer` throws unless `required: false`.
### Helpers
- `textResult(text)` — `{ content: [{ type: 'text', text }] }`
- `errorResult(text)` — same, with `isError: true`
- `resolveApiKey(config)` — standalone key resolution, same rules as above
- `DEFAULT_API_KEY_ENV_VAR` — `'MCP_API_KEY'`
## Wiring into an MCP client
Point your MCP client (Cursor, Claude Desktop, etc.) at your server script and pass the key through `env`:
```json
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["/path/to/my-server.js"],
"env": { "MY_API_KEY": "your-key-here" }
}
}
}
```
## License
MIT
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues