Skip to content

MCP (Model Context Protocol)

Model Context Protocol - Extended AI Capabilities

The Model Context Protocol (MCP) is an open standard that enables AI assistants like GitHub Copilot to connect with external data sources and tools.

What is MCP?

MCP provides a standardized way for AI models to:

  • Access external data sources
  • Interact with tools and services
  • Maintain context across sessions
  • Extend capabilities dynamically

Think of MCP as a "plugin system" for AI assistants.

How MCP Works

graph LR
    A[GitHub Copilot] <-->|MCP Protocol| B[MCP Server]
    B <--> C[Database]
    B <--> D[API Services]
    B <--> E[File Systems]
    B <--> F[Custom Tools]

Key Components

Component Description
Host The AI application (Copilot)
Server Provides resources and tools
Client Connects host to servers
Resources Data the AI can access
Tools Actions the AI can perform

MCP Servers

Available Servers

Common MCP servers include:

  • Database Servers: PostgreSQL, MySQL, MongoDB
  • File System: Local and remote file access
  • API Gateways: REST and GraphQL APIs
  • Development Tools: Git, Docker, Kubernetes
  • Cloud Services: AWS, Azure, GCP

Example: Database Server

{
  "mcpServers": {
    "postgres": {
      "command": "mcp-server-postgres",
      "args": [
        "postgresql://user:pass@localhost/mydb"
      ]
    }
  }
}

With this configured, you can ask Copilot:

"Show me all users who signed up last week"

Copilot can query the database directly!

Setting Up MCP

Configuration

Create a configuration file:

File: .vscode/mcp.json

{
  "servers": {
    "filesystem": {
      "command": "mcp-server-filesystem",
      "args": ["/path/to/project"]
    },
    "github": {
      "command": "mcp-server-github",
      "env": {
        "GITHUB_TOKEN": "${env:GITHUB_TOKEN}"
      }
    }
  }
}

File: ~/.config/mcp/config.json

{
  "servers": {
    "notes": {
      "command": "mcp-server-notes",
      "args": ["~/notes"]
    }
  }
}

Installing Servers

# Install from npm
npm install -g @modelcontextprotocol/server-filesystem
npm install -g @modelcontextprotocol/server-postgres

# Or use Docker
docker run -d modelcontextprotocol/server-github

Using MCP with Copilot

Accessing Resources

Once configured, ask Copilot about your resources:

"What tables are in my database?"

"Show me recent changes in the git log"

"What files are in the src directory?"

Using Tools

MCP tools enable actions:

"Create a new database migration for adding an email column"

"Run the test suite and show failed tests"

"Deploy the latest version to staging"

Creating Custom MCP Servers

Server Structure

from mcp import Server, Resource, Tool

server = Server("my-custom-server")

@server.resource("users")
async def get_users():
    """Get all users from the system"""
    return await fetch_users_from_api()

@server.tool("create_user")
async def create_user(name: str, email: str):
    """Create a new user"""
    return await api.create_user(name, email)

if __name__ == "__main__":
    server.run()

Exposing Resources

@server.resource("projects/{project_id}")
async def get_project(project_id: str):
    """Get project details by ID"""
    return {
        "id": project_id,
        "name": await db.get_project_name(project_id),
        "status": await db.get_project_status(project_id)
    }

Implementing Tools

@server.tool("deploy")
async def deploy_application(
    environment: str,
    version: str
) -> dict:
    """Deploy application to specified environment"""
    result = await deployment_service.deploy(
        env=environment,
        version=version
    )
    return {"status": "success", "url": result.url}

MCP Best Practices

Security

Security First

  • Never expose sensitive credentials
  • Use environment variables for secrets
  • Implement proper authentication
  • Limit server permissions

Resource Design

# Good: Specific and scoped
@server.resource("users/{id}/orders")
async def get_user_orders(id: str):
    pass

# Avoid: Too broad
@server.resource("everything")
async def get_all_data():
    pass

Error Handling

@server.tool("risky_operation")
async def risky_operation():
    try:
        result = await perform_operation()
        return {"success": True, "data": result}
    except OperationError as e:
        return {"success": False, "error": str(e)}

Common Use Cases

🗄️
Database Access

Query and modify databases naturally

📁
File Management

Read, write, and organize files

🔧
DevOps Tools

Deploy, monitor, and manage infrastructure

🔌
API Integration

Connect to external services

Troubleshooting

Issue Solution
Server won't start Check command path and permissions
Connection timeout Verify network settings
Auth failures Check credentials and tokens
Missing resources Ensure server is properly configured

Debugging

Enable verbose logging:

{
  "servers": {
    "myserver": {
      "command": "mcp-server",
      "env": {
        "MCP_LOG_LEVEL": "debug"
      }
    }
  }
}