Skip to content

Refactor MCP server config types across all SDK languages#1051

Open
stephentoub wants to merge 5 commits intomainfrom
stephentoub/refactor-mcp-server-config-types
Open

Refactor MCP server config types across all SDK languages#1051
stephentoub wants to merge 5 commits intomainfrom
stephentoub/refactor-mcp-server-config-types

Conversation

@stephentoub
Copy link
Copy Markdown
Collaborator

Motivation

The C# SDK typed McpServers dictionaries as Dictionary<string, object>, losing all compile-time safety and forcing consumers to know which concrete config type to use without IDE guidance. The type names (McpLocalServerConfig / McpRemoteServerConfig) also didn't align with MCP protocol terminology. Fixes #245.

Approach

C# type hierarchy — Introduces an abstract McpServerConfig base class with:

  • A private protected constructor (no external subclassing)
  • sealed derived types McpStdioServerConfig and McpHttpServerConfig
  • Shared properties (Tools, Type, Timeout) deduplicated into the base
  • [JsonPolymorphic] discriminator on "type" following the same pattern as SessionEvent
  • [JsonIgnore] virtual Type property overridden in each derived type

Strongly-typed dictionaries — All Dictionary<string, object> McpServers properties (SessionConfig, ResumeSessionConfig, CustomAgentConfig, internal RPC records) are now Dictionary<string, McpServerConfig>.

Cross-language rename — Renamed Local/Remote → Stdio/Http across all four SDKs to match MCP protocol terminology:

Language Stdio HTTP
C# McpStdioServerConfig McpHttpServerConfig
TypeScript MCPStdioServerConfig MCPHttpServerConfig
Go MCPStdioServerConfig MCPHTTPServerConfig
Python MCPStdioServerConfig MCPHttpServerConfig

Docs — Updated MCP feature guide and troubleshooting guide with new type names and removed Type = "local" from C# examples (now handled by the type discriminator).

Validation

  • .NET: builds clean, all 13 clone/unit tests pass
  • Go: builds clean
  • TypeScript: no rename-related type errors (pre-existing unrelated errors from missing dev deps in this environment)
  • Grep sweep: zero remaining references to old type names across all files

Introduce an abstract McpServerConfig base class in C# with a private
protected constructor and sealed derived types McpStdioServerConfig and
McpHttpServerConfig. Shared properties (Tools, Type, Timeout) are
deduplicated into the base class. The Type property uses the
JsonPolymorphic discriminator pattern consistent with SessionEvent.

All Dictionary<string, object> McpServers properties are now strongly
typed as Dictionary<string, McpServerConfig>.

Rename Local/Remote to Stdio/Http across all four SDK languages to
match MCP protocol terminology:
- C#: McpStdioServerConfig / McpHttpServerConfig
- TypeScript: MCPStdioServerConfig / MCPHttpServerConfig
- Go: MCPStdioServerConfig / MCPHTTPServerConfig
- Python: MCPStdioServerConfig / MCPHttpServerConfig

Update documentation examples accordingly.

Fixes #245

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@stephentoub stephentoub requested a review from a team as a code owner April 9, 2026 13:45
Copilot AI review requested due to automatic review settings April 9, 2026 13:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors MCP server configuration types across the SDKs, primarily improving the .NET SDK by introducing a polymorphic McpServerConfig hierarchy and updating McpServers dictionaries to be strongly typed. It also renames “Local/Remote” MCP config types to “Stdio/Http” across TypeScript, Python, Go, .NET, and updates documentation and tests accordingly.

Changes:

  • .NET: Introduces polymorphic McpServerConfig with McpStdioServerConfig/McpHttpServerConfig and updates all McpServers dictionaries to Dictionary<string, McpServerConfig>.
  • TypeScript/Python/Go: Renames MCP config types to Stdio/Http variants and updates exports/tests accordingly.
  • Docs: Updates MCP feature and troubleshooting docs to use the new type names and removes explicit "local" type from C# examples.
Show a summary per file
File Description
python/copilot/session.py Renames Python MCP TypedDict config types to MCPStdioServerConfig / MCPHttpServerConfig.
nodejs/test/e2e/mcp_and_agents.test.ts Updates E2E test imports/casts to renamed MCP stdio config type.
nodejs/src/types.ts Renames exported TS MCP config interfaces and updates the union type.
nodejs/src/index.ts Re-exports the renamed TS MCP config interfaces from the public entrypoint.
go/types.go Renames Go MCP config structs to MCPStdioServerConfig / MCPHTTPServerConfig.
dotnet/test/McpAndAgentsTests.cs Updates .NET E2E tests to use typed MCP server configs and new names.
dotnet/test/CloneTests.cs Updates clone tests for strongly-typed McpServers dictionaries.
dotnet/src/Types.cs Adds polymorphic .NET MCP config type hierarchy and updates McpServers property types.
dotnet/src/Client.cs Updates internal RPC request records to use typed MCP server config dictionaries.
docs/troubleshooting/mcp-debugging.md Updates troubleshooting examples for renamed/typed MCP config types.
docs/features/mcp.md Updates MCP feature docs example to use typed McpServerConfig and renamed stdio type.

Copilot's findings

  • Files reviewed: 11/11 changed files
  • Comments generated: 2

@github-actions

This comment has been minimized.

Rename MCPHttpServerConfig to MCPHTTPServerConfig in Python (matching
stdlib convention: HTTPServer, HTTPError) and TypeScript (matching
the all-caps treatment of MCP already in use).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

@stephentoub
Copy link
Copy Markdown
Collaborator Author

Replying to review comment on Types.cs line 1422:

The suggestion won't compile — JsonDerivedType doesn't allow registering the same type with multiple discriminator values. Attempting it would throw InvalidOperationException at runtime.

IgnoreUnrecognizedTypeDiscriminators = true is kept for forward-compatibility (matching the existing pattern on SessionEvent). The primary use case here is serialization (SDK to CLI), where the types always emit the canonical stdio and http discriminators. Legacy values like local and sse are runtime-only synonyms that don't need SDK-side deserialization support.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generated by SDK Consistency Review Agent for issue #1051

Change MCPServerConfig from map[string]any to an interface with a
private marker method, matching the type-safety approach used for C#.
MCPStdioServerConfig and MCPHTTPServerConfig implement the interface
and use MarshalJSON to auto-inject the type discriminator.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

…n tests

- Update MCPServerConfigBase JSDoc to reference stdio/http instead of
  local/remote
- Remove explicit type: local from Python E2E tests (omitted type
  defaults to stdio, matching Go/C# pattern)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Cross-SDK Consistency Review ✅

This PR does an excellent job of maintaining consistency across all four SDK implementations. The rename from Local/RemoteStdio/Http is applied uniformly, and the type hierarchy improvements (sealed base class in C#, sealed interface in Go) are well-parallelized for each language's idioms.

Naming consistency check

Concern Stdio config HTTP config Notes
C# McpStdioServerConfig McpHttpServerConfig ✅ Correct .NET casing (acronyms ≤ 2 chars → PascalCase)
TypeScript MCPStdioServerConfig MCPHTTPServerConfig
Go MCPStdioServerConfig MCPHTTPServerConfig
Python MCPStdioServerConfig MCPHTTPServerConfig

Minor: The PR description table lists Python's HTTP type as MCPHttpServerConfig, but the actual code (and every other SDK) uses MCPHTTPServerConfig. Just a typo in the description—the code is correct.


One consistency gap to consider (pre-existing, but worth addressing)

The Node.js SDK explicitly re-exports MCPStdioServerConfig, MCPHTTPServerConfig, and MCPServerConfig from its public entry point (index.ts), so consumers can do:

import type { MCPStdioServerConfig } from "`@github/copilot-sdk`";

Python's __init__.py does not export any of the session config types (SessionConfig, ResumeSessionConfig, CustomAgentConfig, or the MCP types). Python consumers must import directly from the submodule:

from copilot.session import MCPStdioServerConfig  # works
from copilot import MCPStdioServerConfig           # ❌ fails

This is pre-existing and not introduced by this PR, but since this PR is already touching python/copilot/session.py as part of a public rename, it's a natural opportunity to add the MCP types (and ideally the other session config types) to python/copilot/__init__.py to bring Python in line with Node.js's explicit public API surface. Happy to leave this as a follow-up if you'd prefer to keep this PR focused.


Overall: the cross-SDK rename is thorough and consistent. No blocking issues found.

Generated by SDK Consistency Review Agent for issue #1051 ·

@stephentoub
Copy link
Copy Markdown
Collaborator Author

@SteveSandersonMS, mind taking a peek at this one, just to make sure you agree with the API changes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

improve typing of McpServers in C# sdk.

2 participants