Production MCP Starter

Production MCP Starter

A hexagonal TypeScript starter for production MCP servers with built-in authentication, billing, and tool scaffolding.

Category
Visit Server

README

Production MCP Starter

Ship a paid MCP server in an afternoon.

A hexagonal TypeScript starter for production MCP servers: Hono + Drizzle + Postgres + Redis + Stripe + Notion. OAuth-secured sessions, AES-256-GCM token storage at rest, dual subscription + metered (MPP) billing on one port, per-tool rate limiting, idempotency cache, structured logging, and SSE streaming. Six documented deployment targets, v1.0.0.

Quick start

cp .env.example .env                            # then open .env in your editor
openssl rand -base64 32                         # paste into ENCRYPTION_KEY in .env
docker compose up -d --wait                     # postgres + redis + migrate + app, healthcheck-gated
curl -sS http://localhost:3000/health | jq .
# expect: {"status":"ok","services":{"database":"ok","redis":"ok"}}

Boot fails fast if ENCRYPTION_KEY is unset (Zod min-length check). Stripe / Notion placeholders are accepted at boot and only fail when a billing-gated or OAuth-protected tool fires — see docs/CONFIGURATION.md for the full validation matrix. The six target runbooks (Docker Compose, Railway, Render, Fly.io, Cloudflare Workers + Neon, generic VPS) are in docs/DEPLOYMENT.md.

What's inside

src/transport/ is the Hono HTTP layer (routes, middleware, SSE writer); src/application/ is orchestration (tool dispatcher, OAuth flow, token refresh, billing orchestrator, the 8-stage tool dispatcher pipeline — 11 stages including Hono middleware; see docs/ARCHITECTURE.md for the diagram); src/domain/ is types, branded value objects, ports, and error classes; src/infrastructure/ is the adapters (Postgres + Redis driver factories, AES-256-GCM token cipher, Stripe gateways, Notion clients, pino logger); src/tools/ is where you add MCP tool definitions; src/schema/ is your Drizzle tables (users, oauth_tokens, subscriptions, usage, jobs).

First custom tool in 5 minutes

npm run new-tool myorg.hello
# edit src/tools/myorg-hello/myorg-hello.tool.ts — fill in input/output Zod schemas + handler
# register one line in src/composition-root.ts:
#   toolRegistry.register(myorgHelloTool as AnyToolDefinition);
npm run dev
curl -sS -X POST http://localhost:3000/mcp \
  -H 'Authorization: Bearer <session-token>' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"myorg.hello","arguments":{}}}'

The scaffold emits a typed ToolDefinition with AuthNone + BillingNone defaults — flip those to AuthRequired or BillingSubscription / BillingMpp and the dispatcher pipeline picks up the new requirements at call time, no framework edits. Full extension guide — sync tool, streaming tool, table, OAuth provider — in docs/CUSTOMIZATION.md.

Architecture in 100 words

Hexagonal. The domain layer defines ports (interfaces) and error classes and knows about nothing else. The application layer is orchestration logic (tool dispatcher, OAuth flow, billing) that depends only on domain. The infrastructure layer holds adapters that implement the ports (Postgres, Redis, Stripe, Notion, pino). The transport layer is the Hono app that wires HTTP to the dispatcher. The composition root in src/composition-root.ts is the only place adapters meet ports. A single BillingGateway port dispatches to both Stripe Subscriptions and Stripe MPP based on each tool's billing.kind. Full picture in docs/ARCHITECTURE.md.

Production deploy

Six runbooks ship in docs/DEPLOYMENT.md: Docker Compose self-host (default), Railway, Render, Fly.io, Cloudflare Workers + Neon (serverless edge), and generic VPS behind Caddy. Each runbook covers Postgres + Redis provisioning, Stripe webhook URL, OAuth callback URL, and a smoke-test curl. Env-var rules are documented once in docs/CONFIGURATION.md and referenced from every runbook.

What's NOT in v1

Honest list of what was intentionally deferred:

  • No Stripe Meters / usage-based billing — BillingGateway ships with Subscription and MPP (Metered-Pricing-Per-call) adapters only.
  • No nested-block Notion rendering — blocksToMarkdown emits flat bullets; rich block trees are a v1.1 polish item.
  • No queue/worker for async-poll tools — the pattern is documented in docs/PATTERNS_ASYNC_JOBS.md; the queue itself (BullMQ, SQS, etc.) is the buyer's choice.
  • ENCRYPTION_KEY rotation is operationally manual — re-encrypt-everything script lives in docs/MAINTENANCE.md (ships with the rest of the doc suite). Two-key window support is in the v1.1 backlog.
  • No mass logout or timeout distinction — SessionRepository.revokeAllForUser (security events) and a dedicated TimeoutError (504 vs 500 in dashboards) are both v1.1; today, individual tokens revoke fine and timeouts surface as InternalError.

Full v1.1 roadmap with implementation sketches and ship triggers: V1_1_BACKLOG.md.

Support

For v1.0.0 ship day: Gumroad seller messages on the kit's listing + the email address in LICENSE. See docs/TROUBLESHOOTING.md and SECURITY.md for detail. Pre-launch, the maintainer should replace the support@production-mcp-starter.dev placeholder in LICENSE, SECURITY.md, and docs/TROUBLESHOOTING.md with the real channel — see LAUNCH_CHECKLIST.md.

License

Commercial — single-seat. LICENSE ships in Phase 14 of the build.

Recommended Servers

playwright-mcp

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.

Official
Featured
TypeScript
Magic Component Platform (MCP)

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.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

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.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

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.

Official
Featured
TypeScript
Kagi MCP Server

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.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

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.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured