AgentBack documentation
A TypeScript dependency-injection framework with HTTP (REST) and MCP servers that plug into the same container and validate against the same Zod schemas. This is the place to learn the ideas and build with them.
New here? Read the root README for the one-page tour and the 30-second code feel, then come back for the depth.
How the framework thinks
Three ideas carry the whole framework. Everything in these docs is an elaboration of one of them:
- Everything is a binding in a context. The
Applicationis a DIContext. Controllers, MCP tool classes, services, config, and even the servers themselves are just bindings the framework discovers by tag. New capability = new binding; you never edit a central registry. - Schemas live once, on the decorator. A route's or tool's Zod schema is
simultaneously the runtime validator, the
z.inferTypeScript type, the OpenAPI/MCP contract, and the rendered docs. One artifact, many views. - Servers are components. REST and MCP are interchangeable, composable plug-ins over the same container — run either, or both from one process.
If you internalize those three, the API surface mostly writes itself.
Learning path
Read top-to-bottom the first time; jump around afterwards.
Blog — design notes and release stories
| Entry | What you'll find |
|---|---|
| Blog home | Short-form posts: boundary coherence, hybrid REST + MCP apps, schema-shared clients, agent-actionable errors, tool-surface budgets, and self-describing APIs. |
| Architecture map | A standalone dark HTML/SVG diagram of the runtime boundary model, with copy/PNG/PDF export controls. |
Concepts — understand the machine
| Doc | What you'll learn |
|---|---|
| Dependency injection | Context, Binding, scopes, @inject, providers, tag-based discovery — the foundation everything sits on. |
| Schema-first decorators | How one Zod schema on a decorator becomes validator + type + OpenAPI + MCP contract; the slot-0 input bundle; runtime + compile-time guarantees. |
| Components, servers & lifecycle | How a Component packages bindings, how a Server is discovered and started, and the start/stop lifecycle. |
Guides — build something
| Guide | Outcome |
|---|---|
| Build a REST API | A Zod-validated REST service with auto-emitted OpenAPI 3.1 and Swagger UI. |
| Build an MCP server | Tools, resources, and prompts an MCP client (or Claude) can call, with an inspector UI. |
| Build a hybrid app | REST + MCP from a single process and a single set of schemas, plus a type-safe HTTP client. |
| Render a widget with MCP Apps | An interactive ui:// widget a host (Claude Desktop) renders inline for a tool's result (SEP-1865). |
| Composition & extensibility | The modular toolkit: components, middleware, interceptors, extension points, and subclassing the dispatcher. |
| Testing | createTestApp and the four client surfaces: typed calls, supertest, in-memory MCP, DI assertions. |
| Secure MCP over HTTP | Auth modes (strategies vs OAuth 2.1 resource server), scope-gated tools, DNS-rebinding, rate limits. |
| Deploy to production | Containers, validated config, K8s probes, metrics/tracing, graceful shutdown, multi-instance checklist. |
Reference & design
| Doc | Purpose |
|---|---|
| Architecture overview | The big picture: how a request flows, how servers discover bindings, full package layering. Diagrams included. |
| Metering & payments | Counting every REST/MCP call (metering) and gating or billing the paid ones — x402 / MPP / Stripe (payments). Diagrams. |
| Boundary coherence (design thesis) | Why the framework is shaped this way — the "one artifact, viewed differently" bet and what it buys AI-led teams. |
| Database story | The framework's stance on persistence (Drizzle recipe), and why there's no built-in ORM. |
Every package under packages/ carries its own README.md with
its exports, a usage snippet, and where it sits in the layering.
Server extensions (install* onto a running REST server):
health/readiness probes ·
Prometheus metrics ·
rate limiting (in-memory or Redis,
429 + RateLimit-* headers).
Metering & payments (subclass the dispatcher / mount a rail):
usage metering (per-principal
UsageEvents → audit-log sinks + quota) ·
payments (x402 / MPP / Stripe) — see the
architecture doc.
The shortest possible example
import {z} from 'zod';
import {api, get} from '@agentback/openapi';
import {RestApplication} from '@agentback/rest';
@api({basePath: '/greet'})
class GreetingController {
@get('/hello/{name}', {
path: z.object({name: z.string().min(1)}),
response: z.object({greeting: z.string()}),
})
async hello(input: {path: {name: string}}) {
return {greeting: `Hello, ${input.path.name}!`};
}
}
const app = new RestApplication();
app.restController(GreetingController);
await app.start();
// GET /greet/hello/world -> {"greeting":"Hello, world!"}
// GET /openapi.json -> OpenAPI 3.1.1 derived from the Zod schemas
Change GreetingController to an @mcpServer() with @tool(...) methods and
the same schemas become an MCP tool surface instead — see
Build an MCP server.
Runnable examples
Each guide maps to a working example you can run:
pnpm install && pnpm build # build first — tests/examples run against dist/
pnpm -F hello-rest start # REST + Swagger UI + Context Explorer
pnpm -F hello-mcp test # MCP over stdio, driven by a test client
pnpm -F hello-hybrid start # REST + MCP from one process, both UIs
pnpm -F hello-client start # the typed client calling hello-rest's schemas
| Example | Demonstrates | Guide |
|---|---|---|
examples/hello-rest |
REST + auth + health + metrics + explorers | REST |
examples/hello-mcp |
MCP tools over stdio | MCP |
examples/hello-hybrid |
REST + MCP in one process | Hybrid |
examples/hello-client |
Schema-shared typed client | Hybrid |
examples/hello-mcp-apps |
MCP Apps ui:// widget rendered by a host |
MCP Apps |
Conventions in these docs
- Code blocks are real, compiling TypeScript drawn from the packages and examples — not pseudocode.
- ESM only: relative imports carry
.jsextensions in actual source; doc snippets omit them for readability where the import is from a package. - "Slot 0 / slot 1+" refers to a handler method's parameter positions — see Schema-first decorators.