[Claude Code CLI] Bridging Terminal and VS Code

4 min read Original article ↗

Disclaimer: Claude Code’s CLI and VS Code extension are not publicly available (sorry for the clickbait 😜). But we used various open-source projects to derive the end-to-end flow.

Claude Code CLI runs in your terminal in a separate process from VS Code. Yet the CLI understands the errors VS Code is showing and uses them to answer your prompt. How does an external CLI process access VS Code’s internal diagnostic API? Below screenshot shows Claude Code CLI connecting to an open VS Code window.

  1. User asks: “fix type errors” in the terminal

  2. CLI → Claude API: Sends user message with tools manifest (including getDiagnostics)

  3. Claude API → CLI: Returns tool_use response: {name: “getDiagnostics”}

  4. CLI → Extension: Sends MCP tools/call request

  5. Extension: Calls vscode.languages.getDiagnostics() internally

  6. Extension → CLI: Returns diagnostics array with all errors/warnings

  7. CLI → Claude API: Sends tool_result with diagnostics

  8. Claude API: Sees all errors and suggests fixes

Claude Code CLI finds running IDEs via lock files. We can examine claudecode.nvim, a Neovim extension built by reverse-engineering Claude Code.

The extension writes a lock file upon starting its WebSocket server.

coder/claudecode.nvim:init.lua#L429-L444

coder/claudecode.nvim:lockfile.lua#L69-L151

The lock file contains an authentication token (UUID v4) that the CLI must send to prevent unauthorized access. Early versions lacked this, leading to CVE-2025-52882.

Based on observable behavior, we can infer the CLI’s discovery flow:

  1. Scans all .lock files from ~/.claude/ide/

  2. Parses JSON to extract port, workspace folders, and auth token

  3. Filters by matching workspace (current directory vs. workspaceFolders)

  4. Connects via WebSocket to ws://localhost:{port} with the auth token

The Model Context Protocol (MCP) follows a client-server architecture:

  • Claude Code CLI: MCP client that discovers and invokes tools

  • Claude Code Extension: MCP server that exposes tools and handles requests.

Both client and server must conform to the MCP Specification: Tools - standard JSON-RPC 2.0 format with jsonrpc, method/result, and id fields.

We can examine claudecode.nvim to see how an MCP server handles requests.

coder/claudecode.nvim:init.lua#L267-L334

Diagnostics from VS Code

VS Code stores language server diagnostics (e.g., from rust-analyzer in ExtHostDiagnostics._collections. The vscode.languages.getDiagnostics() API aggregates diagnostics from all sources:

microsoft/vscode:extHostDiagnostics.ts#L318-L337

For example, VS Code’s Git extension uses getDiagnostics to validate commits:

microsoft/vscode:commands.ts#L713-L743

How MCP Server uses getDiagnostics API

While the Claude Code extension is private, it likely invokes vscode.languages.getDiagnostics().

Here is how claudecode.nvim uses Neovim’s getDiagnostics API:

coder/claudecode.nvim:get_diagnostics.lua#L3-L20

coder/claudecode.nvim:get_diagnostics.lua#L26-L95

We can check n8n, a workflow automation framework, for an MCP client implementation.

Tool listing:

n8n-io/n8n:utils.ts#L18-L26

modelcontextprotocol/typescript-sdk:index.ts#L599-L606

Tool invocation:

n8n-io/n8n:McpClient.node.ts#L255-L264

modelcontextprotocol/typescript-sdk:index.ts#L531-L574

modelcontextprotocol/typescript-sdk:protocol.ts#L489-L585

API Integration of Tools

How does the MCP client know when to invoke tools?

MCP tools are “model-controlled”. the LLM discovers and invokes them based on context. The diagram below illustrates the interaction:

Below is a sample request with a `tools` field, based on Claude API docs.

Claude decides to call getDiagnostics and returns a response with a tool_use stop reason.

This establishes an agentic loop. Since the Claude API cannot directly access your machine, it instructs the local CLI to execute the tool (fetching diagnostics) and return the result.

LangChain handles tool execution and message creation as below.

langchain-core:tools/base.py#L888-L933

langchain-core:tools/base.py#L1181-L1210

The sample request sent to Claude API looks like

One downside of MCP is high token usage from context preloading. Tool definitions are loaded at session start whether used or not. Some users report 66K+ tokens consumed before any conversation begins.

Claude’s Agent Skills address this using progressive disclosure, a lazy-loading mechanism that loads only metadata initially. We will cover Skills in a future post.

  • PR #34: feat: diagnostics tool implementation by @krmcbride (Kevin McBride)

  • PR #56: feat: implement WebSocket authentication system with UUID tokens by @ThomasK33 (Thomas Kosiewski), primary author of the repository

  • Issue #30075: Get all problems (errors, warnings, etc.) using VSCode extensions API assigned to @jrieken (Johannes Rieken)

I’m sure I’ve missed many contributors given how much ground this post covers. If you know someone who should be recognized, please tag them in the comments!

Discussion about this post

Ready for more?