MCP Integration Guide
July 17, 2026 · View on GitHub
This guide outlines how VT Code connects to external MCP (Model Context Protocol) servers, how
allowlists control tool access, and how to troubleshoot common configuration issues. The
configuration surface documented below maps directly to the serde structures in
crates/codegen/vtcode-config/src/mcp.rs, so the examples here stay aligned with the loader that powers the
CLI and the reusable vtcode-config crate. For the canonical protocol behaviour and the latest
server/client expectations, consult the upstream MCP reference index at
https://modelcontextprotocol.io/llms.txt. That index links to the full architecture, transport,
authorisation, logging, and resource specification documents maintained by the MCP community.
Developer Note: If you're implementing MCP module features or integrating with the core MCP APIs, see the MCP Integration Guide for API reference, code patterns, and implementation status.
MCP Specification Map
The llms.txt index enumerates every normative reference you may need while configuring VT Code.
When you need deeper protocol detail, jump straight from this guide to the most relevant
specification chapter:
| Topic | Primary reference |
|---|---|
| Architecture, lifecycle, and key changes | Architecture overview, Lifecycle, Changelog |
| Transports and cancellation | Transports, Cancellation, Progress |
| Server-side concepts | Server overview, Tools, Resources, Prompts, Logging, Pagination |
| Client responsibilities | Client overview, Sampling, Elicitation |
| Security and governance | Security best practices, Authorization, Understanding authorization, Governance |
| Tooling and debugging | MCP Inspector, Example clients, Example servers |
Keep the specification open while editing vtcode.toml; VT Code intentionally mirrors the naming
and behavioural guarantees defined there.
Configuring MCP Providers
Core [mcp] table
Open vtcode.toml and ensure the global MCP section is enabled. The top-level table mirrors the
McpClientConfig defaults, letting you tune concurrency, timeout, and transport behaviour in one
place. All values fall back to the defaults compiled into vtcode-config, summarised in the
following table:
| Key | Default | Purpose |
|---|---|---|
enabled | false | Turns all MCP wiring on or off at once. |
max_concurrent_connections | 5 | Global connection pool shared across providers. |
request_timeout_seconds | 30 | Envelope timeout for lifecycle requests (mirrors MCP Lifecycle). |
retry_attempts | 3 | Retry budget for transport failures before surfacing an error. |
startup_timeout_seconds | null | Optional provider start handshake timeout; inherits request_timeout_seconds when unset. |
tool_timeout_seconds | null | Optional per-tool guard for long-running operations. |
experimental_use_rmcp_client | true | Enables the Rust MCP client so HTTP/streamable transports are available. |
requirements | enforce = false | Optional transport-identity allowlist for admitting providers during initialization. |
ui | mode = "compact", max_events = 50, show_provider_names = true | Controls event rendering inside the TUI. |
Configure overrides as needed:
[mcp]
enabled = true
max_concurrent_connections = 3
request_timeout_seconds = 45
retry_attempts = 2
startup_timeout_seconds = 90 # optional: provider startup handshake window
tool_timeout_seconds = 45 # optional: per-tool execution deadline
experimental_use_rmcp_client = true
[mcp.requirements]
enforce = false
allowed_stdio_commands = ["uvx", "npx"]
allowed_http_endpoints = ["https://mcp.example.com/api"]
startup_timeout_seconds defaults to None, which falls back to the global request_timeout_seconds
value. Setting it to 0 disables the startup timeout entirely—handy for first-run npm downloads.
tool_timeout_seconds behaves the same way for individual tool calls.
When mcp.requirements.enforce = true, providers whose stdio command or HTTP endpoint is not
allowlisted are skipped during MCP initialization.
UI configuration
Configure the MCP UI panel if desired. Renderer profiles let you pick tailored output formats for
specific providers or tool prefixes. Renderer identifiers correspond to the enums defined in
McpRendererProfile, so the strings in your TOML match the canonical variants used in code:
[mcp.ui]
mode = "compact"
max_events = 25
show_provider_names = false
[mcp.ui.renderers]
"context7" = "context7"
"sequential-thinker" = "sequential-thinking"
Provider transports
Define one or more providers. Stdio transports embed the command, arguments, and optional working directory directly in the provider table. VT Code forwards every value here into the MCP lifecycle as described in the stdio transport spec:
[[mcp.providers]]
name = "time"
enabled = true
command = "uvx"
args = ["mcp-server-time"]
working_directory = "./servers/time"
max_concurrent_requests = 2
startup_timeout_ms = 15_000
[mcp.providers.env]
PYTHONUNBUFFERED = "1"
For HTTP transports, specify the endpoint and headers in place of the stdio fields. The configuration loader automatically deserializes either transport variant and populates provider metadata used by the MCP client registry:
[[mcp.providers]]
name = "figma"
enabled = true
max_concurrent_requests = 4
endpoint = "https://mcp.figma.com/mcp"
api_key_env = "FIGMA_MCP_TOKEN"
protocol_version = "2025-06-18"
headers = { "X-Client" = "vtcode", "X-MCP-App" = "vtcode" }
Environment variables defined under [mcp.providers.env] are forwarded to stdio transports and
composed with the curated whitelist the loader already exposes. Use working_directory to stage
local binaries, credentials, or fixtures that the provider expects on disk. For HTTP transports,
protocol_version determines which MCP schema the client negotiates (the default matches
vtcode-config's 2024-11-05, but you can adopt the 2025-06-18 release or later when providers
publish compatible endpoints). Custom headers values help satisfy hosted provider requirements
for client identification—check the server's docs for required Authorization formats per the MCP
authorization guidance.
The max_concurrent_requests guard prevents a single provider from starving the global pool
configured in [mcp].
Note: Streamable HTTP support is still evolving. The client negotiates the declared
protocol_version, but servers must expose Server-Sent Events per the transport spec. If an HTTP provider lacks streaming, fall back to a stdio wrapper until the server adopts the reference implementation.
Security and validation
VT Code exposes additional security gates through the [mcp.security] table. Enable authentication
and tighten rate limits or validation rules when running sensitive providers. These settings mirror
the guidance in the MCP security best practices
chapter:
[mcp.security]
auth_enabled = true
api_key_env = "VT_MCP_API_KEY"
[mcp.security.rate_limit]
requests_per_minute = 120
concurrent_requests = 6
[mcp.security.validation]
schema_validation_enabled = true
path_traversal_protection = true
max_argument_size = 262144
The same structure powers the optional embedded MCP server (vtcode as a provider). Combine the
security block with the [mcp.server] table to expose curated tools over SSE or HTTP. Ensure your
tool list lines up with the server tools contract:
[mcp.server]
enabled = true
bind_address = "127.0.0.1"
port = 3030
transport = "sse"
exposed_tools = ["read_file"]
vtcode-config re-exports serde schemas for these tables, making it straightforward to validate
configuration files in automation or IDE tooling.
Allowlist Behaviour
MCP access is gated by pattern-based allowlists. The defaults apply to every provider unless the provider supplies its own patterns. Provider-specific rules now fully override the defaults:
- When a provider defines
tools,resources,prompts, orloggingpatterns, only matches in that provider block are accepted. Default rules are ignored for that provider. - If a provider omits a rule set, VT Code falls back to the default patterns.
- Configuration permissions (
configurationmaps) continue to support provider overrides via an explicit match or by delegating to the default rules.
Each allowlist key maps directly to the Model Context Protocol concepts described in the official
specification (all cited in llms.txt):
toolscorrespond to tool definitions, letting you scope remote execution entry points.resourcesalign with resource handles exposed by a server.promptsconstrain server-authored prompt templates.loggingmirrors logging channels surfaced by compliant servers.
This behaviour avoids situations where a restrictive provider configuration is silently bypassed by broader default patterns.
Example
[mcp.allowlist]
enforce = true
[mcp.allowlist.default]
resources = ["docs/*"]
[mcp.allowlist.providers.context7]
resources = ["journals/*"]
In this configuration:
context7can access onlyjournals/*resources.- Other providers continue to match
docs/*through the default rule.
Enable enforce = true when you want the rules to be mandatory; leaving it unset keeps legacy
behaviour where allowlist checks are advisory only.
Testing the Integration
Run the MCP-focused test suite to verify configuration parsing, allowlist enforcement, and registry wiring. These tests exercise the serde types documented above and confirm compatibility with the schema reference:
cargo test -p vtcode-core mcp -- --nocapture
The suite includes mocked clients and parsing tests so it does not require live MCP servers. For an
end-to-end check against the Context7 MCP server, invoke the ignored smoke test which spawns the
official @upstash/context7-mcp package on demand. This mirrors the example servers
highlighted in the MCP documentation:
cargo test -p vtcode-core --test mcp_context7_manual context7_list_tools_smoke -- --ignored --nocapture
Expect the test to take a little longer on the first run while npx downloads the server bundle.
Troubleshooting
- Unexpected tool execution permissions – confirm whether the provider defines its own allowlist. Provider rules now override defaults, so missing patterns may block tools that defaults would otherwise allow.
- Provider handshake visibility – VT Code now sends explicit MCP client metadata and normalizes structured tool responses. Context7 results surface as plain JSON objects in the tool panel so downstream renderers can display status, metadata, and message lists without additional post-processing.
- Stale configuration values – ensure
max_concurrent_connections,request_timeout_seconds, andretry_attemptsappear under the[mcp]table after any nested[mcp.ui]section. TOML resets the table context when a new header appears. - HTTP transport issues – VT Code currently performs capability probing for HTTP MCP servers but requires a streaming implementation to be fully functional. Use stdio transports when possible.
With these settings and checks in place, MCP providers and allowlists should behave predictably, unlocking additional context-aware tooling in VT Code.