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:

TopicPrimary reference
Architecture, lifecycle, and key changesArchitecture overview, Lifecycle, Changelog
Transports and cancellationTransports, Cancellation, Progress
Server-side conceptsServer overview, Tools, Resources, Prompts, Logging, Pagination
Client responsibilitiesClient overview, Sampling, Elicitation
Security and governanceSecurity best practices, Authorization, Understanding authorization, Governance
Tooling and debuggingMCP 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:

KeyDefaultPurpose
enabledfalseTurns all MCP wiring on or off at once.
max_concurrent_connections5Global connection pool shared across providers.
request_timeout_seconds30Envelope timeout for lifecycle requests (mirrors MCP Lifecycle).
retry_attempts3Retry budget for transport failures before surfacing an error.
startup_timeout_secondsnullOptional provider start handshake timeout; inherits request_timeout_seconds when unset.
tool_timeout_secondsnullOptional per-tool guard for long-running operations.
experimental_use_rmcp_clienttrueEnables the Rust MCP client so HTTP/streamable transports are available.
requirementsenforce = falseOptional transport-identity allowlist for admitting providers during initialization.
uimode = "compact", max_events = 50, show_provider_names = trueControls 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, or logging patterns, 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 (configuration maps) 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):

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:

  • context7 can access only journals/* 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, and retry_attempts appear 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.