MCP Deep Dive: Model Context ProtocolΒΆ
MCP is what turns a chatbot into an agent. Without MCP, your coding assistant can only read files in your workspace and run terminal commands. With MCP, it can browse the web, query databases, call APIs, manage cloud resources, and use any custom tool you build.
This guide focuses on MCP as used in VS Code + GitHub Copilot.
1. What MCP Actually IsΒΆ
MCP (Model Context Protocol) is an open standard created by Anthropic that defines how AI applications connect to external data sources and tools. Think of it as USB-C for AI tools: a single protocol that any AI client (VS Code Copilot, Claude Code, Cursor, etc.) can use to connect to any MCP server. We focus on the VS Code integration here.
The Three MCP PrimitivesΒΆ
Primitive |
Direction |
What it does |
Example |
|---|---|---|---|
Tools |
Client β Server |
Actions the AI can take |
|
Resources |
Server β Client |
Data the AI can read |
Database schema, file contents, API documentation |
Prompts |
Server β Client |
Pre-written prompt templates |
βAnalyze this SQL query for performance issuesβ |
In practice, tools are the most commonly used primitive. When the agent decides it needs to query a database, it calls the query tool on the database MCP server.
ArchitectureΒΆ
ββββββββββββββββ JSON-RPC ββββββββββββββββ Native ββββββββββββββββ
β AI Client β βββββ stdio βββββΊ β MCP Server β βββββββββββββΊ β Data Source β
β (VS Code, β or HTTP/SSE β (Python, β protocol β (Postgres, β
β Claude) β β Node.js) β β Web, API) β
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
The client is your AI tool (VS Code Copilot, Claude Code, etc.)
The server is a lightweight process that translates between MCP and the data sourceβs native protocol
Communication uses JSON-RPC 2.0 over either stdio (local) or HTTP with Server-Sent Events (remote)
2. Transport: stdio vs HTTP/SSEΒΆ
stdio (Local Servers)ΒΆ
The client spawns the server as a child process. Communication happens over stdin/stdout.
{
"servers": {
"my-server": {
"command": "python",
"args": ["server.py"],
"env": { "DB_URL": "postgresql://..." }
}
}
}
Pros: Simple, no auth needed, fast Cons: Must run on the same machine as the client
HTTP/SSE (Remote Servers)ΒΆ
The server runs as a web service. The client connects over HTTP.
{
"servers": {
"remote-db": {
"url": "https://mcp.example.com/db",
"headers": {
"Authorization": "Bearer ${input:apiToken}"
}
}
}
}
Pros: Server can run anywhere (cloud, shared team server) Cons: Requires auth, network latency, more setup
3. MCP Server CatalogΒΆ
Official Servers (by Anthropic / ModelContextProtocol org)ΒΆ
Server |
Package |
What it does |
|---|---|---|
Filesystem |
|
Read/write files, search by glob |
PostgreSQL |
|
Query, inspect schema, run SQL |
SQLite |
|
Local database access |
GitHub |
|
Repos, issues, PRs, actions |
Git |
|
Log, diff, blame, branch |
Brave Search |
|
Web search |
Memory |
|
Persistent key-value memory |
Fetch |
|
HTTP requests to any URL |
Puppeteer |
|
Browser automation |
Community & Vendor ServersΒΆ
Server |
What it does |
|---|---|
Playwright MCP |
Browser automation, screenshots, form filling, navigation |
Azure MCP |
Azure resource management, deployment, monitoring |
Supabase MCP |
Supabase database and auth |
Notion MCP |
Read/write Notion pages and databases |
Slack MCP |
Read/send messages, search channels |
Linear MCP |
Issue tracking, project management |
Sentry MCP |
Error tracking, issue analysis |
Docker MCP |
Container management |
Finding More ServersΒΆ
Official registry: github.com/modelcontextprotocol/servers
Community list: mcpservers.org
npm search:
npx @modelcontextprotocol/server-*pip search:
pip install mcp-server-*
4. Configuration in DetailΒΆ
VS Code (.vscode/mcp.json)ΒΆ
{
"servers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "${input:pgConnectionString}"
}
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:githubToken}"
}
}
}
}
The ${input:name} syntax prompts you for the value when the server starts, so you never commit secrets.
Project Root (.mcp.json)ΒΆ
You can also place MCP config at the project root as .mcp.json. This format is also recognized by other MCP-compatible tools:
{
"mcpServers": {
"rag-server": {
"command": "python",
"args": ["scripts/rag_mcp_server.py"]
}
}
}
5. Security ConsiderationsΒΆ
MCP servers can execute arbitrary code. Treat them like any other dependency:
DoΒΆ
Pin server versions in
package.jsonor requirements filesUse
${input:...}for secrets β never hardcode tokensScope filesystem servers to specific directories (not
/)Review server source code before using in production
Use read-only database credentials when possible
DonβtΒΆ
Run MCP servers as root
Give filesystem servers access to
~/.ssh,~/.aws, or credential directoriesUse MCP servers from untrusted sources without reviewing the code
Commit
.envfiles with MCP credentials
Principle of Least PrivilegeΒΆ
{
"servers": {
"filesystem": {
"command": "npx",
"args": [
"-y", "@modelcontextprotocol/server-filesystem",
"/Users/you/project/data"
]
}
}
}
This restricts the filesystem server to only the data/ directory. The agent cannot read your SSH keys or other sensitive files.
6. Debugging MCP ServersΒΆ
VS CodeΒΆ
Open Command Palette β βMCP: List Serversβ β check status
Open Output Panel β select βMCPβ from the dropdown β see logs
If a server is red, click it to see the error message
Common IssuesΒΆ
Symptom |
Cause |
Fix |
|---|---|---|
Server shows βnot startedβ |
Command not found |
Verify |
Server starts but agent doesnβt use it |
Not in Agent mode |
Switch from Chat to Agent mode |
βConnection refusedβ for HTTP server |
Server not running |
Start the server process manually first |
Tools work but are slow |
Large response payloads |
Limit query results, paginate |
|
Wrong path to server script |
Use absolute path or verify relative path |
Testing a Server ManuallyΒΆ
You can test any stdio MCP server directly:
# Start the server and send a JSON-RPC request
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | \
npx @modelcontextprotocol/server-filesystem /tmp
This prints the list of tools the server exposes.
7. Building Your Own MCP ServerΒΆ
See 05_build_mcp_server.ipynb for a hands-on walkthrough. The key steps:
Install the MCP SDK:
pip install mcp
Define your tools as Python functions with type annotations
Register them with the MCP server framework
Configure the server in
.vscode/mcp.jsonor.mcp.jsonTest by starting the server and calling tools from agent mode
When to Build a Custom ServerΒΆ
Build your own when:
You need to expose an internal API or database that no existing server covers
You want to give the agent access to your ML experiment tracker (W&B, MLflow)
You need custom business logic (e.g., βlookup customer by account IDβ)
You want to wrap a command-line tool as an MCP server
Donβt build your own when:
An existing server already does what you need (check the catalog first)
A simple terminal command would suffice (agent mode can already run commands)
8. MCP vs. Function Calling vs. Tool UseΒΆ
Concept |
What it is |
Scope |
|---|---|---|
Function calling |
LLM API feature: model outputs structured JSON to call a function |
Single API call |
Tool use |
Agent pattern: model decides which tool to call in a loop |
Single agent |
MCP |
Protocol standard: any client can connect to any server |
Cross-tool, cross-vendor |
MCP builds on function calling and tool use but adds:
Discoverability β servers advertise their tools, resources, and prompts
Standardization β same protocol works in VS Code and any MCP-compatible client
Composability β connect multiple servers simultaneously
Next: 03_copilot_instructions_guide.md β custom instructions for Copilot