Elysia MCP Adapter
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
@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: @absolutejs/mcp
Install
bun add @mwillbanks/elysia-mcp-adapter elysiaNode.js >=20.11, Bun >=1.1, Elysia >=1.4, and TypeScript >=5.8 are supported.
Agent guidance
The npm package includes an Agent Skill for integrating the adapter. Install TanStack Intent as a local development dependency in the consuming project. Intent 0.5.6 requires Node.js 20.12 or later.
bun add --dev --exact @tanstack/intent@0.5.6Set an explicit allowlist in the consuming project's package.json:
{
"intent": {
"skills": ["@mwillbanks/elysia-mcp-adapter#elysia-mcp-adapter"],
"exclude": []
}
}Use exact package#skill entries. Every dependency needs its own permission.
Exclusions override permissions. To revoke a skill, remove its entry or add its
exact reference to intent.exclude. Use "skills": [] to disable all sources.
Run the installed CLI from the consuming project:
./node_modules/.bin/intent list
./node_modules/.bin/intent load '@mwillbanks/elysia-mcp-adapter#elysia-mcp-adapter'Load the matching skill only when it applies to the current task. Open the reference
for that task. Use a project-local node_modules install for file-only discovery.
Intent reads installed package metadata and guidance without running dependency code.
When Yarn Plug'n'Play has no usable node_modules, Intent loads Yarn's .pnp.cjs resolver
to locate the files. Editor hooks are optional convenience. Keep the trust policy in
package.json and review guidance when dependencies change.
See the Intent trust model.
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. Add a prompt option to an explicit or route-backed tool to register an associated prompt that guides the host to call that tool; use .mcpPrompt() for standalone prompts.
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 provides the approved current revision and the explicit draft draft-b3d28ac. Update retired draft selectors using the migration guidance in the configuration error. 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.
Workers can create a McpTaskExecutionContext with createMcpTaskExecutionContext(options). Pass McpTaskExecutionContextOptions with the task ID, the original provider context, and the provider's persistence callbacks. Use execution.notify.status() for updates and execution.input.request() for client input. Rebuild the context from durable data after a restart. See the Tasks worker example for the full flow.
See the specification inventory for exact revisions and draft compatibility. Configure specification notices to receive deprecation and pre-release notices in application logs or through your OpenTelemetry Logs 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 notify.progress(), opt-in notify.message(), and typed input helpers alongside the existing reportProgress(), inputResponses, and requestState APIs. 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.
Use request language preferences to provide localized display text from your application.
See the messaging guide for live and durable updates, input, subscriptions, and tool-linked prompts. Set prompt on a tool to add a companion prompt without duplicating its registration.
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.4.0 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.
Requests without a version header or version metadata use classic 2025-11-25 when enabled. Modern clients send the full 2026-07-28 envelope. Classic clients should send the negotiated MCP-Protocol-Version on requests after initialization. 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 reports Beta maturity for Tasks, Skills over MCP, and Server Cards. The approved Server Cards wire baseline still reports status: 'stable' under Final SEP-2127.
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 require MCP 2026-07-28 and default to accepted SEP-3415. The adapter supports authorized discovery, replay polling, event-only SSE with negotiated idle heartbeats, 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:
Structured authorization denials explains the opt-in SEP-2643 tool policy and remediation.
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.
Extension revisions and toolchain
Use Bun 1.4.4. bun run lint checks formatting with bun fmt; bun run typecheck
uses bun check. Fallow remains the static analysis gate. No standalone lint package is required.
Skills preserves optional JSON _meta on registrations and provider sources. Extension-owned keys
use io.modelcontextprotocol.skills/. Resource digests still cover exact published bytes.
Interceptors use the current 07c89a24 proposal, including timestamped invocation context,
optional span/session identifiers, and per-call configuration validation. See the separate HTTP
service in examples/experimental; local chain helpers remain local utilities.
Events uses accepted revision f77a5fe and codes -32023 through -32027. Migrate older Events pins to current and discover Events on server/discover. Server Variants still uses legacy transport.
Apps, Client Credentials, and Enterprise-Managed Authorization have approved profiles. Server Cards follows Final SEP-2127. Tasks exposes approved and pinned draft selections. File Uploads has an eligible working-group draft and is planned. Filesystems remains inventory-only while the group develops its specification. See the website specification inventory for immutable sources, hashes, limitations, and all selectors.
License
MIT © Mike Willbanks
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
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
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
Zero-dependency Cloudflare Worker gateway turning websites and REST APIs into MCP tools.
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.14,076 npm49MIT

@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.753 npmBusiness Source 1.1- AlicenseNot gradedqualityCmaintenanceAn MCP server plugin for the Elysia web framework, enabling AI clients to connect via Streamable HTTP transport with stateful or stateless sessions and authentication.19 npmMIT
- AlicenseNot gradedqualityBmaintenanceAutomatically turns existing Elysia routes into MCP tools, reusing schemas and running full request lifecycle.42 npmMIT