Here is a debugging session I have run more times than I would like to admit. A gateway service in an Aspire app returns 500s. I flip to the dashboard, read a trace, copy the exception into a chat window, paste the correlated log lines under it, add the offending resource's console output for good measure, and finally ask the assistant what it thinks. The assistant is genuinely helpful — but I have spent four minutes being a human clipboard, and I will do it again the moment it asks a follow-up question about a different service.
The Aspire MCP server exists to delete that ritual. It is a Model Context Protocol server that hands your AI coding agent a live, structured view of the running application — resources, logs, traces, and, crucially, the commands to act on them. The interesting part is not that "AI can now see your logs." It is where the server runs and what it is allowed to touch, because those two decisions turn a plausible security nightmare into something you can leave on by default.
The copy-paste tax
An Aspire AppHost is a small orchestrator: it stands up your projects, containers, and integrations, and the dashboard aggregates their telemetry into one place. That aggregation is exactly what an agent lacks. Without it, the agent's model of your system is whatever prose you feed it, and prose goes stale the instant you restart a container. The MCP server replaces the prose with a query interface. Instead of describing that the apiservice resource is unhealthy, the agent calls a tool and reads the health state itself — endpoints, current status, and the commands that resource supports, in one shot.
What the server actually exposes
The tool surface is small and deliberately shaped around a debugging loop, not around "everything the dashboard can render." It splits into three jobs.
Observe — the read side that ends the clipboard work:
list_resources — every resource with state, health, endpoints, and available commands
list_console_logs — raw console output for a named resource
list_structured_logs — OpenTelemetry log entries, optionally filtered by resource
list_traces and list_trace_structured_logs — distributed traces and the logs tied to a specific trace
Act — the tool that earns the "DevOps" framing:
execute_resource_command — run start, stop, or restart against a resource
Orient — discovery so the agent can navigate a multi-project solution and the ecosystem:
list_apphosts / select_apphost — detect and switch between running AppHosts
list_integrations / get_integration_docs — the hosting-integration catalog and its docs
list_docs / search_docs / get_doc — keyword search over the official documentation
doctor — diagnose a broken local setup
refresh_tools — re-emit the tool list when the client needs it
That execute_resource_command entry is the line between an assistant that narrates your outage and one that responds to it. "The migrations container exited before the API came up — restart it and re-check health" stops being a two-window chore and becomes a single tool call the agent can make and verify.
Wiring it up
You do not hand-author the config. The CLI detects your environment and scaffolds it:
aspire agent init
Pick Install Aspire MCP server and it writes the right file for each agent it finds. The shapes differ per client, but the command underneath is always the same aspire agent mcp process:
// .vscode/mcp.json (VS Code)
{
"servers": {
"aspire": { "type": "stdio", "command": "aspire", "args": ["agent", "mcp"] }
}
}
// .mcp.json (Claude Code)
{
"mcpServers": {
"aspire": { "command": "aspire", "args": ["agent", "mcp"] }
}
}
The same generator covers Copilot CLI and OpenCode. (If you have been following the CLI across releases: the older aspire mcp verbs are being folded into aspire agent, and the generated configs already use the new form.)
Why STDIO matters more than it sounds
Read the config again and notice what is missing: there is no URL, no port, no token. The transport is STDIO. The server is not a network service you start and firewall — it is a child process your agent spawns, talking over stdin/stdout pipes.
No open port means no listening socket, which means no network attack surface and nothing to authenticate against. Access is bounded by who can already spawn the process — which is you, on your own machine.
That is a materially different posture from an HTTP MCP server, and it is why leaving this on does not keep me up at night. The blast radius is a local pipe.
The scope is fenced off on the data side too. The server surfaces resource metadata, logs, traces, the integration catalog, and docs. It does not hand over your source code, environment variables and secrets, raw network traffic, or the host machine beyond the AppHost. And when a specific resource should stay invisible — a component holding credentials, say — you exclude it at the source:
builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.ExcludeFromMcp();
The resource still runs and still shows in the dashboard; it simply never reaches the agent.
The takeaway
Treat the MCP server as an operator you scoped down on purpose, not a firehose you pointed at your app. Turn it on for the AppHost you are actively debugging, ExcludeFromMcp() anything that carries secrets, and let the agent read list_traces and drive execute_resource_command instead of asking you to. The next time a container dies on startup, the fix is one tool call away — and you never touch the clipboard. Run aspire agent init before your next debugging session and find out how much of your "AI-assisted" workflow was actually just you, moving text between two windows.
Sources: Aspire MCP server for AI coding agents (aspire.dev) · aspire agent init command reference (aspire.dev) · What's new in Aspire 13.1 (aspire.dev)