Lite
БесплатноНе проверенUltra-lightweight MCP server for Bun with full protocol compliance. Enables building MCP servers with tools, resources, and prompts using minimal dependencies a
Описание
Ultra-lightweight MCP server for Bun with full protocol compliance. Enables building MCP servers with tools, resources, and prompts using minimal dependencies and heap footprint.
README
mcp-lite
Ultra-lightweight MCP server for Bun. Zero Express, zero ajv, zero jose.
Full protocol compliance. ~5MB heap. Drop-in replacement for @modelcontextprotocol/sdk.
Quick Start · Why · Performance · API · Migration · Contributing
Why mcp-lite?
The official @modelcontextprotocol/sdk pulls in Express 5, ajv, jose, cors and 27+ transitive dependencies — adding ~150-200MB to your heap. If you're building on Bun + Hono, you don't need any of that.
mcp-lite extracts the exact same MCP protocol implementation from the official SDK, strips the bloat, and gives you:
- 50% faster module load — Zod schemas lazy-loaded on first message, not at import
- 78% less heap — 5MB vs 150-200MB
- Zero Express — uses Hono (which you already have)
- Zero ajv — passthrough JSON Schema validator
- Full TypeScript types — complete
.d.tsdeclarations for any consumer - 100% protocol compliant — MCP spec 2025-11-25
Comparison
@modelcontextprotocol/sdk |
mcp-lite |
|
|---|---|---|
| Dependencies | Express 5, ajv, jose, cors, eventsource... | zod + hono (peer) |
| Heap footprint | ~150-200MB | ~5MB |
| Module load | ~190ms | ~93ms |
| Transports | stdio, SSE, Streamable HTTP | stdio, Streamable HTTP |
| Protocol version | 2025-11-25 | 2025-11-25 |
| TypeScript | Full | Full |
| Runtime | Node.js, Bun, Deno | Bun (optimized) |
| OAuth | Built-in | Not included (use Hono middleware) |
| Package size | ~2.5MB unpacked | ~50KB unpacked |
Quick Start
1. Install
bun add mcp-lite zod
2. Create a server
import { McpServer, StdioServerTransport } from "mcp-lite";
import { z } from "zod";
const server = new McpServer({
name: "my-server",
version: "1.0.0",
});
server.tool(
"get_weather",
"Get current weather for a city",
{ city: z.string().describe("City name") },
async ({ city }) => ({
content: [{ type: "text", text: `Weather in ${city}: Sunny, 72°F` }],
})
);
const transport = new StdioServerTransport();
await server.connect(transport);
3. Run it
bun run my-server.ts
That's it. Your MCP server is running over stdio.
HTTP Transport (Hono)
import { McpServer, WebStandardStreamableHTTPServerTransport } from "mcp-lite";
import { Hono } from "hono";
import { z } from "zod";
const server = new McpServer({
name: "my-server",
version: "1.0.0",
});
server.tool(
"search",
"Search for items",
{ query: z.string() },
async ({ query }) => ({
content: [{ type: "text", text: `Results for: ${query}` }],
})
);
const transport = new WebStandardStreamableHTTPServerTransport({
sessionIdGenerator: () => crypto.randomUUID(),
});
await server.connect(transport);
const app = new Hono();
app.all("/mcp", (c) => transport.handleRequest(c.req.raw));
export default app;
Performance
mcp-lite is designed for cold-start performance. Here's what happens when your server starts:
Module load: 93ms (vs 190ms official SDK)
types-base: 0.1ms (ErrorCode, McpError, type guards)
protocol: 12ms (lazy Maps, inlined isTerminal)
server: 8ms (lazy task helpers)
zod: 90ms (DEFERRED — only loads on first message)
Key optimizations:
- Zod schemas compile on first
tools/call, not at import time - Protocol Maps use lazy getters (7 Maps created on-demand)
isTerminal()inlined to eliminateexperimental/tasks/interfaces.jschain- Type guards use duck-typing, not
Zod.safeParse()
API Reference
McpServer
High-level server with declarative registration.
const server = new McpServer({
name: "my-server", // Required
version: "1.0.0", // Required
title: "My Server", // Optional
description: "...", // Optional
instructions: "...", // Optional
});
server.tool(name, description?, schema?, annotations?, handler)
Register a tool.
// Full signature
server.tool(
"get_weather",
"Get weather for a city",
{ city: z.string() },
{ readOnlyHint: true },
async ({ city }, extra) => ({
content: [{ type: "text", text: `Sunny in ${city}` }],
})
);
// Shorthand (no description)
server.tool("ping", {}, async () => ({
content: [{ type: "text", text: "pong" }],
}));
// Shorthand (no parameters)
server.tool("version", "Get version", async () => ({
content: [{ type: "text", text: "1.0.0" }],
}));
server.resource(uri, nameOrHandler?, handler?)
Register a static resource.
server.resource("config://app", "App Config", async (uri) => ({
contents: [{ uri, mimeType: "application/json", text: '{"key":"value"}' }],
}));
server.resourceTemplate(uriTemplate, handler)
Register a dynamic resource template.
server.resourceTemplate("users://{userId}/profile", async (uri, params) => ({
contents: [{ uri, text: `Profile for ${params.userId}` }],
}));
server.prompt(name, description?, handler)
Register a prompt.
server.prompt("greeting", "Generate a greeting", async (args) => ({
messages: [{
role: "user",
content: { type: "text", text: `Hello ${args.name}!` },
}],
}));
Notifications
server.sendToolListChanged();
server.sendResourceListChanged();
server.sendResourceUpdated("resource://my-resource");
server.sendPromptListChanged();
server.sendLogMessage("info", "Something happened");
Server
Low-level server with direct protocol handling.
import { Server } from "mcp-lite";
const server = new Server(
{ name: "my-server", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
server.setRequestHandler("tools/list", async () => ({
tools: [{ name: "ping", description: "Ping pong" }],
}));
server.setRequestHandler("tools/call", async (request) => ({
content: [{ type: "text", text: "pong" }],
}));
Transports
StdioServerTransport
import { StdioServerTransport } from "mcp-lite";
const transport = new StdioServerTransport();
await server.connect(transport);
WebStandardStreamableHTTPServerTransport
import { WebStandardStreamableHTTPServerTransport } from "mcp-lite";
const transport = new WebStandardStreamableHTTPServerTransport({
sessionIdGenerator: () => crypto.randomUUID(),
enableJsonResponse: true, // Return JSON instead of SSE
onsessioninitialized: (id) => console.log(`Session ${id}`),
onsessionclosed: (id) => console.log(`Closed ${id}`),
});
await server.connect(transport);
// In your Hono app
app.all("/mcp", (c) => transport.handleRequest(c.req.raw));
InMemoryTransport
For testing.
import { InMemoryTransport } from "mcp-lite";
const transport = new InMemoryTransport();
await server.connect(transport);
Error Handling
import { McpError, ErrorCode } from "mcp-lite";
throw new McpError(ErrorCode.ToolNotFound, "Tool not found: my-tool");
Type Guards
import {
isJSONRPCRequest,
isJSONRPCNotification,
isJSONRPCResponse,
isJSONRPCError,
isInitializeRequest,
isInitializedNotification,
isCompletable,
} from "mcp-lite";
if (isJSONRPCRequest(message)) {
// handle request
}
Migration from Official SDK
1. Change the import
- import { McpServer, StdioServerTransport } from "@modelcontextprotocol/sdk";
+ import { McpServer, StdioServerTransport } from "mcp-lite";
2. Remove Express dependencies
- import express from "express";
- import cors from "cors";
+ import { Hono } from "hono";
3. Update transport instantiation
- const transport = new StreamableHTTPServerTransport({
- sessionIdGenerator: () => crypto.randomUUID(),
- });
+ const transport = new WebStandardStreamableHTTPServerTransport({
+ sessionIdGenerator: () => crypto.randomUUID(),
+ });
4. Update route handler
- app.use("/mcp", cors());
- app.all("/mcp", express.json(), (req, res) => transport.handleRequest(req, res));
+ app.all("/mcp", (c) => transport.handleRequest(c.req.raw));
5. That's it
Everything else (tool registration, resource handling, prompts) works exactly the same.
Protocol Compliance
Implements MCP spec 2025-11-25:
| Feature | Status |
|---|---|
Lifecycle (initialize, initialized, ping) |
✅ |
Tools (tools/list, tools/call) |
✅ |
Resources (resources/list, resources/read) |
✅ |
| Resource Templates | ✅ |
Prompts (prompts/list, prompts/get) |
✅ |
Completions (completion/complete) |
✅ |
Logging (logging/setLevel) |
✅ |
| Progress notifications | ✅ |
| Cancellation | ✅ |
| Subscriptions | ✅ |
| Pagination (cursor-based) | ✅ |
| Streamable HTTP (POST/GET/DELETE) | ✅ |
| SSE streaming | ✅ |
| Session management | ✅ |
| Tool annotations | ✅ |
Project Structure
mcp-lite/
├── src/
│ ├── index.js # Barrel exports (from types-base.js)
│ ├── index.d.ts # Barrel type declarations
│ ├── types-base.js # Non-Zod exports (0ms load)
│ ├── types-base.d.ts # Non-Zod type declarations
│ ├── types.js # Zod schemas (lazy-loaded)
│ ├── inMemory.js # InMemoryTransport
│ ├── server/
│ │ ├── mcp.js # McpServer (high-level)
│ │ ├── index.js # Server (low-level)
│ │ ├── stdio.js # StdioServerTransport
│ │ ├── webStandardStreamableHttp.js # HTTP transport
│ │ ├── completable.js # Completable helper
│ │ ├── zod-compat.js # Zod v3/v4 compatibility
│ │ └── zod-json-schema-compat.js # Zod → JSON Schema
│ ├── shared/
│ │ ├── protocol.js # Protocol base class
│ │ ├── transport.js # Transport interface
│ │ └── stdio.js # Shared stdio helpers
│ ├── validation/
│ │ ├── ajv-provider.js # PassthroughJsonSchemaValidator
│ │ └── index.js # Validation barrel
│ └── experimental/
│ └── tasks/ # Task-augmented execution
├── FEATURES.md # Full feature list & limitations
├── package.json
└── tsconfig.json
Known Limitations
- No OAuth — Use Hono middleware for auth
- No Express transport — Use Hono (which you should be using anyway)
- Bun optimized — Node.js may work but is not tested
- Lazy Zod — First
tools/callhas ~90ms overhead while Zod loads
Contributing
Contributions are welcome! Please read our Contributing Guidelines before submitting a PR.
# Clone the repo
git clone https://github.com/srsergi0/mcp-lite.git
# Install dependencies
bun install
# Run typecheck
bun tsc --noEmit
# Run tests
bun test
Security
If you discover a security vulnerability, please report it responsibly. See SECURITY.md for details.
License
Built with ❤️ for the MCP community.
Установка Lite
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/srsergi0/mcp-liteFAQ
Lite MCP бесплатный?
Да, Lite MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Lite?
Нет, Lite работает без API-ключей и переменных окружения.
Lite — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Lite в Claude Desktop, Claude Code или Cursor?
Открой Lite на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare Lite with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
