A powerful Node.js scaffold for the Model Context Protocol (MCP)
Now with persistent API key management (SQLite), live dashboard with key expiration, and modern TypeScript tooling.
MCP-FORGE is a modern, extensible Node.js server scaffold for building applications using the Model Context Protocol (MCP). It provides session management, API key handling, a live dashboard, and easy tool integration for rapid prototyping.
- MCP Server Integration (official MCP SDK)
- Secure API Key Management
- Automatic Session Lifecycle & Cleanup
- Real-time Dashboard (server stats, logs, API key expiration)
- Custom Tool System
- Express.js Middleware & Routing
- TypeScript Support
- SQLite database for API keys (
better-sqlite3) - Modern dev workflow with tsx
- Biome for formatting and linting
- Overview
- Features
- Installation
- Quick Start
- Usage
- Configuration
- API Reference
- Testing
- Code Quality
- Contributing
- License
Prerequisites
- Node.js (v18+)
- pnpm (recommended) or npm
Note: The database file mcp.db is auto-created and ignored by git.
Install dependencies
pnpm installDevelopment
pnpm run dev
# Uses tsx for fast TypeScript reloadingProduction
pnpm startOn startup, MCP-FORGE prints your API key:
🔑 API Key for MCP (use as Authorization: Bearer <token>): sk-xxxxxxxx...
🕒 API Key Expires In: 23h 59m 59s
Use this key in the Authorization header for all requests.
Basic greeting
{
"method": "tools/call",
"params": {
"name": "say_hello",
"arguments": {}
}
}Response: "Hello, world!"
Personalized greeting
{
"method": "tools/call",
"params": {
"name": "say_hello",
"arguments": {
"name": "Alice"
}
}
}Response: "Hello, Alice!"
Configure via environment variables or .env file:
| Variable | Default | Description |
|---|---|---|
| MCP_API_KEY | generated | API key for authentication |
| PORT | 8000 | Server port |
| MCP_DISABLE_AUTH | false | Disable API key authentication |
| MCP_KEY_PREFIX | sk- | Prefix for generated API keys |
| MCP_KEY_BYTE_LENGTH | 32 | Length (bytes) of API key |
| MCP_DB_PATH | mcp.db | SQLite DB file for API keys |
API keys are stored and auto-expire after 24 hours.
Main Exports
loadConfig()– Loads server configurationgenerateApiKey(prefix, byteLength)– Generates secure API keyssetApiKey(key, createdAt)– Store API key in DBgetApiKey()– Retrieve API key from DBisApiKeyExpired(createdAt)– Check expirationrenewApiKey(config)– Generate and store new keyfindAvailablePort(startPort)– Finds an open portpopulateTools(server)– Registers custom toolscleanupSession(sessionId)– Cleans up sessions
How to Add a Tool
All tools are defined in src/tools.ts. To add a new tool, edit the populateTools function and use server.tool().
Helper for making API requests (GET, POST, custom methods, request body, headers).
Signature:
const _makeRequest = async <T>(
api_url = API_URL,
{
method = "GET",
headers = {},
body = undefined,
}: {
method?: string;
headers?: HeadersInit;
body?: unknown;
} = {}
): Promise<T | null>GET Example:
const result = await _makeRequest<MyType>("https://api.example.com/data");POST Example:
const result = await _makeRequest<MyType>("https://api.example.com/data", {
method: "POST",
body: { key: "value" },
headers: { Authorization: "Bearer TOKEN" }
});Automatically sets Content-Type: application/json for non-string bodies.
Returns parsed JSON or null on error.
Example: Add a tool that calls an external API
// src/tools.ts
server.tool(
"get_todos",
"Retrieve a list of todos",
{},
async () => {
const todos = await _makeRequest<Array<{ id: string; name: string }>>("https://api.example.com/todos");
if (!todos || todos.length === 0) {
return { content: [{ type: "text", text: "No todos found." }] };
}
return {
content: [{ type: "text", text: todos.map(t => `ID: ${t.id}, Name: ${t.name}`).join("\n") }],
};
}
);See src/tools.ts for more examples and details.
Run all tests:
pnpm test
# All tests are TypeScript and cover DB logic, session management, and API endpoints.Format code:
pnpm format
# Uses Biome for formattingLint code:
pnpm lint
# Uses Biome for lintingPull requests and issues are welcome! Please run tests and lint before submitting.
Tip: The codebase is fully TypeScript and uses SQLite for persistent API key management. See src/db.ts for DB logic.
MIT
MCP-FORGE — Crafted for scalable, context-driven applications.
