Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / Config

MCP tool server (app.McpServer)

app.McpServer = new McpServer { Catalogs = [ new ToolCatalog("Name") { VisibleTo = Policy, Tools = [ … ] } ] };

`app.McpServer` exposes your app to an MCP client (an AI agent) as a set of tools. Tools are grouped into named `Catalogs`, each gated by a `VisibleTo` policy (who may see it). A tool is one of: `new Tool(Function)` (call one of your functions), `new CrudTool<Entity>() { Operations = [...] }` (create/read/update/delete an entity), or `new Tool(Knowledge.Search)` (semantic search). A singleton.

stable1 example compiled by CIconfigmcpagenttools

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 declared policy. The catalog (and every tool in it) is only visible and callable to principals for whom the policy holds. VisibleTo must 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; Operations chooses which of Create / Read / Update / Delete are 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#

Related

principal predicates (IsAuthenticated / IsAnonymous) and open reads

Two built-in `when` predicates say who a request is: `IsAuthenticated` is a signed-in user, `IsAnonymous` is an…

publishing a REST API (app.Apis)

`app.Apis` publishes your app to a third party over HTTP. You never write a controller or an endpoint handler — you…

using Memory (semantic search)

Opt into semantic (vector) search over your app's content. `using Memory;` adds a searchable store to the app…