Skip to content

MCP (Model Context Protocol) plugin

The MCP (Model Context Protocol) plugin enables integration with MCP servers and allows you to expose Genkit tools as MCP servers. You can connect to external MCP servers to use their tools and prompts, manage multiple server connections, or turn your Genkit application into an MCP server.

This plugin requires MCP servers to be available. For testing and development, you can use:

  • mcp-server-time - Spmple server Exposing time operations
  • @modelcontextprotocol/server-everything - A comprehensive MCP server for testing
  • Custom MCP servers written in Python, TypeScript, or other languages

To connect to a single MCP server, import the mcp package and create a GenkitMCPClient:

import "github.com/firebase/genkit/go/plugins/mcp"
ctx := context.Background()
g, err := genkit.Init(ctx)
if err != nil {
log.Fatal(err)
}
client, err := mcp.NewGenkitMCPClient(mcp.MCPClientOptions{
Name: "mcp-server-time",
Stdio: &mcp.StdioConfig{
Command: "uvx",
Args: []string{"mcp-server-time"},
},
})
if err != nil {
log.Fatal(err)
}

To manage connections to multiple MCP servers, use GenkitMCPManager:

import "github.com/firebase/genkit/go/plugins/mcp"
manager, err := mcp.NewMCPManager(mcp.MCPManagerOptions{
Name: "my-app",
MCPServers: []mcp.MCPServerConfig{
{
Name: "everything-server",
Config: mcp.MCPClientOptions{
Name: "everything-server",
Stdio: &mcp.StdioConfig{
Command: "npx",
Args: []string{"-y", "@modelcontextprotocol/server-everything"},
},
},
},
{
Name: "mcp-server-time",
Config: mcp.MCPClientOptions{
Name: "mcp-server-time",
Stdio: &mcp.StdioConfig{
Command: "uvx",
Args: []string{"mcp-server-time"},
},
},
},
},
})
if err != nil {
log.Fatal(err)
}

To expose your Genkit tools as an MCP server, create an MCPServer:

import "github.com/firebase/genkit/go/plugins/mcp"
// Define your tools first
addTool := genkit.DefineTool(g, "add", "Add two numbers",
func(ctx *ai.ToolContext, input struct{A, B int}) (int, error) {
return input.A + input.B, nil
})
// Create MCP server
server := mcp.NewMCPServer(g, mcp.MCPServerOptions{
Name: "genkit-calculator",
Version: "1.0.0",
})

Once connected to an MCP server, you can retrieve and use its tools:

// Get a specific tool
echoTool, err := client.GetTool(ctx, g, "echo")
if err != nil {
log.Fatal(err)
}
// Use the tool in your workflow
resp, err := genkit.Generate(ctx, g,
ai.WithModel(myModel),
ai.WithPrompt("Use the echo tool to repeat this message"),
ai.WithTools(echoTool),
)
if err != nil {
log.Fatal(err)
}

Retrieve and use prompts from connected MCP servers:

// Get a specific prompt
simplePrompt, err := client.GetPrompt(ctx, g, "simple_prompt")
if err != nil {
log.Fatal(err)
}
// Use the prompt
resp, err := genkit.Generate(ctx, g,
ai.WithModel(myModel),
ai.WithPrompt(simplePrompt),
)

With GenkitMCPManager, you can dynamically manage server connections:

// Connect to a new server at runtime
err = manager.Connect("weather", mcp.MCPClientOptions{
Name: "weather-server",
Stdio: &mcp.StdioConfig{
Command: "python",
Args: []string{"weather_server.py"},
},
})
if err != nil {
log.Fatal(err)
}
// Disconnect a server completely
err = manager.Disconnect("weather")
if err != nil {
log.Fatal(err)
}
// Get all tools from all active servers
tools, err := manager.GetActiveTools(ctx, g)
if err != nil {
log.Fatal(err)
}
// Get a specific prompt from a specific server
prompt, err := manager.GetPrompt(ctx, g, "mcp-server-time", "current_time", nil)
if err != nil {
log.Fatal(err)
}

For individual client management (disable/enable without disconnecting), you would access the clients directly. The manager focuses on connection lifecycle management.

To run your Genkit application as an MCP server:

// Option 1: Auto-expose all defined tools
server := mcp.NewMCPServer(g, mcp.MCPServerOptions{
Name: "genkit-calculator",
Version: "1.0.0",
})
// Option 2: Expose only specific tools
server = mcp.NewMCPServer(g, mcp.MCPServerOptions{
Name: "genkit-calculator",
Version: "1.0.0",
Tools: []ai.Tool{addTool, multiplyTool},
})
// Start the MCP server
log.Println("Starting MCP server...")
if err := server.ServeStdio(ctx); err != nil {
log.Fatal(err)
}

You can use either Stdio or SSE

Stdio: &mcp.StdioConfig{
Command: "uvx",
Args: []string{"mcp-server-time"},
Env: []string{"DEBUG=1"},
}
SSE: &mcp.SSEConfig{
BaseURL: "http://localhost:3000/sse",
}

To test your Genkit application as an MCP server:

Terminal window
# Run your server
go run main.go
# Test with MCP Inspector in another terminal
npx @modelcontextprotocol/inspector go run main.go
type MCPClientOptions struct {
Name string // Server identifier
Version string // Version number (defaults to "1.0.0")
Disabled bool // Disabled flag to temporarily disable this client
Stdio *StdioConfig // Stdio transport config
SSE *SSEConfig // SSE transport config
}
type StdioConfig struct {
Command string // Command to run
Args []string // Command arguments
Env []string // Environment variables
}
type MCPServerConfig struct {
Name string // Name for this server
Config MCPClientOptions // Client configuration options
}
type MCPManagerOptions struct {
Name string // Manager instance name
Version string // Manager version (defaults to "1.0.0")
MCPServers []MCPServerConfig // Array of server configurations
}
type MCPServerOptions struct {
Name string // Server name
Version string // Server version
Tools []ai.Tool // Specific tools to expose (optional)
}