إنتقل إلى المحتوى الرئيسي

MCP server authoring guide

What this page is

How to add a new MCP server domain to AuroraSOC. Covers the tool surface contract, the launcher integration, the auth/audit model agents inherit, and the compose-stack integration so the new server is reachable.

Why it exists this way

The MCP plane is the boundary between agents and side-effecting infrastructure. Every privileged action an agent can take goes through an MCP tool; the tool runs in a separate process with its own policy. Adding a new domain (the WAF MCP that landed this wave is a recent example) is a recurring task; this page makes the recipe explicit.

How it works

A new domain takes four steps:

  1. Define the tools. Create a module under packages/backend/aurorasoc/tools/. Each tool is a BeeAI Tool subclass with a Pydantic input schema. Inputs declare their fields explicitly; Any is not acceptable. The tool docstring is the prompt the agent sees when picking tools, so write it in clear plain English.

  2. Register the server. Add a server.py next to the tool modules. The server class subclasses the existing MCP server base and lists the tools it exposes. The launcher reads the domain name from MCP_DOMAIN at startup and instantiates the matching server. See aurorasoc.tools.mcp_launcher for the dispatch table.

  3. Wire the port and the compose service. Pick the next unused port in packages/backend/aurorasoc/config/settings.py under MCPSettings; the unique-ports validator catches collisions at startup. Add a service stanza in infra/compose/docker-compose.yml following the existing pattern (build from the shared agent.Dockerfile, set MCP_DOMAIN, depend on Redis).

  4. Update the orchestrator dependency. If the orchestrator needs the new domain to be present for a class of investigations, add it to the orchestrator's depends_on in compose so the orchestrator fails loudly when the server is missing rather than silently degrading.

Auth and audit

Every tool call goes through require_permission (see Permission taxonomy codegen). The permission pair is declared at the tool level; the launcher refuses to start a server whose tools declare an unknown pair.

Every tool call is logged to the decisions:tools Redis Stream by the base class, so the new domain inherits the audit trail without writing any per-tool boilerplate.

What goes wrong

  • MCP_DOMAIN env var typo, the launcher exits with the list of known domains. Add the new one to the dispatch table in mcp_launcher if it is genuinely new.
  • Tool calls return but the orchestrator never sees them, most often the agent did not pick the tool because the docstring did not match its intent. Rewrite the docstring; agent prompts are the closest thing to a contract.
  • A tool's permission check fails because the require_permission pair is not in permission_taxonomy.py. Add the pair in aurora-schema, re-run the codegen, commit both in one atomic change per the codegen rules.