Skip to main content
sunpeak API

Overview

Sunpeak provides three ways to run a production MCP server, from zero-config to full control:
ApproachUse case
sunpeak startZero-config — loads tools, resources, and auth from dist/ automatically
createMcpHandlerNode.js — mount the MCP handler on your own Express/Fastify/http server
createHandlerWeb Standard — Cloudflare Workers, Deno, Bun, Vercel Edge
sunpeak start auto-discovers tools from dist/tools/, resources from dist/{name}/, and auth from dist/server.js, then passes them to startProductionHttpServer internally. createMcpHandler and createHandler accept these as config objects — you load and pass them yourself. This gives full control over how tools, resources, and auth are provided. All three use MCP Streamable HTTP transport on a single /mcp endpoint.

createMcpHandler

Creates a Node.js request handler for MCP over Streamable HTTP.
import { createMcpHandler } from 'sunpeak/mcp';
import type { ProductionServerConfig } from 'sunpeak/mcp';

const handler = createMcpHandler(config);
// handler: (req: IncomingMessage, res: ServerResponse) => Promise<void>
The handler responds to POST /mcp, GET /mcp, DELETE /mcp, and OPTIONS /mcp. For unmatched paths it does nothing, so you can chain it with your own routes.

Example: Express

import express from 'express';
import { createMcpHandler } from 'sunpeak/mcp';

const app = express();
app.get('/health', (req, res) => res.json({ ok: true }));

// tools: ProductionTool[], resources: ProductionResource[], auth: AuthFunction
const mcpHandler = createMcpHandler({ tools, resources, auth });
app.use((req, res, next) => {
  mcpHandler(req, res).then(() => {
    if (!res.headersSent) next();
  });
});

app.listen(3000);

ProductionServerConfig

name
string
default:"sunpeak-app"
Server name reported to hosts during MCP handshake.
version
string
default:"0.1.0"
Server version reported to hosts.
tools
ProductionTool[]
required
Tool registrations. Each has a name, tool config (resource reference, title, description), optional schema (Zod shape for input validation), and handler function.
resources
ProductionResource[]
required
Resource registrations. Each has a name, uri, html (self-contained HTML string), and optional _meta.
auth
(req: IncomingMessage) => AuthInfo | null
Auth function called on every request. Return AuthInfo to authenticate, null to reject with 401. See Server Entry.

createHandler

Creates a Web Standard request handler for serverless and edge runtimes.
import { createHandler } from 'sunpeak/mcp';
import type { WebHandlerConfig } from 'sunpeak/mcp';

const handler = createHandler(config);
// handler: (req: Request) => Promise<Response>
Unlike createMcpHandler, this handler does not do path matching — it handles every request it receives. Mount it behind your own router.

Example: Cloudflare Worker

import { createHandler } from 'sunpeak/mcp';

const handler = createHandler({ tools, resources, auth });
export default { fetch: handler };

Example: Hono

import { Hono } from 'hono';
import { createHandler } from 'sunpeak/mcp';

const app = new Hono();
const handler = createHandler({ tools, resources });
app.all('/mcp', (c) => handler(c.req.raw));
export default app;

WebHandlerConfig

Same shape as ProductionServerConfig, except auth takes a Web Standard Request:
auth
(req: Request) => AuthInfo | null
Auth function for Web Standard environments. Return AuthInfo to authenticate, null to reject with 401.

startProductionHttpServer

The built-in HTTP server used by sunpeak start. A convenience wrapper around createMcpHandler that adds a root page, favicon, and graceful shutdown.
import { startProductionHttpServer } from 'sunpeak/mcp';

startProductionHttpServer(config, 3000);
For most projects, use sunpeak start instead of calling this directly.

See Also