VS MCP Bridge
Source of Truth: docs/ARCHITECTURE.md
Status: Canonical repo cleanup aligned to the current architecture as of 2026-05-16. Bracket-style tokens are intentional BlogEngine/GwnWikiExtension tokens.
VS MCP Bridge Blog Series: Part 1
From VSIX Startup to the First MCP Tool Call
This post is the first in a short developer ramp-up series for the VS MCP Bridge project. Its job is to make the startup flow understandable before diving into individual tools, proposal approval, diagnostics, and security seams.
The key question is simple: what actually happens from the moment Visual Studio loads the VSIX until an AI client can make a useful MCP tool call?
The Short Version
The bridge has two local process boundaries, not one.
- The VSIX runs inside Visual Studio and owns Visual Studio APIs, editor state, proposal approval, and the local Named Pipe Listener.
- The MCP server runs as a separate local process and waits on Stdio for MCP protocol messages from an AI client.
- The MCP server exposes a small explicit tool surface. For VS-backed tools, it forwards typed requests to the VSIX over the named pipe.
- The VSIX dispatches only known bridge commands, performs the Visual Studio-side operation, and sends a structured response back.
The important mental model is that the VSIX is not a chat endpoint. It waits for structured bridge requests. Natural-language reasoning happens in the AI client; bridge execution happens through explicit tool and command boundaries.
Step 1: Visual Studio Loads the VSIX Package
The Visual Studio entry point is the package class, VsMcpBridgePackage. It is an AsyncPackage that composes VSIX services and registers the command that opens the bridge tool window.
At startup, the package path is responsible for four important things:
- Registering the command that can open the bridge tool window.
- Building the dependency injection container.
- Composing shared and VSIX-specific services.
- Starting the named-pipe side of the local bridge when the VSIX is initialized.
This is the first major clarification for new developers: Visual Studio work stays in the VSIX. The MCP-facing process does not load inside Visual Studio and does not own DTE or editor access.
Step 2: Dependency Injection Assembles the Runtime
The package itself stays relatively thin. Most behavior is composed through dependency injection so the Visual Studio host and standalone app host can share the same infrastructure where that makes sense.
During startup, the service collection registers components such as:
- logging and unhandled exception capture
- configuration-backed host services
- proposal approval state
- Visual Studio service access
- edit proposal and apply services
- tool window presenter and view model
- named pipe server
That means the startup path can feel indirect in the debugger unless you remember that the package is mainly a composition root.
Step 3: The VSIX Listens on a Named Pipe
Once the pipe server is available, it listens on the fixed local pipe name VsMcpBridge. That pipe is the handoff point between the external MCP server process and the Visual Studio host.
The Visual Studio side is then alive but idle. In that idle state:
- the VSIX package has loaded
- services have been composed
- the local pipe boundary is the intended VS-backed request entry point
- no MCP request has arrived yet
Operationally, live validation has shown one practical rule: if VS-backed tools cannot connect to the pipe, open the Visual Studio Experimental Instance and then open View -> Other Windows -> VS MCP Bridge. That activation path initializes the VSIX/tool-window side in the environment where manual validation has been proven.
Step 4: The Tool Window Is the Human Review Surface
The tool window is not a generic chat window. It is the operator-facing surface for logs, proposal entry, proposal review, approval, rejection, and outcome messages.
When the tool window is created, it resolves the presenter and view model, binds the shared WPF control, and initializes the UI state. The initial UI is idle:
- logs are ready for diagnostic output
- proposal fields are empty
- the approval surface is inactive until a proposal exists
This distinction matters because bridge transport, tool execution, and human approval are related but separate concerns.
Step 5: The MCP Server Waits on Stdio
The project also contains a separate process, VsMcpBridge.McpServer. This process hosts the MCP server and uses stdio for protocol traffic.
That means an AI client can launch the MCP server process, write MCP messages to standard input, and read MCP responses from standard output. The server does not need to expose an HTTP endpoint or a public network port for this local workflow.
At this point the architecture has two different waiting states:
- the VSIX waits for a named-pipe request
- the MCP server waits for an MCP message over stdio
Keeping those transports separate is one of the main reasons the project is understandable. Stdio gets the request into the local MCP process. The named pipe gets the VS-backed request into Visual Studio.
Step 6: The First Tool Call Arrives
When a user submits a prompt in an AI client, nothing special happens in the bridge unless the AI client chooses to call one of the registered MCP tools.
For a VS-backed tool call, the flow looks like this:
- The AI client sends an MCP tool request over stdio.
VsMcpBridge.McpServer receives the request.
- The selected MCP tool method forwards typed work through the pipe client.
- The pipe client connects to the local
VsMcpBridge named pipe.
- The VSIX pipe server accepts the connection and reads the request envelope.
- The pipe server dispatches only known commands to the Visual Studio service layer.
- The VSIX performs the host-side operation and returns a response.
- The MCP server returns the result over stdio to the AI client.
This is where the bridge stops being idle and starts doing useful work.
Read-Only Calls vs. Edit Proposals
Read-only operations such as reading the active document, reading selected text, listing solution projects, or reading the Error List are straightforward. The VSIX performs the Visual Studio operation and returns data.
Edit-oriented requests are different. MCP can create edit proposals, but apply still happens only after explicit approval in the host UI. The proposal path validates the target content before mutation and keeps Visual Studio control over file changes.
That design is deliberate: the AI side can suggest changes, but the host side owns approval, apply, rollback behavior, and final outcome reporting.
Where Shared Tool Security Fits
The current architecture also has a shared compiled tool execution boundary for bridge tools outside the direct VS-backed pipe command path. Shared tools run through BridgeToolExecutor, which is the policy, approval, execution, audit, and redaction boundary for those tools.
That boundary now carries several lightweight security and observability seams:
- tool execution policy evaluation
- optional approval-aware execution for tools that require it
- declarative capability metadata
- secret-reference indirection hooks
- redaction before payload-oriented logs and audit metadata
- structured audit envelopes with classification metadata
- request and operation correlation metadata
Those seams are not a full authentication, OAuth, vault, sandbox, or SIEM system. They are intentional architecture joints that make later hardening possible without turning tool execution into a black box.
Why Diagnostics Matter
Stdio is protocol traffic, so stdout must stay clean. Diagnostics need to go through safe channels such as app-data logs, stderr where appropriate, and host UI logging.
The bridge also follows an anti-black-box rule: important workflows should leave enough evidence to reconstruct what happened. That is why recent architecture work records durable trace artifacts and Mermaid diagrams for tool execution, approval-aware execution, MEF discovery, and inactive VSIX named-pipe diagnostics.
For example, if a VS-backed tool cannot connect to the named pipe, the current server returns an activation diagnostic instead of an opaque timeout. The operator action is concrete: launch the Visual Studio Experimental Instance, open the VS MCP Bridge tool window, and retry the VS-backed tool.
Why This Architecture Exists
At first glance, it can seem odd that both stdio and named pipes exist in the same design. The reason is that they solve different problems:
- stdio is the local protocol transport between an AI client and the MCP server process
- named pipes are the local host bridge between the MCP server process and Visual Studio
- the tool window is the human-facing review and diagnostics surface
- BridgeToolExecutor is the shared compiled-tool policy and audit boundary
This split keeps Visual Studio API access inside the VSIX, keeps MCP protocol handling outside Visual Studio, and gives future tool work a clear place for policy, approval, redaction, audit, and correlation.
Takeaway
If you are trying to understand startup, the cleanest mental model is this:
Visual Studio starts VSIX
- package initializes
- services are composed
- named pipe side becomes the VS-backed request boundary
- tool window activation may be required for live validation
AI client starts MCP server
- MCP server starts
- stdio transport waits for MCP protocol messages
- registered MCP tools become callable
User submits a prompt
- AI may call an MCP tool
- MCP server handles protocol work
- VS-backed calls cross the named-pipe boundary
- shared compiled tools cross BridgeToolExecutor
- host-side results flow back to the AI client
In other words, VS MCP Bridge is not one big chat loop. It is a set of explicit local boundaries: MCP over stdio, Visual Studio work over a named pipe, user approval in the host UI, and shared tool execution behind a policy/audit executor.
Next In The Series
The next post should answer a natural follow-up question: why stdio is used at all, what it is good at, and why it should not be treated as a multi-client shared bus.