mcp-lite
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-litecreate a server with a 'get_time' tool that returns current time"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 consumer100% protocol compliant — MCP spec 2025-11-25
Comparison
|
| |
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 |
Related MCP server: MCP Template
Quick Start
1. Install
bun add mcp-lite zod2. 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.tsThat'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 timeProtocol Maps use lazy getters (7 Maps created on-demand)
isTerminal()inlined to eliminateexperimental/tasks/interfaces.jschainType 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 ( | ✅ |
Tools ( | ✅ |
Resources ( | ✅ |
Resource Templates | ✅ |
Prompts ( | ✅ |
Completions ( | ✅ |
Logging ( | ✅ |
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.jsonKnown 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 testSecurity
If you discover a security vulnerability, please report it responsibly. See SECURITY.md for details.
License
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/srsergi0/mcp-lite'
If you have feedback or need assistance with the MCP directory API, please join our Discord server