Skip to content

MCP Configuration

MCP (Model Context Protocol) servers provide tool access to agents. Each war-room gets its own MCP server instances, creating isolated tool boundaries.

Config files

MCP configuration lives in .agents/mcp/:

FilePurpose
config.jsonUser/project config (highest priority)
mcp-builtin.jsonBuilt-in servers shipped with OSTwin
mcp-catalog.jsonAvailable but inactive servers
extensions.jsonThird-party extension configs
config_resolver.pyResolution engine
vault.pySecret management

Config format

{
"mcp": {
"server-name": {
"type": "local",
"command": ["python", "path/to/server.py"],
"environment": {
"API_KEY": "{env:MY_API_KEY}"
}
}
}
}

Server types

Runs as a child process:

{"channel": {"type": "local", "command": ["python", "{env:HOME}/.ostwin/.agents/mcp/channel-server.py"], "environment": {"AGENT_OS_ROOT": "."}}}

4-tier priority

Configs merge in priority order (highest wins):

PrioritySourceFile
1Per-roomwar-rooms/room-001/mcp.json
2Project.agents/mcp/config.json
3User~/.ostwin/.agents/mcp/config.json
4Built-in.agents/mcp/mcp-builtin.json

Higher-priority sources override lower ones per server name. A server set to null in a higher tier disables it.

Variable resolution

Environment variables use {env:VAR} syntax with optional defaults:

{
"environment": {
"API_KEY": "{env:ANTHROPIC_API_KEY}",
"PORT": "{env:MCP_PORT:-8080}",
"LOG_LEVEL": "{env:MCP_LOG_LEVEL:-info}"
}
}

Vault secrets

For sensitive values, use vault references instead of env vars:

{"environment": {"API_KEY": "${vault:github/token}", "DB_PASSWORD": "${vault:database/password}"}}
  1. Add a secret: python dashboard/scripts/vault_get.py set github token "ghp_your_token"

  2. Reference it in MCP config using ${vault:server/key} syntax.

  3. Verify. The resolver validates all vault refs at startup and errors on missing secrets.

Per-room MCP

Override servers for specific war-rooms with mcp.json in the room directory:

{
"mcp": {
"database": {
"type": "local",
"command": ["python", "tools/db-server.py"],
"environment": {"DB_URL": "postgresql://localhost/room001_db"}
}
}
}

This gives room-001 a database server no other room can access.

Adding custom servers

  1. Write the server following MCP protocol:

    from mcp.server import Server
    server = Server("my-tools")
    @server.tool()
    async def my_tool(param: str) -> str:
    """What this tool does."""
    return f"Result for {param}"
    if __name__ == "__main__":
    server.run()
  2. Add to config.json:

    {"mcp": {"my-tools": {"type": "local", "command": ["python", "tools/my-server.py"], "environment": {"AGENT_OS_ROOT": "."}}}}
  3. Validate: python .agents/mcp/validate_mcp.py

Built-in servers

ServerFileTools
channelchannel-server.pypost_message, read_messages, get_latest
warroomwarroom-server.pyupdate_status, report_progress, list_artifacts
memorymemory-core.pypublish, query, search, get_context

Audit logging

Tool calls are logged to .agents/mcp/logs/. Watch with tail -f .agents/mcp/logs/channel-server.log. Entries include timestamp, tool name, parameters, and result status.

Token optimization

MCP tool definitions consume context tokens. Minimize overhead:

{"mcp": {"playwright": null, "chrome-devtools": null}}

Setting a server to null removes it from resolution.

Troubleshooting

SymptomFix
”Vault reference not found”Add the secret via vault script
Server fails to startVerify path uses {env:HOME} correctly
Tools not visibleAdd server to config.json
Env variable emptyAdd to ~/.ostwin/.env
Resolver errorValidate JSON: python -m json.tool < config.json