Introducing AgentBack

AgentBack is a TypeScript framework for building agent-facing services where REST endpoints, MCP tools, docs, typed clients, tests, and runtime validation all share one Zod contract.

First, a word on why this exists. Thirteen years ago I co-created LoopBack to make API development feel like declaring what you want instead of wiring plumbing. Since then I've built large-scale platforms — Collab.Land, and Faction's AI agent harness and deal-flow systems — and kept watching the contract an API enforces, the contract it documents, and the contract an agent is given drift apart. My conclusion: LoopBack needs a refresh for the AI agent era. AgentBack is that refresh — built on the DI core I know best, with the drift made structurally impossible.

Modern backends are no longer consumed only by web apps and mobile apps. They are also consumed by AI agents that discover tools, inspect schemas, call APIs, retry failures, and compose services into longer workflows. That changes the cost of contract drift.

In the old world, a stale OpenAPI document or tool manifest was mostly a documentation bug. In the agent world, it is a runtime bug. The model may choose the wrong tool, send the wrong body, miss an auth requirement, or trust a response shape that no longer exists.

Why bet so heavily on schemas? Because a schema is three things to an agent at once. It is knowledge — the tool contract is the only documentation an agent reliably reads, and a precise one beats a paragraph of prose. It is a constraint — a model can hallucinate an argument, but a validated boundary stops bad input before it reaches your handler. And it is a contract — stable, diffable, testable, the thing both sides can hold each other to.

Schema-first lost to code-first once already, and the reason was honest: rigorous schemas are tedious, and developers are lazy — I say that with affection, laziness is an engineering virtue. But the economics flipped. Agents are tireless. When an agent writes and maintains the schema, the cost of rigor drops to nearly zero, while the value of rigor goes up, because the consumer on the other side of the boundary is also a machine that takes the contract literally.

The core product claim is simple: one schema, every boundary.

The shape

An AgentBack application is one dependency-injection container. REST controllers, MCP tool classes, services, config, auth strategies, lifecycle observers, and servers are bindings. Servers discover the bindings they care about by tag.

const app = new RestApplication();
app.component(MCPComponent);

app.restController(OrdersController);
app.service(OrderTools);
app.service(OrderService);

await app.start();

The DI container is what makes the architecture componentized rather than monolithic. A Component bundles controllers, services, providers, servers, and lifecycle observers into one registration — auth, health, metrics, metering, payments, and MCP support all ship this way, and your features should too. Extension points take it further: a service declares a slot (@extensionPoint) and anyone fills it by tag (@extensions) — that's how the auth stack collects strategies and health collects checks, without either ever importing its plugins. The rule underneath both: add a binding, never edit the core. New capability is composition, not modification.

The contract lives on decorators as Zod. That same schema validates requests, gives the handler its `z.infer` type, emits OpenAPI 3.1, registers MCP input/output schemas, and powers the Swagger UI or MCP Inspector.

const OrderPath = z.object({id: z.string().uuid()});
const Order = z.object({id: z.string(), status: z.string()});

@get('/orders/{id}', {path: OrderPath, response: Order})
async get(input: {path: z.infer<typeof OrderPath>}) {
  return this.orders.get(input.path.id);
}

@tool('get_order', {input: OrderPath, output: Order})
async getOrder(input: z.infer<typeof OrderPath>) {
  return this.orders.get(input.id);
}

Where it sits

Express gives you freedom, but every boundary is hand-wired. tRPC gives excellent TypeScript inference, but the contract is primarily TypeScript-native. NestJS gives structure and DI, but API schemas and tool schemas still tend to live in separate worlds. FastAPI showed how powerful one model artifact can be, but TypeScript teams still need a native version of that story.

AgentBack takes the FastAPI-style contract-coherence bet and applies it to TypeScript services that must serve both humans and agents. The differentiator is not REST alone, MCP alone, or DI alone. It is the way those pieces share the same artifact.

Beyond hello world

The framework is deliberately modular. The DI core can stand alone. REST and MCP can run separately or in one process. The client package gives TypeScript consumers typed calls without codegen. The auth, authorization, rate-limit, health, metrics, OTel, testing, plugin, messaging, metering, and payments packages compose around the same binding model.

That matters for production agent systems. A useful agent backend is not just a tool function. It needs identity, policy, quotas, audit logs, paid or metered access, background work, tracing, tests, and operator visibility. Those concerns need to attach to the same route and tool boundaries, or they become another source of drift.

The same goes for the conventions agents specifically need: errors with stable codes and the violated schema inline, confirmation round-trips on dangerous operations, idempotency-key replay on mutations, and a /llms.txt the service generates from its own route registry. These ship as framework defaults rather than per-team conventions; the posts Errors an agent can fix and Your API's first reader is an agent cover them in detail.

AI-native means the tooling too

"AI-native" is an easy claim, so here is what it means concretely. Most of this framework was written by coding agents, and the project treats agents as first-class developers, not just first-class callers. The docs site serves /llms.txt and a full markdown mirror of every page, so an agent can read the corpus in one fetch instead of scraping HTML.

More importantly, the repo ships an installable agent skill — a structured playbook that teaches a coding agent the framework's conventions: the schema-on-decorator pattern, the slot-0 input bundle, how DI discovery works, the auth stack, and how to share schemas with a typed client. These are exactly the things an agent can't guess from type signatures. One command installs it into Claude Code, Codex, Cursor, and 20+ other agents:

npx skills add ninemindai/agentback

After that, asking your agent to "add a paid MCP tool with an idempotency key" lands on the framework's conventions instead of an improvised approximation of them. The framework's own development works the same way — the agents that build it use the skill that ships with it.

Status

AgentBack is in alpha, and as of this week it is on npm: all @agentback/* packages and the create-agentback scaffolder are published at 0.1.0. The examples work end to end, and the package surface is still moving. The project is intentionally sharpest for teams willing to adopt the core design rule now: put the schema on the boundary, then let every transport and tool derive from it.

npm install @agentback/core @agentback/rest @agentback/openapi zod
# or scaffold a new app:
npm create agentback@latest
Read the README Open architecture map