One container, two surfaces

A hybrid AgentBack app can serve HTTP clients and MCP clients from the same process, backed by the same services and schemas.

The runtime shape is intentionally plain. The application is a dependency-injection context. Servers are bindings in that context. Controllers, tool classes, providers, config, and lifecycle observers are also bindings.

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

app.restController(GreetingController);
app.service(EchoTools);
app.service(GreetingService);

await app.start();

At startup, the REST server finds bindings tagged as REST controllers. The MCP server finds bindings tagged as MCP servers. Both can inject the same business service, so the transport adapters stay thin. The process then serves /openapi.json, Swagger UI, the MCP inspector, and /llms.txt, all derived from the same bindings it just discovered.

Discovery beats central registries

Adding a new route or tool should not require editing a router file, an OpenAPI document, and a tool manifest. In this model, adding a feature means adding a tagged class binding. The server that cares about that tag discovers it.

Where the diagram helps

The full architecture map shows the pieces as a runtime system: clients at the edges, a single application context in the center, and contract artifacts emitted from the shared schemas.

Open architecture map Read the hybrid guide