Declares which commands, queries and aggregates an application offers over MCP.
defmodule MyApp.Interface.MCP do
use DDD.MCP.Server,
instructions: "Manage todo lists.",
commands: [MyApp.Commands.CreateList, {MyApp.Commands.RenameItem, name: "rename_todo"}],
queries: [MyApp.Queries.OpenItems],
repos: [MyApp.TodoList.Repository],
read_only: false,
authorize: &MyApp.MCPPolicy.authorize/2
endNothing is exposed unless it is listed here, and the commands and entities themselves know
nothing about MCP. The level of access is what you list: a server with only queries: and
repos: can only read.
commands:andqueries:become tools. A module is listed alone, or as{Module, name: "tool_name"}. The default name is the last module segment in snake case.repos:become read-only resources, one per repository. List the repository port (it says which aggregate and whichfind_bylookups exist), or{Aggregate, repository: Port}. The port must defineimpl/0.read_only: truerefuses every command tool.authorize:is a function(name, arguments) -> :ok | {:error, reason}called before each tool call (with the tool's name) and resource read (with"resource:<name>"and%{"uri" => uri}).name:,version:andinstructions:are reported to the client.
Every exposed module needs a description. A missing one, or two tools with the same name,
raises when the server is built (at startup), not when a client calls.
The module gets handle/1 (one decoded JSON-RPC message), serve/1 (the stdio loop) and
registry/0. Run it with mix vic.mcp MyApp.Interface.MCP.