# What Are MCP Servers and How to Use Them with the Copilot SDK

> Discover MCP servers and their role in exposing tools to Copilot sessions. Learn how to use them with the Copilot SDK via stdio, HTTP, or SSE server types for seamless integration.

- Repository: [GitHub/copilot-sdk](https://github.com/github/copilot-sdk)
- Tags: how-to-guide
- Published: 2026-07-18

---

**MCP servers are external processes that expose tools to Copilot sessions through the Model Context Protocol (MCP), and the Copilot SDK supports stdio, HTTP, and SSE server types that can be configured via `SessionConfig` and automatically managed during the session lifecycle.**

The Copilot SDK enables AI-powered workflows by integrating external tools through the Model Context Protocol (MCP). As implemented in the github/copilot-sdk repository, MCP servers act as bridges that make local scripts and remote APIs available as callable functions during Copilot sessions. Developers configure these servers through the SDK's Rust-based configuration types, allowing the runtime to spawn processes, manage authentication, and route tool calls automatically.

## Understanding MCP Server Types in the Copilot SDK

The SDK recognizes three distinct transport mechanisms for MCP servers, each defined in [`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs).

### Stdio (Local) Servers

**Stdio servers** run as child processes on the local machine, communicating with the Copilot runtime through standard input/output streams. According to the source code in [`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs) (lines 21-58), these servers are defined with `{"type":"stdio"}` (the alias `"local"` is also accepted). This type is ideal for local tools like Node.js scripts or Python executables that need direct process management.

### HTTP (Remote) Servers

**HTTP servers** expose tools via standard HTTP endpoints that receive JSON-RPC requests. As defined in [`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs) (lines 99-106), these use the wire representation `{"type":"http", ...}`. The SDK contacts these remote servers directly via their URLs, making them suitable for cloud-based tools or microservices.

### SSE (Remote) Servers

**SSE servers** utilize Server-Sent Events for streaming transport, sharing the same configuration structure as HTTP servers in [`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs) (lines 99-106). These use `{"type":"sse", ...}` and provide real-time communication capabilities for scenarios requiring persistent connections.

## Configuring MCP Servers in SessionConfig

The integration centers on the `SessionConfig` struct, which maintains an `mcp_servers` map of type `IndexMap<String, McpServerConfig>` (lines 632-692 in [`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs)). This configuration determines which tools are exposed to the AI and how the runtime interacts with each server.

Each server configuration includes a `tools` field that controls visibility:

- `None` exposes all available tools from the server
- `Some(vec![])` exposes no tools (effectively disabling the server)
- `Some(vec!["tool_name"])` exposes only the explicitly listed tools

The SDK handles server lifecycle automatically: it spawns local stdio servers when sessions start, verifies remote HTTP/SSE endpoints are reachable, and tracks server status through `MCPServerStatus`. For protected endpoints, the SDK supports custom `McpAuthHandler` implementations to supply OAuth tokens (lines 1901-1905 in [`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs)).

## Implementing MCP Servers with the Copilot SDK

Below are practical implementations using the SDK's Rust API.

### Adding a Local Stdio Server

To register a local MCP server that runs as a subprocess, use `McpStdioServerConfig`:

```rust
use github_copilot_sdk::{McpServerConfig, McpStdioServerConfig};
use github_copilot_sdk::IndexMap;

// Define a server that runs `npx @playwright/mcp` and exposes all tools.
let stdio = McpServerConfig::Stdio(McpStdioServerConfig {
    command: "npx".into(),
    args: vec!["-y".into(), "@playwright/mcp".into()],
    tools: Some(vec!["*".into()]), // expose every tool the server provides
    ..Default::default()
});

// Register it under the name "playwright".
let mut mcp_servers = IndexMap::new();
mcp_servers.insert("playwright".to_string(), stdio);

```

This pattern appears in the SDK's test suite ([`rust/tests/session_test.rs`](https://github.com/github/copilot-sdk/blob/main/rust/tests/session_test.rs), lines 10-18) and demonstrates how to pass command arguments, environment variables, and working directories to the spawned process.

### Adding a Remote HTTP Server

For remote tools accessible via HTTP endpoints, configure an `McpHttpServerConfig`:

```rust
use github_copilot_sdk::{McpServerConfig, McpHttpServerConfig};

let http = McpServerConfig::Http(McpHttpServerConfig {
    url: "https://example.com/mcp".into(),
    tools: Some(vec!["forecast".into()]), // only expose the "forecast" tool
    ..Default::default()
});

let mut mcp_servers = IndexMap::new();
mcp_servers.insert("weather".to_string(), http);

```

As shown in [`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs) (lines 99-106), this configuration serializes to `{"type":"http", ...}` for wire transmission.

### Building the Session Configuration

Combine server definitions into a complete `SessionConfig` using the `with_mcp_servers` method (lines 692-700 in [`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs)):

```rust
use github_copilot_sdk::{SessionConfig, IndexMap};

let cfg = SessionConfig::new()
    .with_mcp_servers(mcp_servers); // inject the map defined above

```

### Starting the Session

When initializing a session, the SDK automatically manages server startup:

```rust
let session = Session::new(cfg).await?;

```

Upon creation, the SDK launches any stdio servers as child processes with the supplied `env`, `cwd`, and `args`. For remote servers, it verifies reachability and validates OAuth tokens if `McpAuthHandler` is configured.

### Invoking Tools from Prompts

Once configured, tools are invoked through JSON-RPC routed to the appropriate server. A tool call in the conversation payload looks like this:

```json
{
  "role": "assistant",
  "content": "Use the playwright tool to navigate to https://example.com",
  "tool_calls": [
    {
      "id": "tool-1",
      "type": "function",
      "function": {
        "name": "playwright/navigate",
        "arguments": "{\"url\":\"https://example.com\"}"
      }
    }
  ]
}

```

The runtime routes `playwright/navigate` to the "playwright" MCP server defined earlier, executes the JSON-RPC call, and injects the response back into the conversation context.

## Key Source Files and Implementation Details

Understanding the following files is essential for advanced MCP server implementations:

- **[`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs)**: Contains core definitions including `McpServerConfig`, `McpStdioServerConfig`, `McpHttpServerConfig`, and the `mcp_servers` field on `SessionConfig` (lines 632-692, 1901-1905).
- **[`rust/src/wire.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/wire.rs)**: Handles serialization of MCP configurations for runtime transmission (lines 88-96).
- **[`rust/tests/session_test.rs`](https://github.com/github/copilot-sdk/blob/main/rust/tests/session_test.rs)**: Validates serialization round-trips and configuration parsing (lines 10-18, 31-38).
- **[`rust/tests/e2e/rpc_mcp_lifecycle.rs`](https://github.com/github/copilot-sdk/blob/main/rust/tests/e2e/rpc_mcp_lifecycle.rs)**: End-to-end tests covering server start, stop, and restart operations.
- **`test/harness/test-mcp-server.mjs`**: Reference JavaScript implementation used by the test harness.

## Summary

- **MCP servers** extend Copilot sessions by exposing external tools through the Model Context Protocol, with support for stdio, HTTP, and SSE transports.
- **Configuration** occurs through `SessionConfig::with_mcp_servers`, accepting an `IndexMap` of `McpServerConfig` variants defined in [`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs).
- **Local servers** run as child processes with stdio communication, while **remote servers** connect via HTTP or SSE endpoints.
- **Tool filtering** is controlled per-server through the `tools` field, allowing selective exposure of specific functions or complete server contents.
- **Lifecycle management** is automatic: the SDK spawns local processes, maintains connections to remote endpoints, and handles authentication via `McpAuthHandler`.

## Frequently Asked Questions

### What is the Model Context Protocol (MCP)?

The Model Context Protocol (MCP) is a JSON-RPC based interface that standardizes how external tools expose functionality to AI systems. In the Copilot SDK, MCP servers act as adapters that translate between the Copilot runtime and external capabilities, whether local scripts or remote APIs.

### How does the Copilot SDK handle MCP server authentication?

The SDK supports OAuth-protected MCP servers through the `McpAuthHandler` trait, defined in [`rust/src/types.rs`](https://github.com/github/copilot-sdk/blob/main/rust/src/types.rs) (lines 1901-1905). Developers install custom handlers that supply tokens when the runtime connects to protected HTTP or SSE endpoints, ensuring secure access without hardcoding credentials in configuration files.

### Can I restrict which tools an MCP server exposes to Copilot?

Yes. Each `McpServerConfig` includes a `tools` field that controls visibility: setting it to `None` exposes all tools, `Some(vec![])` exposes none, and `Some(vec!["tool_name"])` exposes only specific named tools. This allows fine-grained control over which capabilities the AI can access from each server.

### What is the difference between stdio and HTTP MCP servers in the Copilot SDK?

**Stdio servers** are local child processes that communicate through standard input/output streams, managed entirely by the SDK's lifecycle system. **HTTP servers** are remote endpoints that the SDK contacts via HTTP requests; they run independently and are not spawned by the SDK. Stdio is ideal for local CLI tools, while HTTP suits cloud-based microservices or third-party APIs.