MCP App Template
A starter template for building MCP Apps on deco, enabling tools, resources, and interactive React UIs powered by the Model Context Protocol.
README
MCP App Template
Official starter for building MCP Apps on deco — interactive UIs powered by the Model Context Protocol.
Quick Start
# Clone the template
git clone https://github.com/decocms/mcp-app.git my-mcp-app
cd my-mcp-app
# Install dependencies
bun install
# Start development
bun run dev
Project Structure
├── api/ # MCP server (platform-agnostic)
│ ├── app.ts # App core — tools, resources, middleware
│ ├── main.bun.ts # Bun entrypoint (local dev)
│ ├── tools/
│ │ ├── index.ts # Tool registry
│ │ └── hello.ts # Example tool (hello_world)
│ ├── resources/
│ │ └── hello.ts # MCP App resource (serves HTML)
│ └── types/
│ └── env.ts # StateSchema + Env type
├── web/ # React UI (MCP App)
│ ├── tools/ # One folder per tool UI (folder-based routing)
│ │ └── hello/ # hello_world tool UI
│ │ ├── main.tsx # React entry point
│ │ ├── bridge.ts # MCP App SDK integration
│ │ ├── context.tsx # React context for MCP state
│ │ ├── router.tsx # TanStack Router with UI
│ │ └── types.ts # UI state types
│ ├── entry.tsx # Build entry (imports @tool/main.tsx)
│ ├── components/ui/ # shadcn/ui components
│ ├── lib/utils.ts # cn() helper
│ └── globals.css # Tailwind base styles
├── index.html # Single Vite entry (shared by all tools)
├── package.json
├── tsconfig.json
├── biome.json
├── vite.config.ts
├── components.json # shadcn/ui config
├── app.json # Deco mesh config
└── .mcp.json # Local MCP server config
Development
# Run API server + web build concurrently
bun run dev
# API server only (port 3001)
bun run dev:api
# Web build only (watch mode)
bun run dev:web
Connecting to deco Studio
To test your MCP App in deco Studio, expose your local server through a tunnel:
bun start
# Tunnel started -> 🌐 Preview: https://<your-id>.deco.host
Then connect in Studio using the MCP URL:
https://<your-id>.deco.host/api/mcp
Adding a New Tool with UI
Each tool UI lives in web/tools/<name>/. The TOOL env var tells Vite which folder to build — one build per tool, output as dist/client/<name>.html.
- Create the tool —
api/tools/my-tool.tsusingcreateTool - Register it — add to the
toolsarray inapi/tools/index.ts - Create the UI —
web/tools/my-tool/withmain.tsx,bridge.ts,context.tsx,router.tsx,types.ts - Create the resource —
api/resources/my-tool.tsservingdist/client/my-tool.html - Update build scripts:
"build:web": "TOOL=hello vite build && TOOL=my-tool vite build", "dev:web": "concurrently \"TOOL=hello vite build --watch\" \"TOOL=my-tool vite build --watch\""
How the Tool Router Works
TOOL=hello vite build
→ resolves @tool/* → web/tools/hello/*
→ index.html imports web/entry.tsx imports @tool/main.tsx
→ outputs dist/client/hello.html (single-file bundle)
Tech Stack
- Runtime: Bun (default), deployable to any Web Standard runtime
- Server: @decocms/runtime MCP server
- UI: React 19 + TanStack Router (hash-based) + TanStack Query
- Styling: Tailwind CSS v4 + shadcn/ui
- MCP Apps: @modelcontextprotocol/ext-apps SDK
- Build: Vite + vite-plugin-singlefile
- Linting: Biome
How It Works
- The app core (
api/app.ts) defines tools, resources, and middleware as a platform-agnosticfetchhandler - A platform entrypoint (
api/main.bun.ts) starts the server using the platform's API - Tools perform actions and can link to a UI via
_meta.ui.resourceUri - Resources serve single-file HTML bundles with
mimeType: "text/html;profile=mcp-app" - The MCP App UI connects to the host via
@modelcontextprotocol/ext-apps, receives tool input/results, and renders an interactive display - Vite builds each tool UI into a self-contained HTML file (CSS + JS inlined) using the
TOOLenv var to select whichweb/tools/<name>/folder to bundle
Deployment
Multi-Platform
The app uses a factory pattern that separates business logic (api/app.ts) from platform wiring. To deploy to a new platform, add a thin entrypoint file — see the add-deploy-target skill for step-by-step instructions.
Supported targets out of the box:
- Bun —
api/main.bun.ts(default, used for local dev)
Easy to add:
- Cloudflare Workers — ~5 lines +
wrangler.toml - Deno — ~5 lines
- Node.js — ~5 lines +
@hono/node-server - AWS Lambda — ~5 lines +
hono/aws-lambda
Publish to deco
- Update
app.jsonwith your app's name, description, and connection URL - Push to your repository — CI will validate the build
- Follow deco mesh publishing instructions to deploy
CI
GitHub Actions runs on every push and pull request:
bun run ci:check— Biome lint + format checkbun run check— TypeScript type checkingbun test— Unit testsbun run build— Production build
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.