mcp-orbit
v0.2.0
Published
MCP Server Framework — server, transports, tool registry, clients, and utilities
Maintainers
Readme
mcp-orbit
A lightweight framework for building and connecting Model Context Protocol (MCP) servers and clients in Node.js.
Build MCP-compliant tool servers with stdio or HTTP transport, define tools with Zod schemas, and connect to any MCP server from your application.
Features
- Server Framework — Register tools, resources, and prompts with a simple API
- Dual Transport — Stdio (for local/CLI use) and HTTP (for remote servers)
- Client Libraries — Connect to any MCP server (stdio or HTTP) from your app
- Zod Integration — Define tool input schemas with Zod, auto-converted to JSON Schema
- Resource System — RFC 6570 URI templates for dynamic resources
- Prompt Registry — Templated prompts with argument validation
- CLI Helpers —
--stdio/--httpargument parsing out of the box
Install
npm install mcp-orbitQuick Start
Build a Tool Server
import { registerTool, startServer, parseArgs, applyPreInit } from "mcp-orbit";
import { z } from "zod";
// Define a tool with Zod schema
registerTool({
name: "greet",
description: "Greet someone by name",
inputSchema: z.object({
name: z.string().describe("Name of the person to greet"),
}),
execute: async ({ name }) => ({
content: [{ type: "text", text: `Hello, ${name}!` }],
}),
});
// Start the server (auto-detects --stdio or --http from CLI args)
const config = parseArgs();
applyPreInit(config);
const server = startServer(config);Run it:
# Stdio mode (for Claude Desktop, local integrations)
node dist/index.js --stdio
# HTTP mode (for remote access)
node dist/index.js --http --http-port=8080Connect to an MCP Server
import { StdioMCPClient, HttpMCPClient } from "mcp-orbit";
// Connect to a local stdio server
const local = new StdioMCPClient({
name: "my-plugin",
command: "node",
args: ["./plugins/my-plugin/dist/index.js", "--stdio"],
});
const tools = await local.listTools();
const result = await local.callTool("greet", { name: "World" });
// Connect to a remote HTTP server
const remote = new HttpMCPClient({
name: "remote-api",
url: "https://api.example.com/mcp/",
headers: { Authorization: "Bearer sk-..." },
});
const remoteTools = await remote.listTools();API Reference
Server
| Export | Description |
|--------|-------------|
| registerTool(tool) | Register a tool with name, schema, and execute function |
| startServer(config) | Start the MCP server with the given transport config |
| createMCPServer() | Create the underlying MCP SDK Server instance |
| executeTool(name, args) | Execute a registered tool by name |
| getTool(name) | Get a registered tool definition |
| getToolCount() | Number of registered tools |
| getToolDefinitions() | All tool schemas for MCP ListTools |
| startHttpServer(port, host, server) | Start HTTP transport directly |
| startStdioServer(server) | Start stdio transport directly |
Clients
Both StdioMCPClient and HttpMCPClient implement the IMcpClient interface:
interface IMcpClient {
listTools(timeoutMs?: number): Promise<{ tools: MCPToolSchema[] }>;
callTool(name: string, args: Record<string, any>, timeoutMs?: number): Promise<MCPToolResponse>;
listResources(timeoutMs?: number): Promise<MCPResourceList>;
readResource(uri: string, timeoutMs?: number): Promise<MCPResourceContent>;
listPrompts(timeoutMs?: number): Promise<MCPPromptList>;
getPrompt(name: string, args?: Record<string, any>, timeoutMs?: number): Promise<MCPPromptResponse>;
close(): Promise<void>;
}StdioMCPClient
Spawns a local child process and communicates via stdin/stdout.
const client = new StdioMCPClient({
name: "my-server",
command: "node",
args: ["./server.js", "--stdio"],
env: {
API_KEY: "${MY_API_KEY}", // Resolved from process.env
},
cwd: "./plugins",
});Environment variables with ${VAR_NAME} syntax are automatically resolved from process.env.
HttpMCPClient
Connects to a remote MCP server over HTTP (Streamable HTTP transport, Protocol 2025-03-26).
const client = new HttpMCPClient({
name: "remote",
url: "https://api.example.com/mcp/",
headers: { Authorization: "Bearer sk-..." },
timeout_ms: 15000,
});Resources
Register resources with static URIs or RFC 6570 templates:
import { createAndRegisterResource } from "mcp-orbit";
createAndRegisterResource({
uri: "config://app/settings",
name: "App Settings",
description: "Current application configuration",
mimeType: "application/json",
read: async () => JSON.stringify({ theme: "dark" }),
});Prompts
Register prompt templates with optional argument validation:
import { createAndRegisterPrompt } from "mcp-orbit";
import { z } from "zod";
createAndRegisterPrompt({
name: "analyze-data",
description: "Analyze a dataset",
arguments: [
{ name: "dataset", description: "Dataset name", required: true },
{ name: "format", description: "Output format", required: false },
],
inputSchema: z.object({
dataset: z.string(),
format: z.enum(["json", "csv"]).default("json"),
}),
render: async ({ dataset, format }) => ({
messages: [
{ role: "user", content: { type: "text", text: `Analyze ${dataset} as ${format}` } },
],
}),
});Utilities
| Export | Description |
|--------|-------------|
| createLogger(scope) | Scoped, colored console logger |
| zodToMcpJsonSchema(schema) | Convert Zod schema to MCP JSON Schema |
| HTTPClient | Lightweight HTTP client for tool implementations |
| parseArgs() | Parse --stdio / --http CLI arguments |
| applyPreInit(config) | Configure stderr logging for stdio mode |
Building Plugins
Create an MCP plugin as a standalone npm package:
// my-plugin/src/index.ts
import { registerTool, startServer, parseArgs, applyPreInit } from "mcp-orbit";
import { z } from "zod";
// Register your tools
registerTool({
name: "my_tool",
description: "Does something useful",
inputSchema: z.object({
input: z.string(),
}),
execute: async ({ input }) => ({
content: [{ type: "text", text: `Processed: ${input}` }],
}),
});
// Start server
const config = parseArgs();
applyPreInit(config);
startServer(config);Then use it as a stdio plugin from any MCP client:
node ./node_modules/my-plugin/dist/index.js --stdioTransport Modes
| Mode | Flag | Use Case |
|------|------|----------|
| Stdio | --stdio | Local integrations, Claude Desktop, CLI tools |
| HTTP | --http | Remote servers, multi-client access |
HTTP mode supports session management, bearer token auth, health checks (/health), and graceful shutdown.
Requirements
- Node.js >= 20.0.0
- TypeScript (recommended)
License
MIT
