MCP Server sample
This page is part of the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at README.md, and llms.txt lists every page.A single-process demonstration of the optional Orleans.Lattice.Api.Mcp add-on.
It co-hosts a single-silo Orleans cluster with the Model Context Protocol (MCP)
server over streamable HTTP, then drives it with a real MCP client - exactly as
an AI agent or MCP-aware tool would - to show the two headline properties of the
surface:
- Permission-scoped discovery. An authenticated agent that has been granted access discovers the state / data / auth tool set and calls a tool end-to-end over MCP, reading back through the data facade a value the host seeded directly on the demo tree.
- Fail-closed by default. A caller the credential bridge cannot authenticate
is offered nothing - not even the
lattice_capabilitiesmeta-tool.
Known issue: the sample registers no
ILatticeApiMcpAuthorizer.AddLatticeMcptherefore falls back to the defaultDenyAllMcpAuthorizer, which the discovery core consults for every group tool when it builds the tool list and again when a tool is called;RequireAuthorization = falsedoes not lift that gate. As written, the agent is offered only thelattice_capabilitiesmeta-tool, so the run cannot complete property 1: itslattice_data_getcall names a tool the session does not offer, which the MCP server answers with a protocol error, so the client throws and the run ends there, before the anonymous-caller act. Property 2 still holds; the run just never reaches the step that shows it. RegisteringAllowAllMcpAuthorizer(or your ownILatticeApiMcpAuthorizer) is the missing step for the agent journey below.
Everything runs in one process for convenience, but the client talks to the
server strictly over MCP using only the SDK's public surface
(McpClient + HttpClientTransport), so Program.cs doubles as a copy-paste
reference for wiring a real MCP client against a Lattice cluster.
Run it
dotnet run --project samples/McpServer/McpServer.csproj
The sample seeds an agent subject with a full-access grant on a demo tree and
prints the agent's discovered tool set. It is written to then print a live
lattice_data_get result and show the anonymous caller being offered zero
tools before it exits, but as written the data call fails and the run ends
there - see the known issue above. It listens on
http://localhost:5290 over plain HTTP to stay dependency-free.
Authorization on the endpoint is disabled purely to keep the sample one-command
runnable with no identity provider: a demo credential bridge maps a request that
carries a marker header onto a fixed agent credential, and a demo authenticator
resolves that credential to the agent subject inside the cluster. A real
deployment leaves RequireAuthorization at its secure default, registers an
ILatticeApiMcpAuthorizer, and lifts an authenticated ASP.NET Core principal
onto the ambient credential instead.
What to look at
Program.cs- the silo + MCP host wiring (AddLatticeMcp/AddStateTools/AddDataTools/AddAuthTools/MapLatticeMcp), the rule seeding, and the MCP client journey.DemoCredentialBridge.cs- the fail-closedILatticeApiMcpCredentialBridgethat decides which requests are the agent and which are anonymous.DemoAuthenticator.cs- the trusted-token authenticator that resolves the ambient credential to a cluster subject.- The package docs under
docs/lattice.api.mcp/cover the full tool catalogue, the security and discovery model, and the remote-hosting topology in depth.