Documentation
¶
Overview ¶
Package mcp provides canonical MCP (Model Context Protocol) server configuration types that serve as the bridge between different AI assistant platforms.
This package defines platform-agnostic types for representing MCP server configurations. These types can be translated to and from platform-specific formats (Claude Code, OpenCode, Codex, Gemini CLI) using the respective platform adapters.
Server Configuration ¶
The Server type represents a single MCP server with support for both local (stdio) and remote (SSE) transports:
// Local stdio server
server := &mcp.Server{
Name: "github",
Command: "npx",
Args: []string{"-y", "@modelcontextprotocol/server-github"},
Env: map[string]string{"GITHUB_TOKEN": "${GITHUB_TOKEN}"},
}
// Remote SSE server
server := &mcp.Server{
Name: "remote-api",
URL: "https://api.example.com/mcp",
Transport: mcp.TransportSSE,
Headers: map[string]string{"Authorization": "Bearer ${API_KEY}"},
}
Transport Types ¶
MCP supports two transport mechanisms:
- TransportStdio: Local process communication via stdin/stdout (default)
- TransportSSE: Remote server communication via Server-Sent Events
Use the Server.IsLocal and Server.IsRemote helper methods to determine the transport type:
if server.IsLocal() {
// Launch process with Command and Args
}
if server.IsRemote() {
// Connect to URL with Headers
}
Configuration Container ¶
The Config type holds a collection of server configurations:
config := mcp.NewConfig()
config.Servers["github"] = &mcp.Server{
Name: "github",
Command: "npx",
Args: []string{"-y", "@modelcontextprotocol/server-github"},
}
Forward Compatibility ¶
Both Server and Config preserve unknown JSON fields during serialization. This ensures forward compatibility when future MCP versions add new fields:
// Unknown fields are preserved through marshal/unmarshal cycles
data := []byte(`{"servers": {...}, "futureField": "value"}`)
var config mcp.Config
json.Unmarshal(data, &config)
output, _ := json.Marshal(&config)
// output contains futureField
Platform Translation ¶
These canonical types are designed to be translated to/from platform-specific formats. See the platform packages for translation logic:
- internal/platform/claude: Claude Code format (Command string, Args []string)
- internal/platform/opencode: OpenCode format (Command []string, Type string)
Index ¶
Constants ¶
const ( // TransportStdio indicates local process communication via stdin/stdout. // This is the default transport when a Command is specified. TransportStdio = "stdio" // TransportSSE indicates remote server communication via Server-Sent Events. // This transport is used when connecting to remote MCP servers via HTTP. TransportSSE = "sse" )
Transport type constants for MCP server communication.
Variables ¶
var ( // ErrFieldNotSupported indicates a canonical field cannot be represented // in the target platform format. Callers should warn users about potential // data loss when this error is encountered. // // Example: A canonical server has both Command and URL, but the target // platform only supports one transport type. ErrFieldNotSupported = errors.New("field not supported by platform") // ErrRequiredFieldMissing indicates the platform data is missing a field // required to construct a valid canonical representation. // // Example: A platform server config has neither "command" nor "url", // making it impossible to determine the transport type. ErrRequiredFieldMissing = errors.New("required field missing from platform data") )
Sentinel errors for translation operations.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Servers maps server names to their configurations.
Servers map[string]*Server `json:"servers"`
// contains filtered or unexported fields
}
Config represents a canonical MCP configuration containing server definitions. It can be translated to and from platform-specific configuration formats.
func (*Config) MarshalJSON ¶
MarshalJSON implements json.Marshaler to include unknown fields in output.
func (*Config) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler to capture unknown fields.
type Server ¶
type Server struct {
// Name is the server's unique identifier.
// This is typically used as the map key in configuration files.
Name string `json:"name"`
// Command is the executable path for local (stdio) servers.
// Required for local servers, empty for remote servers.
Command string `json:"command,omitempty"`
// Args are command-line arguments passed to the Command executable.
// Only applicable for local servers.
Args []string `json:"args,omitempty"`
// URL is the server endpoint for remote (SSE) servers.
// Required for remote servers, empty for local servers.
URL string `json:"url,omitempty"`
// Transport specifies the communication protocol: "stdio" or "sse".
// Defaults to "stdio" if Command is set, "sse" if URL is set.
Transport string `json:"transport,omitempty"`
// Env contains environment variables passed to the server process.
// Only applicable for local servers.
Env map[string]string `json:"env,omitempty"`
// Headers contains HTTP headers for SSE transport connections.
// Only applicable for remote servers.
Headers map[string]string `json:"headers,omitempty"`
// Platforms restricts the server to specific OS platforms.
// Valid values: "darwin", "linux", "windows".
// Empty means all platforms.
Platforms []string `json:"platforms,omitempty"`
// Disabled indicates whether the server is temporarily disabled.
Disabled bool `json:"disabled,omitempty"`
// contains filtered or unexported fields
}
Server represents a canonical MCP server configuration that can be translated to and from platform-specific formats.
func (*Server) IsLocal ¶
IsLocal returns true if this server uses local (stdio) transport. A server is considered local if it has a Command or explicit stdio transport.
func (*Server) IsRemote ¶
IsRemote returns true if this server uses remote (SSE) transport. A server is considered remote if it has a URL or explicit SSE transport.
func (*Server) MarshalJSON ¶
MarshalJSON implements json.Marshaler to include unknown fields in output.
func (*Server) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler to capture unknown fields.
type Translator ¶
type Translator interface {
// ToCanonical converts platform-specific MCP configuration to canonical format.
//
// The platformData parameter contains raw JSON from the platform's config file.
// For example, Claude Code uses a "mcpServers" key with server configs, while
// OpenCode uses an "mcp" key with a different structure.
//
// Returns the canonical Config representation, or an error if the platform
// data is malformed or cannot be converted.
//
// Unknown fields in the platform data should be captured and stored in the
// canonical types' unknownFields for preservation during round-trip.
ToCanonical(platformData []byte) (*Config, error)
// FromCanonical converts canonical MCP configuration to platform-specific format.
//
// Returns JSON bytes formatted according to the platform's expected structure.
// The output should be suitable for writing directly to the platform's config file.
//
// Returns [ErrFieldNotSupported] if the canonical config contains fields that
// cannot be represented in the platform format (caller should warn the user).
//
// Unknown fields stored in the canonical types should be included in the output
// if the platform format supports them.
FromCanonical(cfg *Config) ([]byte, error)
// Platform returns the name of the platform this translator handles.
//
// This is used for error messages, logging, and registry lookups.
// Expected values: "claude", "opencode", "codex", "gemini"
Platform() string
}
Translator converts between canonical and platform-specific MCP formats.
Each platform adapter (Claude Code, OpenCode, Codex, Gemini CLI) implements this interface to enable bidirectional translation of MCP server configurations.
Translation Flow ¶
When reading from a platform config:
platformJSON -> Translator.ToCanonical() -> *Config
When writing to a platform config:
*Config -> Translator.FromCanonical() -> platformJSON
Unknown Field Preservation ¶
Implementations MUST preserve unknown fields during translation. Platform configs may contain fields not defined in the canonical format, and these must be retained through the round-trip to avoid data loss.
Error Handling ¶
Implementations should return ErrFieldNotSupported when encountering a canonical field that cannot be represented in the platform format. This allows callers to warn users about potential data loss.
Implementations should return ErrRequiredFieldMissing when the platform data is missing a field required for valid canonical representation.
Example Implementation ¶
type ClaudeTranslator struct{}
func (t *ClaudeTranslator) ToCanonical(platformData []byte) (*Config, error) {
var claude ClaudeMCPConfig
if err := json.Unmarshal(platformData, &claude); err != nil {
return nil, err
}
// Convert ClaudeMCPConfig -> canonical *Config
return convertToCanonical(claude), nil
}
func (t *ClaudeTranslator) FromCanonical(cfg *Config) ([]byte, error) {
claude := convertFromCanonical(cfg)
return json.MarshalIndent(claude, "", " ")
}
func (t *ClaudeTranslator) Platform() string {
return "claude"
}