MCP Bridge

Bridge MCP servers to VS Code Copilot Chat — expose any MCP tool as a native Copilot Chat tool via vscode.lm.registerTool().
In corporate environments where native MCP support in VS Code Chat is blocked by policy, MCP Bridge provides an alternative path: it connects to MCP servers as a regular VS Code extension and exposes their tools to Copilot Chat.
✨ Features
- 🔌 Multi-server support — Connect to any number of MCP servers simultaneously
- 🚀 All transports — Stdio, SSE, and Streamable HTTP
- 🛠️ Tool bridging — MCP tools accessible in Copilot Chat via 2 static proxy tools (
mcp-bridge_call_tool + mcp-bridge_list_tools)
- 🔒 OAuth 2.1 + PKCE — Built-in authentication for HTTP-based MCP servers
- 🔄 Auto-reconnection — Exponential backoff reconnection when servers disconnect
- 🔍 Server discovery — Automatically detect servers from VS Code, Claude Desktop, and Cursor configs
- 🌲 Sidebar TreeView — Visual management of servers, tools, resources, and prompts
- 🔐 SecretStorage — OAuth tokens stored securely via VS Code SecretStorage
✨ New in v0.4.0
- 📦 Schema cache (F1) — TTL-based tool schema cache, refreshed on server connect (
mcpBridge.schemaCacheTtlMinutes)
- 🗒️ Audit log (F2) — JSONL append-only record of every tool call, queryable via
mcp-bridge_get_audit_log (mcpBridge.auditLog.*)
- 💊 Health dashboard (F3) — Per-server latency + error rate badges in the sidebar tree (
mcpBridge.healthDashboard.*)
- ✅ Rich confirmation (F4) — Markdown confirmation previews before tool calls, with write-detection (
mcpBridge.confirmCalls)
- 🛡️ Resilience (F5) — Per-server retry + circuit breaker via cockatiel (
mcpBridge.resilience.*)
- ✂️ Auto-chunking (F6) — Automatic truncation/pagination for large MCP responses (
mcpBridge.responseLimit.*)
- 🗂️ Registry templates (F7) — One-click install for popular MCP servers (GitHub, Filesystem, Brave Search, PostgreSQL, SQLite, Puppeteer)
- 📤 Config sync (F8) — Export and import server configurations, redacting secrets on export (
mcp-bridge_export_config, mcp-bridge_import_config)
- 👤 Profiles (F9) — Named sets of active servers with status bar indicator and quick-switch (
mcp-bridge_switch_profile, mcpBridge.profiles)
- ⚙️ Settings panel (F10) — Unified webview UI for all configuration (
MCP Bridge: Open Settings Panel)
🚀 Quick Start
- Install the extension from the VS Code Marketplace
- Add a server via the command palette (
MCP Bridge: Add Server) or in settings.json:
{
"mcpBridge.servers": {
"my-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@anthropic/mcp-server-atlassian"],
"env": {
"ATLASSIAN_API_TOKEN": "${env:ATLASSIAN_API_TOKEN}"
}
}
}
}
- Use in Copilot Chat — Reference
#mcpTool or use @mcp /tools to discover available tools
⚙️ Configuration
Add MCP servers to your VS Code settings.json under mcpBridge.servers:
{
"mcpBridge.servers": {
"atlassian": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@anthropic/mcp-server-atlassian"],
"env": {
"ATLASSIAN_API_TOKEN": "${env:ATLASSIAN_API_TOKEN}"
},
"enabled": true
},
"my-api": {
"type": "sse",
"url": "http://localhost:3000/sse",
"headers": {
"Authorization": "Bearer ${env:MY_API_TOKEN}"
}
},
"remote": {
"type": "streamable-http",
"url": "https://mcp.example.com/api"
}
}
}
Server Options
| Property |
Type |
Required |
Description |
type |
"stdio" \| "sse" \| "streamable-http" |
Yes |
Transport type |
command |
string |
stdio only |
Command to run |
args |
string[] |
No |
Command arguments |
env |
object |
No |
Environment variables (stdio). Supports ${env:VAR} |
url |
string |
sse/http |
Server URL |
headers |
object |
No |
HTTP headers. Supports ${env:VAR} |
oauth |
object |
No |
OAuth 2.1 configuration for HTTP transports |
enabled |
boolean |
No |
Enable/disable (default: true) |
Global Settings
| Setting |
Default |
Description |
mcpBridge.toolCallTimeout |
30000 |
Timeout in ms for MCP tool calls (0 = no timeout) |
mcpBridge.confirmCalls |
"when-writing" |
When to confirm tool calls: always, when-writing, or never |
mcpBridge.schemaCacheTtlMinutes |
60 |
TTL for cached tool schemas in minutes |
mcpBridge.auditLog.enabled |
true |
Enable/disable the JSONL audit log |
mcpBridge.auditLog.redactArguments |
false |
Redact tool call arguments in the audit log |
mcpBridge.auditLog.maxEntries |
10000 |
Maximum entries retained in the audit log |
mcpBridge.healthDashboard.enabled |
true |
Enable per-server health badges in the sidebar |
mcpBridge.healthDashboard.errorThreshold |
5 |
Error count that triggers a warning badge |
mcpBridge.resilience.retryEnabled |
true |
Enable automatic retry on transient failures |
mcpBridge.resilience.retryAttempts |
3 |
Number of retry attempts |
mcpBridge.resilience.retryInitialDelayMs |
200 |
Initial retry delay in ms (exponential backoff) |
mcpBridge.resilience.retryMaxDelayMs |
5000 |
Maximum retry delay in ms |
mcpBridge.resilience.circuitBreakerEnabled |
true |
Enable the circuit breaker |
mcpBridge.resilience.circuitBreakerThreshold |
5 |
Consecutive failures before opening the circuit |
mcpBridge.resilience.circuitBreakerHalfOpenAfterMs |
30000 |
Ms before circuit attempts half-open probe |
mcpBridge.responseLimit.maxChars |
100000 |
Maximum characters returned per tool call |
mcpBridge.responseLimit.warnOnTruncation |
true |
Append a truncation notice when response is cut |
mcpBridge.responseLimit.strategy |
"truncate" |
Response limit strategy: truncate or paginate |
mcpBridge.registry.customTemplatesPath |
"" |
Path to a custom templates JSON file |
mcpBridge.sync.scope |
"workspace" |
Config export/import scope: workspace or global |
mcpBridge.activeProfile |
"default" |
Name of the active server profile |
mcpBridge.profiles |
{} |
Named server profiles (maps profile name → server names) |
🌐 Supported Transports
| Transport |
Use Case |
Auth |
| stdio |
Local CLI tools (npx, python, etc.) |
Env vars |
| SSE |
Server-Sent Events endpoints |
Headers, OAuth 2.1 |
| streamable-http |
Modern HTTP-based MCP servers |
Headers, OAuth 2.1 |
MCP Bridge registers 16 tools accessible via Copilot Chat. Two proxy tools bridge any MCP tool call, and fourteen management tools handle server lifecycle and observability.
Why proxy tools? VS Code requires every tool name to be statically declared in the extension manifest (package.json). Since MCP tool names are discovered dynamically at runtime (e.g., mcp-atlassian_confluence_get_page), they cannot be pre-declared. The proxy pattern lets any MCP tool be invoked without manifest changes.
| Tool |
Reference |
Description |
mcp-bridge_list_tools |
#mcpTools |
List tools from all connected MCP servers (optionally filter by server) |
mcp-bridge_call_tool |
#mcpTool |
Call any MCP tool — specify server, tool, and arguments |
Example usage in Copilot Chat:
List all available MCP tools #mcpTools
Call the Jira search tool with query "my issues" #mcpTool
| Tool |
Reference |
Description |
mcp-bridge_list_servers |
#mcpList |
List all servers with status and counts |
mcp-bridge_add_server |
#mcpAdd |
Add a new MCP server |
mcp-bridge_remove_server |
#mcpRemove |
Remove a server |
mcp-bridge_toggle_server |
#mcpToggle |
Enable/disable a server |
mcp-bridge_reconnect_server |
#mcpReconnect |
Reconnect a server |
mcp-bridge_get_server_logs |
#mcpLogs |
Get recent server logs |
mcp-bridge_diagnose_server |
#mcpDiagnose |
Run comprehensive server diagnosis |
mcp-bridge_search_registry |
#mcpSearch |
Search the public MCP registry |
mcp-bridge_install_from_registry |
#mcpInstall |
Install a server from the registry |
mcp-bridge_update_from_registry |
#mcpUpdate |
Update an installed server |
mcp-bridge_get_audit_log |
#mcpAudit |
Query the tool call audit log |
mcp-bridge_export_config |
#mcpExport |
Export server config (secrets redacted) |
mcp-bridge_import_config |
#mcpImport |
Import server config (merge or replace) |
mcp-bridge_switch_profile |
#mcpProfile |
Switch the active server profile |
💬 Commands
| Command |
Description |
MCP Bridge: Add Server |
Add a new MCP server via UI wizard |
MCP Bridge: Remove Server |
Remove a server configuration |
MCP Bridge: Reconnect Server |
Reconnect a specific server |
MCP Bridge: Enable/Disable Server |
Toggle a server on/off |
MCP Bridge: Reconnect All Servers |
Reconnect all servers at once |
MCP Bridge: Refresh Server List |
Refresh the sidebar view |
MCP Bridge: Scan for MCP Servers |
Discover servers from external configs |
MCP Bridge: Import Discovered Server |
Import a discovered server |
MCP Bridge: Import All Discovered Servers |
Import all discovered servers |
MCP Bridge: Browse Registry |
Open the server template browser |
MCP Bridge: Export Config |
Export server config to JSON (secrets redacted) |
MCP Bridge: Import Config |
Import server config from JSON file |
MCP Bridge: Switch Profile |
Switch the active server profile via QuickPick |
MCP Bridge: Open Settings Panel |
Open the unified webview settings UI |
⚠️ Migrating from 0.3.x → 0.4.0
v0.4.0 replaces per-server dynamic tool registration with two static proxy tools. This resolves 219 "Tool was not contributed" Extension Host errors from v0.3.0.
Before (0.3.x): each discovered MCP tool was registered as an individual VS Code language model tool (e.g., #mcp-bridge_confluence_get_page). VS Code requires every tool name to be declared in the extension manifest before activation — dynamically discovered names were rejected at runtime.
After (0.4.0): two static proxy tools bridge all MCP calls:
| What you need |
How to do it in 0.4.0 |
| List available tools |
#mcpTools → mcp-bridge_list_tools |
| Call a specific tool |
#mcpTool → mcp-bridge_call_tool with {server, tool, arguments} |
Example prompt:
What Confluence pages can I access? Use #mcpTools to check available tools, then #mcpTool to call the right one.
No configuration changes are required — server definitions in mcpBridge.servers are unchanged.
🏗️ Architecture Overview
┌─────────────────────────────────────────────────────┐
│ VS Code │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ Copilot │◄──►│ MCP Bridge │◄──►│ Sidebar │ │
│ │ Chat │ │ Extension │ │ TreeView │ │
│ └──────────┘ └──────┬───────┘ └──────────┘ │
│ │ │
│ vscode.lm.registerTool() │
└─────────────────────────┬───────────────────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│ stdio │ │ SSE │ │ HTTP │
│ server │ │ server │ │ server │
└────────┘ └────────┘ └────────┘
src/
├── extension.ts # Activation — wires all modules
├── types.ts # Shared TypeScript interfaces
├── mcp/
│ ├── transport.ts # Transport factory (Stdio/SSE/StreamableHTTP)
│ ├── client.ts # MCP Client wrapper
│ ├── manager.ts # Multi-connection manager with reconnection
│ ├── schema-cache.ts # TTL-based tool schema cache (F1)
│ ├── health-tracker.ts # Per-server latency + error tracking (F3)
│ └── resilience.ts # Retry + circuit breaker via cockatiel (F5)
├── audit/
│ └── audit-log.ts # JSONL append-only audit log (F2)
├── tools/
│ ├── provider.ts # Tool registration bridge (vscode.lm.registerTool)
│ ├── confirmation-formatter.ts # Rich tool call confirmation (F4)
│ └── response-limiter.ts # Auto-chunking for large responses (F6)
├── registry/
│ ├── panel.ts # Registry browser WebviewPanel (F7)
│ └── template-loader.ts # Curated server template catalogue (F7)
├── settings/
│ ├── panel.ts # Unified Settings WebviewPanel (F10)
│ └── panel-helpers.ts # Pure helpers for settings panel (F10)
├── sidebar/
│ ├── tree-provider.ts # TreeDataProvider with health badges (F3)
│ └── commands.ts # Sidebar + profile + sync commands (F8/F9)
└── config/
└── settings.ts # Configuration management + profiles (F9)
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature)
- Commit your changes (
git commit -m 'feat: add amazing feature')
- Push to the branch (
git push origin feature/amazing-feature)
- Open a Pull Request
Development
npm install
npm run build # Production build with esbuild
npm run watch # Watch mode for development
npm run compile # Type check
npm run test # Run tests
📄 License
This project is licensed under the MIT License — see the LICENSE file for details.