Package Exports
- @frontmcp/sdk
- @frontmcp/sdk/package.json
Readme
The TypeScript way to build MCP servers with decorators, DI, and Streamable HTTP.
Made with ❤️ for TypeScript developers
FrontMCP is a TypeScript-first framework for the Model Context Protocol (MCP). You write clean, typed code; FrontMCP handles the protocol, transport, DI, session/auth, and execution flow.
// src/main.ts
import 'reflect-metadata';
import { FrontMcp, LogLevel } from '@frontmcp/sdk';
import HelloApp from './hello.app';
@FrontMcp({
info: { name: 'Demo 🚀', version: '0.1.0' },
apps: [HelloApp],
http: { port: 3000 },
logging: { level: LogLevel.Info },
})
export default class Server {}Table of Contents
- Why FrontMCP?
- Installation
- Quickstart
- Core Concepts
- Authentication
- Sessions & Transport
- Deployment
- Version Alignment
- Contributing
- License
Why FrontMCP?
- TypeScript-native DX — decorators, Zod, and strong typing end-to-end
- Scoped invoker + DI — secure, composable execution with hooks
- Adapters & Plugins — extend your server without boilerplate
- Spec-aligned transport — Streamable HTTP for modern MCP clients
Installation
Prereqs: Node.js ≥ 22, npm ≥ 10. (Installation - FrontMCP)
Option A — New project (recommended)
npx frontmcp create my-appThis scaffolds a FrontMCP project, writes a modern ESM tsconfig.json for decorators, adds helpful package scripts, and
installs required dev deps. (Installation - FrontMCP)
Option B — Add to an existing project
npm i -D frontmcp @types/node@^20
npx frontmcp initinit adds scripts, verifies your tsconfig.json, and checks layout. No need to install @frontmcp/sdk directly—the
CLI bundles a compatible SDK for you. (Installation - FrontMCP)
Quickstart
If you haven’t installed FrontMCP yet, follow the installation guide first.
1) Create Your FrontMCP Server
// src/main.ts
import { FrontMcp, LogLevel } from '@frontmcp/sdk';
import HelloApp from './hello.app';
@FrontMcp({
info: { name: 'Hello MCP', version: '0.1.0' },
apps: [HelloApp],
http: { port: 3000 },
logging: { level: LogLevel.INFO },
})
export default class HelloServer {}2) Define an App
// src/hello.app.ts
import { App } from '@frontmcp/sdk';
import GreetTool from './tools/greet.tool';
@App({
id: 'hello',
name: 'Hello App',
tools: [GreetTool],
})
export default class HelloApp {}3) Add Your First Tool
// src/tools/greet.tool.ts
import { Tool } from '@frontmcp/sdk';
import { z } from 'zod';
@Tool({
name: 'greet',
description: 'Greets a user by name',
inputSchema: { name: z.string() },
})
export default class GreetTool {
async execute({ name }: { name: string }) {
return `Hello, ${name}!`;
}
}4) Run It
Add scripts (if you didn't use frontmcp create):
{
"scripts": {
"dev": "frontmcp dev",
"build": "frontmcp build",
"start": "node dist/main.js"
}
}Then:
npm run dev
# Server listening on http://localhost:3000Tip: FrontMCP speaks MCP Streamable HTTP. Connect any MCP-capable client and call
greetwith{"name": "Ada"}. (Quickstart - FrontMCP)
Function and Class Tools
Tools are typed actions with Zod schemas. Implement them as classes with @Tool({...}) or inline via tool(). Pass
Zod fields directly (no z.object({...})). (Tools - FrontMCP)
Function tool
import { tool } from '@frontmcp/sdk';
import { z } from 'zod';
export default tool({
name: 'greet',
description: 'Greets a user by name',
inputSchema: { name: z.string() }, // shape, not z.object
})(({ name }) => `Hello, ${name}!`);Class tool
import { Tool } from '@frontmcp/sdk';
import { z } from 'zod';
@Tool({
name: 'add',
description: 'Add two numbers',
inputSchema: { a: z.number(), b: z.number() },
})
export default class AddTool {
async execute({ a, b }: { a: number; b: number }) {
return a + b;
}
}Scripts & tsconfig
After create or init, you’ll have:
{
"scripts": {
"dev": "frontmcp dev",
"build": "frontmcp build",
"inspect": "frontmcp inspector",
"doctor": "frontmcp doctor"
}
}These map to dev watch, production build, zero‑setup Inspector launch, and environment checks. (Installation - FrontMCP)
Recommended tsconfig.json (ESM + decorators)
{
"compilerOptions": {
"target": "es2021",
"module": "esnext",
"lib": ["es2021"],
"moduleResolution": "bundler",
"rootDir": "src",
"outDir": "dist",
"strict": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"sourceMap": true
},
"include": ["src/**/*.ts"],
"exclude": ["**/*.test.ts", "**/__tests__/**"]
}This mirrors what init writes for you. (Local Dev Server - FrontMCP)
Optional tsconfig.build.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"declaration": true,
"sourceMap": false
},
"exclude": ["**/*.test.ts", "**/__tests__/**", "src/**/*.dev.ts"]
}Inspector
Run a browser UI to exercise tools and messages:
npm run inspectThis launches the MCP Inspector; point it at your local server (e.g., http://localhost:3000). (Local Dev Server -
FrontMCP)
Core Concepts
Servers
@FrontMcp({...}) defines info, apps, http, logging, session, and optional auth. Keep it
minimal or scale up with providers and plugins. (The FrontMCP Server - FrontMCP)
Apps
Use @App to group tools, resources, prompts, plus providers, adapters, and plugins. With
splitByApp: true, each app gets its own scope/base path and, if needed, its own auth surface. (Apps - FrontMCP)
Tools
Typed actions with schemas (class @Tool or inline tool({...})(handler)). Use the Zod‑field shape style for
inputSchema. (Tools - FrontMCP)
Resources
Readable data by URI or RFC6570 template (see @Resource / @ResourceTemplate). (Resources - FrontMCP)
Prompts
Reusable templates returning MCP GetPromptResult, with typed arguments. (Prompts - FrontMCP)
Providers / Adapters / Plugins
Inject shared services, generate tools from OpenAPI, and add cross‑cutting behavior like caching and hooks. (Add OpenAPI Adapter - FrontMCP)
Authentication
Configure auth at the server (shared) or per app (isolated). With splitByApp: true, define auth per app
(server‑level auth is disallowed). (Authentication - FrontMCP)
Remote OAuth
auth: {
type: 'remote',
name: 'frontegg',
baseUrl: 'https://idp.example.com',
dcrEnabled?: boolean,
clientId?: string | ((info: { clientId: string }) => string),
mode?: 'orchestrated' | 'transparent',
allowAnonymous?: boolean,
consent?: boolean,
scopes?: string[],
grantTypes?: ('authorization_code' | 'refresh_token')[],
authEndpoint?: string,
tokenEndpoint?: string,
registrationEndpoint?: string,
userInfoEndpoint?: string,
jwks?: JSONWebKeySet,
jwksUri?: string
}See Authentication → Remote OAuth for full details and DCR vs non‑DCR. (Remote OAuth - FrontMCP)
Local OAuth
auth: {
type: 'local',
id: 'local',
name: 'Local Auth',
scopes?: string[],
grantTypes?: ('authorization_code' | 'refresh_token')[],
allowAnonymous?: boolean, // default true
consent?: boolean,
jwks?: JSONWebKeySet,
signKey?: JWK | Uint8Array
}Use per‑app when isolating scopes. (Local OAuth - FrontMCP)
Sessions & Transport
session: {
sessionMode?: 'stateful' | 'stateless' | ((issuer) => ...), // default 'stateless'
transportIdMode?: 'uuid' | 'jwt' | ((issuer) => ...), // default 'uuid'
}- Stateful: server‑side store (e.g., Redis); supports refresh; best for short‑lived upstream tokens.
- Stateless: embeds session in JWT; simpler but no silent refresh.
- Transport IDs:
uuid(per node) orjwt(signed; distributed setups). (The FrontMCP Server - FrontMCP)
Deployment
Local Dev
npm run dev- Default HTTP port:
3000unless configured npm run doctorchecks Node/npm versions,tsconfig, and scripts. (Local Dev Server - FrontMCP)
Production
npm run build
NODE_ENV=production PORT=8080 npm startBuilds to dist/ (uses tsconfig.build.json). Consider a process manager and reverse proxy; align all @frontmcp/*
versions. (Production Build - FrontMCP)
Version Alignment
If versions drift, the runtime will throw a clear “version mismatch” at boot. Keep @frontmcp/* versions aligned.
(Production Build - FrontMCP)
Contributing
- PRs welcome! Read the full CONTRIBUTING.md for workflow details, coding standards, and the PR checklist.
- Keep changes focused, add/adjust Jest specs, and update docs/snippets when behavior changes.
- Before opening a PR run
yarn nx run-many -t lint,test,build,npx frontmcp doctor, and verify the demo/Inspector flows relevant to your change. - Align
@frontmcp/*versions in examples to avoid runtime version mismatches.
License
See LICENSE.