mcp

package
v0.1.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

README

MCP Integration for Genie

This package provides MCP (Model Context Protocol) integration for Genie, enabling connection to MCP servers via multiple transports (stdio, HTTP, SSE) and managing tool discovery and execution.

Overview

The MCP package uses mark3labs/mcp-go for MCP protocol communication and wraps tools to be compatible with trpc-agent-go.

Features

  • Multiple Transport Support: stdio, streamable_http, and sse
  • Tool Filtering: Include/exclude specific tools using allowlist/blocklist patterns
  • Configuration-Driven: TOML/YAML configuration for easy setup
  • trpc-agent-go Compatible: Tools work seamlessly with trpc-agent-go agents
  • Multiple Servers: Connect to multiple MCP servers simultaneously

Configuration

TOML Configuration Example
# Stdio transport (local MCP server)
[[mcp.servers]]
name = "local-tools"
transport = "stdio"
command = "go"
args = ["run", "./mcp-server/main.go"]
timeout = "60s"
include_tools = ["echo", "add"]  # Optional: allowlist specific tools

# Stdio with env (e.g. GitHub token from gh auth token)
# [[mcp.servers]]
# name = "github"
# transport = "stdio"
# command = "npx"
# args = ["-y", "@anthropic/github-mcp-server"]
# [mcp.servers.env]
# GITHUB_PERSONAL_ACCESS_TOKEN = "${GH_TOKEN}"
# Run: GH_TOKEN=$(gh auth token) genie mcp validate

# HTTP streaming transport with headers
[[mcp.servers]]
name = "terraform-registry"
transport = "streamable_http"
server_url = "http://localhost:3000/mcp"
timeout = "60s"

[mcp.servers.headers]
User-Agent = "genie/1.0"
Authorization = "Bearer your-token-here"

include_tools = ["search_modules", "get_module"]

# SSE transport
[[mcp.servers]]
name = "sse-server"
transport = "sse"
server_url = "http://localhost:8080/sse"
timeout = "60s"
YAML Configuration Example
mcp:
  servers:
    - name: local-tools
      transport: stdio
      command: go
      args:
        - run
        - ./mcp-server/main.go
      timeout: 60s
      include_tools:
        - echo
        - add
    
    - name: terraform-registry
      transport: streamable_http
      server_url: http://localhost:3000/mcp
      timeout: 60s
      headers:
        User-Agent: genie/1.0
        Authorization: Bearer your-token-here
      include_tools:
        - search_modules
        - get_module

Usage

Basic Usage
import (
    "context"
    "github.com/stackgenhq/genie/pkg/mcp"
    "time"
)

// Create configuration
config := mcp.MCPConfig{
    Servers: []mcp.MCPServerConfig{
        {
            Name:      "terraform",
            Transport: "streamable_http",
            ServerURL: "http://localhost:3000/mcp",
            Timeout:   60 * time.Second,
            IncludeTools: []string{"search_modules", "get_module"},
        },
    },
}

// Initialize client
client, err := mcp.NewClient(context.Background(), config)
if err != nil {
    // handle error
}
defer client.Close()

// Get available tools
tools := client.GetTools()

// Use tools with trpc-agent-go agents
// tools can be passed to llmagent.WithTools()
Tool Filtering
// Include only specific tools (allowlist)
config := mcp.MCPServerConfig{
    Name:      "server",
    Transport: "stdio",
    Command:   "mcp-server",
    IncludeTools: []string{"tool1", "tool2"},
}

// Exclude specific tools (blocklist)
config := mcp.MCPServerConfig{
    Name:      "server",
    Transport: "stdio",
    Command:   "mcp-server",
    ExcludeTools: []string{"dangerous_tool"},
}
Multiple Servers
config := mcp.MCPConfig{
    Servers: []mcp.MCPServerConfig{
        {
            Name:      "local-tools",
            Transport: "stdio",
            Command:   "go",
            Args:      []string{"run", "./server.go"},
        },
        {
            Name:      "remote-tools",
            Transport: "streamable_http",
            ServerURL: "http://localhost:3000/mcp",
        },
    },
}

client, err := mcp.NewClient(ctx, config)
// All tools from both servers are available via client.GetTools()

Configuration Options

MCPServerConfig
Field Type Required Description
name string Yes Unique identifier for the server
transport string Yes Transport type: "stdio", "streamable_http", or "sse"
server_url string For HTTP/SSE Server URL for HTTP/SSE transports
command string For stdio Executable command for stdio transport
args []string No Command arguments for stdio transport
timeout duration No Connection timeout (default: 60s)
headers map[string]string No Custom HTTP headers for HTTP/SSE transports
env map[string]string No Env vars for stdio subprocess (values support ${VAR} expansion)
include_tools []string No allowlist of tool names to include
exclude_tools []string No blocklist of tool names to exclude

Troubleshooting

Connection Issues

Problem: Failed to connect to stdio server

Solution:

  • Verify the command and args are correct
  • Ensure the MCP server executable is in PATH or use absolute path
  • Check server logs for initialization errors

Problem: HTTP/SSE connection timeout

Solution:

  • Verify the server_url is correct and accessible
  • Increase timeout value if server is slow to respond
  • Check network connectivity and firewall rules
Tool Discovery

Problem: No tools available after initialization

Solution:

  • Check if tool filtering is too restrictive
  • Verify the MCP server is properly implementing the ListTools endpoint
  • Check server logs for errors during tool listing
Integration with trpc-agent-go

Problem: Tools not working with agents

Solution:

  • Ensure tools are passed to agent via llmagent.WithTools(client.GetTools()...)
  • Verify tool schemas are valid
  • Check agent logs for tool execution errors

Validation

From the CLI, verify that all configured MCP servers are reachable and list tools:

genie mcp validate

For GitHub MCP, pass a token (e.g. from gh auth token):

GITHUB_PERSONAL_ACCESS_TOKEN=$(gh auth token) genie mcp validate
# or set GH_TOKEN and use [mcp.servers.env] GITHUB_PERSONAL_ACCESS_TOKEN = "${GH_TOKEN}" in config

Testing

Run tests:

go test ./pkg/mcp/... -v

Run tests with coverage:

go test ./pkg/mcp/... -cover

References

Documentation

Overview

Package mcp provides MCP (Model Context Protocol) integration for Genie using trpc-agent-go. It enables Genie to connect to MCP servers via multiple transports (stdio, HTTP, SSE) and manage tool discovery and execution.

The package leverages trpc-agent-go's out-of-the-box MCP tool integration (mcp.NewMCPToolSet) and provides a configuration-driven approach to managing MCP server connections.

Key Features

  • Multiple transport support: stdio, streamable_http, and sse
  • Tool filtering with include/exclude patterns
  • Session reconnection for automatic recovery
  • Configurable retry behavior with exponential backoff
  • Multiple concurrent MCP server connections

Basic Usage

import (
    "context"
    "github.com/stackgenhq/genie/pkg/mcp"
    "time"
)

// Create configuration
config := mcp.MCPConfig{
    Servers: []mcp.MCPServerConfig{
        {
            Name:      "terraform",
            Transport: "streamable_http",
            ServerURL: "http://localhost:3000/mcp",
            Timeout:   10 * time.Second,
            IncludeTools: []string{"search_modules", "get_module"},
        },
    },
}

// Initialize client
client, err := mcp.NewClient(context.Background(), config)
if err != nil {
    // handle error
}
defer client.Close()

// Get available tools
tools := client.GetTools()

Configuration Examples

See README.md for comprehensive configuration examples including:

  • Stdio transport configuration
  • HTTP/SSE transport configuration
  • Tool filtering
  • Session reconnection
  • Retry configuration

Integration with trpc-agent-go

This package uses trpc-agent-go's mcp.NewMCPToolSet to create MCP tool sets. The tools returned by GetTools() implement the tool.Tool interface and can be used directly with trpc-agent-go agents.

For more details on trpc-agent-go MCP integration, see: https://github.com/trpc-group/trpc-agent-go/tree/main/tool/mcp

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client manages MCP server connections and provides access to MCP tools. It uses mark3labs/mcp-go for MCP protocol communication and wraps tools to be compatible with trpc-agent-go.

Note: This is a simplified implementation that provides configuration management. Full MCP integration will be available when trpc-agent-go releases its MCP package.

func NewClient

func NewClient(ctx context.Context, config MCPConfig, opts ...ClientOption) (*Client, error)

NewClient creates a new MCP client from the provided configuration. It initializes connections to all configured MCP servers and returns a client that provides access to all available tools. Options (e.g. WithSecretProvider) can be used to enable secret lookup for MCP server env values containing "${VAR}".

The client must be closed when no longer needed to release resources.

func (*Client) Close

func (c *Client) Close(ctx context.Context)

Close closes all MCP server connections and releases resources. This should be called when the client is no longer needed.

func (*Client) GetTools

func (c *Client) GetTools() []tool.Tool

GetTools returns all available tools from all configured MCP servers. The tools implement the tool.Tool interface and can be used with trpc-agent-go agents.

type ClientOption

type ClientOption func(*Client)

ClientOption configures an MCP Client (e.g. WithSecretProvider).

func WithSecretProvider

func WithSecretProvider(sp security.SecretProvider) ClientOption

WithSecretProvider sets the SecretProvider used to resolve env values that start with "${" when building the stdio subprocess environment. If not set, env values are used as-is (config load may have already expanded them).

type ClientTool

type ClientTool struct {
	// contains filtered or unexported fields
}

ClientTool wraps an MCP Client and Tool to implement the trpc-agent-go tool.Tool interface. Tools are namespaced by server name to avoid collisions when multiple MCP servers expose tools with the same name (e.g. "search").

func NewClientTool

func NewClientTool(caller MCPCaller, mcpTool mcp.Tool, serverName string) *ClientTool

NewClientTool creates a new ClientTool wrapper. The serverName is used to prefix the tool name so that tools from different MCP servers are disambiguated (e.g. "github_search" vs "jira_search").

func (*ClientTool) Call

func (t *ClientTool) Call(ctx context.Context, jsonArgs []byte) (any, error)

Call executes the tool using the MCP client.

func (*ClientTool) Declaration

func (t *ClientTool) Declaration() *tool.Declaration

Declaration returns the tool declaration.

func (*ClientTool) Description

func (t *ClientTool) Description() string

Description returns the tool description.

func (*ClientTool) Name

func (t *ClientTool) Name() string

Name returns the namespaced tool name (serverName_toolName).

type MCPCaller added in v0.1.6

type MCPCaller interface {
	CallTool(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error)
}

MCPCaller is the subset of the MCP client interface used by ClientTool. Extracting this allows unit testing Call() with counterfeiter fakes.

type MCPConfig

type MCPConfig struct {
	// Servers is a list of MCP server configurations
	Servers []MCPServerConfig `json:"servers,omitempty" yaml:"servers,omitempty" toml:"servers,omitempty"`
}

MCPConfig represents the top-level MCP configuration for multiple server connections. This configuration enables Genie to connect to MCP servers via different transports (stdio, HTTP, SSE) and manage tool discovery and execution.

func (*MCPConfig) Validate

func (c *MCPConfig) Validate() error

Validate validates the MCP configuration and returns an error if invalid. This ensures that all required fields are present and values are within acceptable ranges.

type MCPServerConfig

type MCPServerConfig struct {
	// Name is a unique identifier for this server configuration
	Name string `json:"name,omitempty" yaml:"name,omitempty" toml:"name,omitempty"`

	// Transport specifies the connection type: "stdio", "streamable_http", or "sse"
	Transport string `json:"transport,omitempty" yaml:"transport,omitempty" toml:"transport,omitempty"`

	// ServerURL is the HTTP/SSE server URL (required for streamable_http and sse transports)
	ServerURL string `json:"server_url,omitempty" yaml:"server_url,omitempty" toml:"server_url,omitempty"`

	// Command is the executable command (required for stdio transport)
	Command string `json:"command,omitempty" yaml:"command,omitempty" toml:"command,omitempty"`

	// Args are the command arguments (optional for stdio transport)
	Args []string `json:"args,omitempty" yaml:"args,omitempty" toml:"args,omitempty"`

	// Timeout is the connection timeout duration (default: 60s)
	Timeout time.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty" toml:"timeout,omitempty"`

	// Headers are custom HTTP headers (optional for HTTP/SSE transports)
	Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty" toml:"headers,omitempty"`

	// Env is environment variables for the MCP subprocess (stdio transport only).
	// Values support ${VAR} expansion from config. Use for tokens, e.g.
	// GITHUB_PERSONAL_ACCESS_TOKEN = "${GH_TOKEN}" with GH_TOKEN=$(gh auth token).
	Env map[string]string `json:"env,omitempty" yaml:"env,omitempty" toml:"env,omitempty"`

	// IncludeTools is a list of tool names to include (allowlist)
	// If specified, only these tools will be available
	IncludeTools []string `json:"include_tools,omitempty" yaml:"include_tools,omitempty" toml:"include_tools,omitempty"`

	// ExcludeTools is a list of tool names to exclude (blocklist)
	// If specified, these tools will be filtered out
	ExcludeTools []string `json:"exclude_tools,omitempty" yaml:"exclude_tools,omitempty" toml:"exclude_tools,omitempty"`

	// SessionReconnect enables automatic session reconnection with max retry attempts
	// Set to 0 to disable session reconnection
	SessionReconnect int `json:"session_reconnect,omitempty" yaml:"session_reconnect,omitempty" toml:"session_reconnect,omitempty,omitzero"`
}

MCPServerConfig represents configuration for a single MCP server connection. It supports multiple transport types and provides fine-grained control over connection behavior, tool filtering, and error handling.

func (*MCPServerConfig) SetDefaults

func (s *MCPServerConfig) SetDefaults()

SetDefaults sets default values for the MCP configuration. This ensures that optional fields have sensible defaults when not specified.

func (*MCPServerConfig) Validate

func (s *MCPServerConfig) Validate() error

Validate validates a single MCP server configuration. It checks that required fields are present based on transport type and that values are within acceptable ranges.

Directories

Path Synopsis
Code generated by counterfeiter.
Code generated by counterfeiter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL