Elysia MCP Adapter
Click on "Deploy 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., "@Elysia MCP Adapterget user with id user_123"
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.
@mwillbanks/elysia-mcp-adapter turns eligible Elysia HTTP routes into MCP tools while preserving the request lifecycle you already rely on: parsing, validation, hooks, guards, authentication, error handling, and response mapping. It also provides thin APIs for standalone tools, resources, resource templates, and prompts.
Why this adapter?
Keep Elysia in charge. Route-backed calls run through
app.handle(new Request(...)); handlers are never invoked out of band.Reuse schemas. Existing TypeBox and route schemas are normalized to JSON Schema for MCP clients.
Secure by default. Origin checks are enabled, model-controlled headers are denied, credential-bearing response headers are redacted, and binary responses are disabled.
Stay protocol-focused. The package is ESM-only and does not introduce a second application framework or translate TypeBox to Zod.
Related MCP server: Hono MCP Server
Install
bun add @mwillbanks/elysia-mcp-adapter elysiaNode.js >=20.11, Bun >=1.1, Elysia >=1.4, and TypeScript >=5.8 are supported.
Quick start
import { mcp } from '@mwillbanks/elysia-mcp-adapter'
import { Elysia, t } from 'elysia'
const app = new Elysia()
.use(
mcp({
server: {
name: 'users-api',
version: '1.0.0'
}
})
)
.get(
'/users/:id',
({ params }) => ({ id: params.id }),
{
params: t.Object({ id: t.String() }),
detail: {
operationId: 'users.get',
summary: 'Get a user'
}
}
)
.listen(3000)The adapter exposes GET /users/:id as the users.get MCP tool at POST /mcp. The default protocol is 2026-07-28. Modern clients send the required protocol, method, target, and Accept headers. Tool calls are converted to internal HTTP requests and sent back through Elysia:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users.get",
"arguments": {
"params": { "id": "user_123" }
},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": { "name": "example-client", "version": "1.0.0" },
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}Explicit MCP primitives
Install the plugin, then register MCP-only behavior alongside your HTTP routes:
const app = new Elysia()
.use(mcp({ allowedRoutes: [] }))
.mcpTool(
'math.add',
({ a, b }: { a: number; b: number }) => ({ sum: a + b }),
{
inputSchema: {
type: 'object',
properties: {
a: { type: 'number' },
b: { type: 'number' }
},
required: ['a', 'b'],
additionalProperties: false
}
}
)
.mcpResource('config://runtime', () => ({ environment: 'production' }))
.mcpPrompt(
'review-error',
({ message }: { message: string }) => `Review this error: ${message}`
)Routes become tools by default. Resources and prompts require explicit route metadata or the standalone methods above.
MCP extensions
Tasks, OAuth resource-server enforcement, enterprise authorization profiles, Apps, and Skills are opt-in:
app.use(
mcp({
transport: {
protocolVersions: ['2026-07-28', '2025-11-25']
},
extensions: {
tasks: {
version: 'current',
provider
},
auth: {
version: 'current',
resource: 'https://api.example.com/mcp',
authorizationServers: ['https://auth.example.com'],
verifyAccessToken
},
apps: {
version: 'current'
},
skills: {
version: 'current',
directoryRead: true
}
}
})
)Omitting an extension version selects current; supported dated and draft selectors resolve through the exported MCP_EXTENSION_SUPPORT manifest. Tasks keeps draft pinned to revision 2c1425d and exposes the current draft as draft-5246bc3, so updating upstream does not move the legacy codec. Modern MCP 2026-07-28 uses per-request protocol metadata and server/discover, while legacy 2025-11-25 initialization remains supported. Tasks require modern MCP and a durable provider.
Modern core behavior
The core option configures published 2026-07-28 utilities:
mcp({
core: {
maxToolInputElements: 10_000,
continuation: { signingKey: process.env.MCP_CONTINUATION_KEY! },
pagination: { pageSize: 100, signingKey: process.env.MCP_CURSOR_KEY! },
cache: { default: { cacheScope: 'private', ttlMs: 0 } },
subscriptions: { provider, toolsListChanged: true, resources: true }
}
})Tools, resource reads, and prompts can return McpInputRequiredResult. Invocation contexts expose validated inputResponses, restored requestState, client metadata, an abort signal, and reportProgress(). Route handlers read the same request-scoped values with getMcpInvocationContext(request). Prompt and resource-template registrations accept completion callbacks. Pagination and subscriptions remain disabled until configured. Signing keys must contain at least 32 bytes. Single-use continuations require an application provider.
core.maxToolInputElements optionally rejects oversized nested tool inputs before route handlers or task providers run. It counts object members and array elements and leaves input unlimited when omitted. transport.allowedOrigins accepts exact serialized origins and explicit non-HTTP scheme patterns such as chrome-extension://*. HTTP, HTTPS, and global wildcards remain forbidden.
The MCP client SDK 2.3.1 interoperates with modern discovery, progress SSE, prompts, and task reads
and cancellation. It rejects valid task-creation responses after creating the task because its decoder
does not accept resultType: 'task'. Use the minimal Tasks clients for creation and avoid blind retries.
Unversioned requests select the modern default and must include its complete envelope. Send MCP-Protocol-Version: 2025-11-25, or configure protocolVersions: ['2025-11-25'], for legacy clients. Hosts approve and fulfill elicitation, sampling, and roots requests before retrying the original operation.
The exported MCP_EXTENSION_LATEST_REVIEWED manifest records reviewed upstream sources for planning. It does not advertise adapter support.
The repository includes tested, package-root examples for every extension:
Tasks uses SQLite subprocess workers and BullMQ 6 with real Redis.
Authorization uses Better Auth, Bun SQLite, OAuth Provider, and SAML SSO.
Apps vanilla and Apps React use the MCP Apps v2 SDK and build one self-contained HTML document with Bun.
Modern core includes a minimal client for MRTR, completion, pagination, progress, cancellation, and subscriptions.
Skills registers exact skill bytes and verifies paginated manifests, direct lookup, and resource integrity.
Experimental extensions exercises server cards, interceptors, server variants, resource subscriptions, action metadata, and trust annotations.
Events demonstrates replay polling, event-only SSE, durable Bun SQLite subscriptions, and verified webhooks.
Server Cards
Server Cards are a finalized MCP extension. They publish advisory discovery metadata at GET /mcp/server-card. They use application/mcp-server-card+json, CORS, ETags, and conditional caching. Use HTTPS in production. Loopback HTTP is development-only. Cards must not contain credentials, private topology, or primitive catalogs. Clients decide whether and when to fetch them.
MCP_EXTENSION_SUPPORT.serverCard.maturity reports the current stable classification. Its nested version record retains status: 'experimental' because that immutable record describes the originally reviewed schema snapshot.
Experimental extension policy
Experimental extensions are off by default. Enable each feature explicitly and pin its exported revision constant. Revision selectors are immutable reviewed commits, not semver ranges. Server variants require legacy 2025-11-25; modern protocol configuration rejects them. Other experiments use modern transport methods where the draft defines them.
Interceptors expose canonical interceptors/list and singular interceptor/invoke. Pass sending to executeInterceptorChain() to mutate before validation. Pass receiving to validate before mutation. Validators run in parallel against isolated payload clones. Mutators run sequentially and use the phase-specific priorityHint, then name ordering for ties. Only severity: 'error' blocks. Audit mode never blocks and returns completed or failed outcomes for observability. Failures close by default; failOpen is explicit, and timeouts abort the local handler. Every wire result includes its interceptor, type, and phase. The adapter never contacts external interceptor services.
Legacy server variants bind discovery, selection, cursors, registries, subscriptions, and requests to the authenticated MCP-Session-Id. Metadata key io.modelcontextprotocol/server-variant takes precedence over MCP-Server-Variant. The first visible, ranked variant must be stable unless the client requests experimental results. Unsubscribe and session deletion close subscription iterators.
Action metadata describes destinations, sources, sensitivity, outcome, and review needs. Trust result metadata distinguishes an absent boolean from false. Evidence references are bounded descriptors; the adapter does not fetch them. Hosts own approval, union-strengthening, consent, evidence retrieval, and unavailable functionality. Behavioral annotations never grant authorization.
Events are legacy-only and pinned to revision 6682596d65eec778fe0b8b1f43b4e89d2fe2c546. The adapter supports authorized discovery, replay polling, event-only SSE, and durable webhook subscriptions. Clients own replay cursors. Webhook providers atomically preserve ownership, verification, secrets, expiry, and status, then reauthorize every delivery. The runnable example performs real signed TLS subscription, rotation, restart recovery, and unsubscribe operations through the adapter.
Client support changes independently of this package. Consult the canonical MCP Extension Support Matrix.
The experimental Filesystems repository currently defines no wire contract. The adapter exposes no filesystem methods and monitors its pinned README for future normative changes.
Documentation
The full guides and API reference live at mwillbanks.github.io/elysia-mcp-adapter:
Development
bun link
bun install
bun install --cwd website
bun run lint
bun run typecheck
bun --bun run --cwd website typecheck
bun test
bun test --coverage --coverage-reporter=lcov
bun run fallow
bun run buildDocumentation development runs independently from website/ with bun install and bun run dev.
bun run fallow checks dependencies, duplication, and health for the adapter and website independently.
Every finding fails the gate under the default thresholds. CI records measured Bun coverage separately
from Fallow's estimated coverage. Installation, builds, tests, and packed-consumer checks use Bun;
the declared Node.js compatibility floor is checked statically.
License
MIT © Mike Willbanks
This server cannot be deployed
Maintenance
Related MCP Connectors
Enable secure connectivity between Sentry issues and debugging data, and LLM clients, using a Model Context Protocol (MCP) server.
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
- QuallaaOAuthcom.quallaa
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
Hosted MCP server for LLM cost estimation, model comparison, and budget-aware routing.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA comprehensive ElysiaJS plugin for building Model Context Protocol (MCP) servers with HTTP transport, session management, and support for tools, resources, and prompts.15,569 npm49MIT
- AlicenseNot gradedqualityDmaintenanceExposes Hono API endpoints as Model Context Protocol tools, allowing LLMs to interact with your API routes through a dedicated MCP endpoint. It provides helpers to describe routes and includes a codemode for dynamic API interaction via search and execute tools.34 npm86MIT
- AlicenseNot gradedqualityDmaintenanceEnables creating high-performance MCP servers using Bun and Elysia, exposing resources, tools, and prompts to LLMs via SSE transport.284 npm24MIT

@absolutejs/mcpofficial
AlicenseNot gradedqualityBmaintenanceEnables serving a remote Model Context Protocol endpoint by exposing tools, prompts, and resources with customizable authorization and hooks, allowing AI models to interact with your application through a standardized JSON-RPC interface.793 npmBusiness Source 1.1