Offers storage backend integration with Cloudflare KV and R2 services for key-value storage and object storage capabilities
Includes text-to-speech service integration for converting text content into audio using ElevenLabs' voice synthesis API
Provides storage backend integration allowing data persistence and retrieval through Supabase's database and storage services
✨ Features
Declarative Tools & Resources: Define capabilities in single, self-contained files. The framework handles registration and execution.
Elicitation Support: Tools can interactively prompt the user for missing parameters during execution, streamlining user workflows.
Robust Error Handling: A unified
McpErrorsystem ensures consistent, structured error responses across the server.Pluggable Authentication: Secure your server with zero-fuss support for
none,jwt, oroauthmodes.Abstracted Storage: Swap storage backends (
in-memory,filesystem,Supabase,Cloudflare KV/R2) without changing business logic.Full-Stack Observability: Get deep insights with structured logging (Pino) and optional, auto-instrumented OpenTelemetry for traces and metrics.
Dependency Injection: Built with
tsyringefor a clean, decoupled, and testable architecture.Service Integrations: Pluggable services for external APIs, including LLM providers (OpenRouter) and text-to-speech (ElevenLabs).
Rich Built-in Utility Suite: Helpers for parsing (PDF, YAML, CSV), scheduling, security, and more.
Edge-Ready: Write code once and run it seamlessly on your local machine or at the edge on Cloudflare Workers.
🚀 Getting Started
MCP Client Settings/Configuration
Add the following to your MCP Client configuration file (e.g., cline_mcp_settings.json).
Prerequisites
Bun v1.2.0 or higher.
Installation
Clone the repository:
Navigate into the directory:
Install dependencies:
🛠️ Understanding the Template: Tools & Resources
This template includes working examples of tools and resources.
1. Example Tool: template_echo_message
This tool echoes back a message with optional formatting. You can find the full source at src/mcp-server/tools/definitions/template-echo-message.tool.ts.
The echoTool is registered in src/mcp-server/tools/definitions/index.ts, making it available to the server on startup. For an example of how to use the new elicitation feature, see template_madlibs_elicitation.tool.ts.
2. Example Resource: echo-resource
This resource provides a simple echo response via a URI. The source is located at src/mcp-server/resources/definitions/echo.resource.ts.
Like the tool, echoResourceDefinition is registered in src/mcp-server/resources/definitions/index.ts.
⚙️ Core Concepts
Configuration
All configuration is centralized and validated at startup in src/config/index.ts. Key environment variables in your .env file include:
Variable | Description | Default |
| The transport to use:
or
. |
|
| The port for the HTTP server. |
|
| Authentication mode:
,
, or
. |
|
| Storage backend:
,
,
,
,
. |
|
| Set to
to enable OpenTelemetry. |
|
| The minimum level for logging. |
|
Authentication & Authorization
Modes:
none(default),jwt(requiresMCP_AUTH_SECRET_KEY), oroauth(requiresOAUTH_ISSUER_URLandOAUTH_AUDIENCE).Enforcement: Wrap your tool/resource
logicfunctions withwithToolAuth([...])orwithResourceAuth([...])to enforce scope checks. Scope checks are bypassed for developer convenience when auth mode isnone.
Storage
Service: A DI-managed
StorageServiceprovides a consistent API for persistence. Never accessProviders: The default is
in-memory. Node-only providers includefilesystem. Edge-compatible providers includesupabase,cloudflare-kv, andcloudflare-r2.Multi-Tenancy: The
StorageServicerequirescontext.tenantId. This is automatically propagated from thetidclaim in a JWT when auth is enabled.
Observability
Structured Logging: Pino is integrated out-of-the-box. All logs are JSON and include the
RequestContext.OpenTelemetry: Disabled by default. Enable with
OTEL_ENABLED=trueand configure OTLP endpoints. Traces, metrics (duration, payload sizes), and errors are automatically captured for every tool call.
▶️ Running the Server
Local Development
Build and run the production version:
# One-time build bun rebuild # Run the built server bun start:http # or bun start:stdioRun checks and tests:
bun devcheck # Lints, formats, type-checks, and more bun test # Runs the test suite
Cloudflare Workers
Build the Worker bundle:
Run locally with Wrangler:
Deploy to Cloudflare:
sh bun deploy:prod> Note: Thewrangler.tomlfile is pre-configured to enablenodejs_compatfor best results.
📂 Project Structure
Directory | Purpose & Contents |
| Your tool definitions (
). This is where you add new capabilities. |
| Your resource definitions (
). This is where you add new data sources. |
| Implementations for HTTP and STDIO transports, including auth middleware. |
| The
abstraction and all storage provider implementations. |
| Integrations with external services (e.g., the default OpenRouter LLM provider). |
| Dependency injection container registrations and tokens. |
| Core utilities for logging, error handling, performance, security, and telemetry. |
| Environment variable parsing and validation with Zod. |
| Unit and integration tests, mirroring the
directory structure. |
🧑💻 Agent Development Guide
For a strict set of rules when using this template with an AI agent, please refer to AGENTS.md. Key principles include:
Logic Throws, Handlers Catch: Never use
try/catchin your tool/resourcelogic. Throw anMcpErrorinstead.Use Elicitation for Missing Input: If a tool requires user input that wasn't provided, use the
elicitInputfunction from theSdkContextto ask the user for it.Pass the Context: Always pass the
RequestContextobject through your call stack.Use the Barrel Exports: Register new tools and resources only in the
index.tsbarrel files.
❓ FAQ
Does this work with both STDIO and Streamable HTTP?
Yes. Both transports are first-class citizens. Use
bun run dev:stdioorbun run dev:http.
Can I deploy this to the edge?
Yes. The template is designed for Cloudflare Workers. Run
bun run build:workerand deploy with Wrangler.
Do I have to use OpenTelemetry?
No, it is disabled by default. Enable it by setting
OTEL_ENABLED=truein your.envfile.
How do I publish my server to the MCP Registry?
Follow the step-by-step guide in
docs/publishing-mcp-server-registry.md.
🤝 Contributing
Issues and pull requests are welcome! If you plan to contribute, please run the local checks and tests before submitting your PR.
📜 License
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
This server cannot be installed