# MCP tool server (app.McpServer)

> `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.

<!-- id: config-mcp-server · area: config · stability: stable · html: https://osysharp.com/reference/config/mcp-server/ -->

## Summary        {#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.

```osy syntax
app.McpServer = new McpServer {
  Catalogs = [
    new ToolCatalog("admin-tools") {
      Description = "Admin-only tools",
      VisibleTo   = IsAdmin,
      Tools = [ new Tool(OrderTotal) ],
    },
  ],
};
```

## Signature      {#signature}
```osy syntax
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    {#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       {#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:

```osy title="basic" test app=config-mcp-example
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       {#see-also}
- [principal predicates (IsAuthenticated / IsAnonymous) and open reads](https://osysharp.com/reference/security/principal-predicates/) — the `[Principal]`, `[Role]`, and `policy` that `VisibleTo` gates a catalog with
- [publishing a REST API (app.Apis)](https://osysharp.com/reference/api/rest/) — `app.Apis`, the HTTP surface that exposes the same functions and entities to non-agent callers
- [using Memory (semantic search)](https://osysharp.com/reference/memory/search/) — the searchable knowledge that `new Tool(Knowledge.Search)` exposes
