Summary#
app.McpServer exposes your application to an MCP (Model Context Protocol) client — typically an AI agent — as a set of
tools the agent may call. As with the REST surface, you expose what you already have rather than write a tool
handler: a tool is one of your functions, an entity's CRUD operations, or a semantic search over your knowledge. Tools
are grouped into named catalogs, and each catalog is gated by a VisibleTo policy that decides which principals may
see and call it. app.McpServer is a singleton — an app has at most one MCP server.
app.McpServer = new McpServer {
Catalogs = [
new ToolCatalog("admin-tools") {
Description = "Admin-only tools",
VisibleTo = IsAdmin,
Tools = [ new Tool(OrderTotal) ],
},
],
};Signature#
app.McpServer = new McpServer {
Catalogs = [ // one entry per named group of tools
new ToolCatalog("Name") { // the catalog's name, shown to the client
Description = "…", // optional; describes the catalog to the agent
VisibleTo = IsAdmin, // a declared `policy` — who may see this catalog
Tools = [ // the tools this catalog exposes
new Tool(OrderTotal), // call a function
new CrudTool<Order>() { Operations = [CrudOp.Read] }, // CRUD over an entity
new Tool(Knowledge.Search), // semantic search
],
},
],
};app.McpServer is a singleton; its Catalogs is a list — an app may group its tools into several independently-gated
catalogs.
Description#
A ToolCatalog has:
"Name"— the catalog's name, passed to the constructor, shown to the MCP client.Description(optional) — prose describing the catalog to the agent.VisibleTo— the name of a declaredpolicy. The catalog (and every tool in it) is only visible and callable to principals for whom the policy holds.VisibleTomust name a declared policy — an undeclared name is a compile error that lists your policies. The policy is defined over your[Principal]and its[Role], e.g.policy IsAdmin => user.Role == AppRole.Admin;.Tools— a list of tools. A tool is one of three kinds:new Tool(Function)— exposes one of your functions as a callable tool. The function must be declared — an unknown name is a compile error that lists your functions.new CrudTool<Entity>() { Operations = [CrudOp.…] }— exposes create/read/update/delete over one entity;Operationschooses which ofCreate/Read/Update/Deleteare available. The entity must be defined in your app.new Tool(Knowledge.Search)— exposes semantic (vector) search over your app's searchable knowledge.
A catalog is either a group of CRUD/function tools or a polymorphic tool group — a catalog mixes tool kinds
freely, but each Tools entry is exactly one tool. You write no tool schema, no argument parsing, and no dispatch: the
signature of the function and the shape of the entity are the contract.
Examples#
A complete app that exposes one function and one entity's full CRUD as an admin-only catalog. Note the catalog needs a
declared [Principal], its [Role] enum, and the policy that VisibleTo references:
entity Order { [Required, MaxLength(200)] string CustomerRef; decimal Total; }
[Role] enum AppRole { Staff, Admin }
[Principal] entity User {
[MaxLength(200)] string Email;
AppRole Role;
}
policy IsAdmin => user.Role == AppRole.Admin;
decimal OrderTotal(decimal subtotal, decimal tax) { return subtotal + tax; }
app.McpServer = new McpServer {
Catalogs = [
new ToolCatalog("admin-tools") {
Description = "Admin-only tools",
VisibleTo = IsAdmin,
Tools = [
new Tool(OrderTotal),
new CrudTool<Order>() { Operations = [CrudOp.Create, CrudOp.Read, CrudOp.Update, CrudOp.Delete] },
],
},
],
};See also#
- principal predicates (IsAuthenticated / IsAnonymous) and open reads — the
[Principal],[Role], andpolicythatVisibleTogates a catalog with - publishing a REST API (app.Apis) —
app.Apis, the HTTP surface that exposes the same functions and entities to non-agent callers - using Memory (semantic search) — the searchable knowledge that
new Tool(Knowledge.Search)exposes