managed-agent-control-mcp
managed-agent-control-mcp
Start, observe, and interact with Claude Managed Agents from any MCP client (Claude.ai, Claude Code, Cursor, mcp-remote, your own agent, …).
Claude Managed Agents run on Anthropic's platform — each is an agent definition
(model, system prompt, tools, skills) that executes inside a sandbox environment.
This MCP server puts a remote control on those agents: connect it to any MCP
client and you can launch an agent, watch what it does, reply to it, approve the
tools it wants to run, and stop it. Claude.ai is the showcase client (do it all
from a normal conversation), but the same tools work from Claude Code, Cursor,
mcp-remote, the MCP Inspector, or a custom MCP client. It is the runtime
companion to the Terraform provider
that defines agents declaratively.
It runs as a local stdio server, a generic HTTP container, or on AWS Lambda, with pluggable inbound auth (static bearer, generic OIDC, or an AWS Cognito preset).
This is a community project. It is not maintained by, endorsed by, or affiliated
with Anthropic. The Managed Agents API is a beta API (managed-agents-2026-04-01).
How it works
MCP client ──MCP──▶ managed-agent-control-mcp ──HTTPS (x-api-key)──▶ Managed Agents API
(Claude.ai, (this server: tools + auth) (agents run here)
Claude Code, …)You drive a loop: discover an agent → start a session → observe by
polling events → interact (reply / interrupt / approve tools) → end.
Because MCP tool calls are request/response, observation is by polling
(session_events / session_get) — there is no live stream into the chat.
Related MCP server: aichat-mcp
Quickstart (local, <2 min)
You need an ANTHROPIC_API_KEY with Managed Agents access and
uv.
git clone https://github.com/modus-agendi/managed-agent-control-mcp
cd managed-agent-control-mcp
uv sync
# Run the server over stdio:
ANTHROPIC_API_KEY=sk-ant-... uv run python -m managed_agents_mcpExplore the tools interactively with the MCP Inspector:
ANTHROPIC_API_KEY=sk-ant-... npx @modelcontextprotocol/inspector \
uv run python -m managed_agents_mcpRegister it with Claude Code (a project-scoped .mcp.json is included):
claude mcp add managed-agent-control -- uv run python -m managed_agents_mcpOnce published to PyPI, you can skip the clone: uvx managed-agent-control-mcp.
Tools
Tier | Tool | Does |
Discover |
| Find an agent and inspect its config |
| Find a sandbox environment | |
| Find a credential vault to attach at | |
| Find a persistent memory store | |
Start |
| Create a session and (optionally) send the first instruction |
Observe |
| Status ( |
| List sessions | |
| Poll the agent's output/activity (cursor + type filter) | |
Interact |
| Send a message / continue a turn |
| Stop or redirect a running agent | |
| Approve/deny a tool the agent is waiting on | |
Destructive 🔒 |
| Archive (keep history) or delete |
See docs/tools.md for every argument and return shape.
Configuration
Only ANTHROPIC_API_KEY is required for local use. Full reference in
docs/configuration.md.
Env var | Purpose |
| Required. Operator key the server acts with. |
| Override the API base URL (gateways/testing). |
| Inbound auth for HTTP: |
| Shared token for |
| JWT verification for |
|
|
| Agents |
|
|
Authentication
There are two auth layers (kept separate by design):
Outbound — how this server calls Anthropic: your
ANTHROPIC_API_KEY.Inbound — how MCP clients authenticate to this server. Pluggable and required for any HTTP deployment:
bearer — a shared static token. Simplest; works with Claude.ai connectors and
mcp-remote.oidc — verify JWTs from any OIDC provider (Auth0, Okta, Keycloak, Entra, Cognito).
cognito — the OIDC verifier plus the hosted-UI OAuth facade Cognito needs.
Setup and Claude.ai connector onboarding: docs/authentication.md.
Never expose an HTTP deployment without an inbound auth mode set. Anyone who passes inbound auth can drive your Anthropic key — scope the key and use theguardrails.
Deployment
Target | How |
Local (stdio) |
|
Container (HTTP) |
|
AWS Lambda | Self-contained Terraform module in |
Details: docs/deployment.md.
Documentation
Configuration — every env var + guardrails
Authentication — bearer / OIDC / Cognito + Claude.ai setup
Deployment — local, container, Lambda
Architecture — module map, the two auth layers, the polling model
Tools — full tool reference
Examples — end-to-end deployment walkthroughs (host + OAuth provider)
Contributing
Contributions welcome — see CONTRIBUTING.md and the Code of Conduct. Found a security issue? See SECURITY.md.
License
MIT — see LICENSE. Maintained by Andrei Svirida.
Available Tools
17 toolsagent_getA
Get one agent's full configuration by agent_* id.
Read this BEFORE starting a session: the agent's description, metadata, model,
system prompt, tools, mcp_servers, and skills tell you what it does — and
therefore which environment, vault(s), and memory store(s) you must attach at
session_start for it to work. Then match those against environment_list /
vault_list / memory_store_list.
Inputs: agent_id (required). Returns: object
agent_listA
List managed agents (summaries: id, name, model, description, metadata).
Find an agent_* to run (unless the user gave one). Read each agent's
name/description/metadata to understand what it does — that determines which
environment, vault(s), and memory store(s) it needs. Use agent_get for full
config before starting. Page via the returned next_page token.
Inputs: limit, page. Returns: object
environment_getA
Get one environment's full configuration by env_* id (packages, networking).
Inputs: environment_id (required). Returns: object
environment_listA
List sandbox environments (summaries: id, name, description, metadata).
Starting a session needs an env_*. Don't just grab the first — pick the
environment that fits THIS agent by matching its name/description/metadata to
the agent (e.g. metadata.agent_name, or a shared naming convention). The wrong
environment gives the agent the wrong tools/packages. Page via next_page.
Inputs: limit, page. Returns: object
memory_store_getA
Get one memory store's details by memstore_* id (name, description, timestamps).
Inputs: memory_store_id (required). Returns: object
memory_store_listA
List memory stores (summaries: id, name, description, metadata).
memstore_* stores are the agent's persistent memory, mounted as a directory.
Attach the store that BELONGS to THIS agent at session_start(memory_store_ids=[…])
— match its name/description/metadata to the agent (commonly
metadata.agent_name=<agent> or a name like "-memory"). The wrong store, or
none, means the agent loses its history/context. Page via next_page.
Inputs: limit, page. Returns: object
session_archiveA
Archive a session: stop accepting new events but keep its history. Reversible-ish.
Inputs: session_id (required). Returns: object
session_deleteA
Permanently delete a session (history + sandbox). Cannot delete a running session.
Inputs: session_id (required). Returns: object
session_eventsA
Read a session's events — the agent's output and activity. POLL this to observe.
To observe new output as the agent works, poll: pass the returned next_since
back as since on the next call to fetch only events recorded after the last
batch (events are returned oldest-first). Filter with types (e.g.
["agent.message"] for just the agent's text, or ["agent.tool_use",
"agent.tool_result"] for tool activity). When has_more is true within a
batch, pass the returned next_page token as page. Large payloads truncated.
Common types: agent.message (text), agent.thinking, agent.tool_use / agent.tool_result, agent.mcp_tool_use, session.status_idle (with stop_reason).
Inputs: session_id (required), types, since, limit, +1 more. Returns: object
session_getA
Get a session's current status and token usage.
Status is one of: idle (waiting for input — done with its turn), running
(working), rescheduling (retrying), terminated (ended on error). When idle
with a stop_reason of requires_action, the agent is waiting on a tool
confirmation — use session_respond.
Inputs: session_id (required). Returns: object
session_interruptA
Interrupt a running agent, optionally redirecting it with a new instruction.
Sends a user.interrupt; if then_message is given, it follows immediately so
the agent stops what it's doing and takes the new direction.
Inputs: session_id (required), then_message. Returns: object
session_listA
List sessions, optionally filtered to one agent_id and/or statuses.
statuses filters by session status (e.g. ["running", "idle"]). Returns id +
status each; page with the returned next_page token when has_more is true.
Inputs: agent_id, statuses, limit, page. Returns: object
session_messageA
Send a user message to the agent — start work, reply, or continue a turn.
Use to give the agent a new instruction or to resume an idle session. After
sending, OBSERVE by polling session_events.
Inputs: session_id (required), text (required). Returns: object
session_respondA
Approve or deny a tool call the agent is waiting on (a permission policy gate).
When session_get shows status "idle" with stop_reason requires_action, the
agent paused for confirmation. The blocking event ids are in
stop_reason.event_ids. Call this with tool_use_id = the blocking event id
and result = "allow" or "deny" (add deny_message to explain a denial).
Inputs: session_id (required), tool_use_id (required), result (required), deny_message. Returns: object
session_startA
Start a managed-agent session — with the RIGHT resources attached for THIS agent.
Do NOT start bare or with mismatched resources. An agent only behaves well when its OWN environment, vault(s), and memory store(s) are attached; the wrong or missing ones cause failed tool authentication, lost memory/context, and bad outcomes.
Before calling, assemble the resources for this agent:
agent_get(agent_id)— read its description, metadata, mcp_servers, skills.Choose
environment_id+vault_ids+memory_store_idsthat BELONG to this agent by matching each resource's name/description/metadata (oftenmetadata.agent_name=<agent>, or "-vault" / "-memory"). Use environment_list / vault_list / memory_store_list (and *_get when unsure). If you can't confidently match a resource, ask the user — don't guess or skip it.
Then:
vault_ids—vlt_*credential vaults (else MCP servers needing auth fail).memory_store_ids—memstore_*persistent memory mounted in the sandbox.message— sent as the first instruction now (omit to only provision).agent_version— pin a version (default: latest).
Returns the session_id. After starting, OBSERVE by polling
session_get/session_events until status is "idle".
Inputs: agent_id (required), environment_id (required), message, vault_ids, +2 more. Returns: object
vault_getA
Get one vault's details by vlt_* id (display name, metadata, timestamps).
Secret values are never returned — Anthropic stores and injects them. This is metadata only, to confirm the vault is the one you want before attaching it.
Inputs: vault_id (required). Returns: object
vault_listA
List credential vaults (summaries: id, display_name, metadata).
An agent whose MCP servers need auth must start with the vlt_* vault that
BELONGS to it (session_start(vault_ids=[…])), or those servers fail to connect.
Identify the right vault by matching its display_name/metadata to the agent —
commonly metadata.agent_name=<agent> or a name like "-vault". Attaching
the wrong vault, or none, breaks the agent's tools. Page via next_page.
Inputs: limit, page. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 17 tools
Each tool targets a distinct resource (agent, environment, vault, memory store, session) and action (list, get, start, etc.). No two tools serve overlapping purposes; even session_archive and session_delete are clearly differentiated by their effects.
Tool names follow a consistent noun_verb pattern (e.g., agent_get, session_start), all lowercase with underscores. There is no mixing of conventions across the tool set.
17 tools cover the domain of managed-agent control without being excessive. Each tool serves a needed function, and there are no redundant or trivial tools.
The tool set covers the full session lifecycle (start, message, observe, interrupt, respond, archive, delete). While resource management (e.g., create/update for agents, environments) is missing, it is likely out of scope, making the surface complete for its control purpose.
Maintenance
Related MCP Connectors
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Build and manage AI-native customer support agents from Claude or any MCP client.
One MCP endpoint for Claude, GPT & Gemini: 100+ tools + no-code connectors + agent workers.
Real-time chat hub for AI agents — Claude Code, Cursor, Cline, Codex over MCP or REST.
Related MCP Servers
- AlicenseAqualityBmaintenanceWraps the Claude Agent SDK as MCP servers, letting you spawn multiple specialized Claude Code agents — each with its own model, tools, system prompt, and personality — from any MCP client.5111 npm22ISC
- AlicenseAqualityDmaintenanceMCP server for inter-agent communication. Gives multiple Claude Code sessions a shared message board, agent registry, and orchestration layer — backed by a cloud relay so agents can coordinate across machines, repos, and teams.860 npm1MIT
- AlicenseAqualityCmaintenanceMCP server that exposes a pool of Claude SDK agents as tools, enabling deterministic agent creation, retrieval, and resumption from a capability corpus.1064 PyPI1MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to securely discover, execute, and observe tools with role-based access control and audit logging. Serves tools over MCP stdio and HTTP for integration with Claude Desktop, Cursor, and other clients.1-