Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 104 additions & 88 deletions go/plugins/mcp/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Genkit MCP Plugin

Model Context Protocol (MCP) integration for Go Genkit - connect to MCP servers and expose Genkit tools as MCP servers.
Model Context Protocol (MCP) integration for Go Genkit

Connect to MCP servers and expose Genkit tools as MCP servers.

## GenkitMCPClient - Single Server Connection

Expand All @@ -10,52 +12,40 @@ Connect to and use tools/prompts from a single MCP server:
package main

import (
"context"
"log"
"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/mcp"
"context"
"log"

"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/mcp"
)

func main() {
ctx := context.Background()
g, _ := genkit.Init(ctx)

// Connect to the MCP everything server
client, err := mcp.NewGenkitMCPClient(mcp.MCPClientOptions{
Name: "everything-server",
Stdio: &mcp.StdioConfig{
Command: "npx",
Args: []string{"-y", "@modelcontextprotocol/server-everything"},
},
})
if err != nil {
log.Fatal(err)
}

// Get specific tools from the everything server
echoTool, err := client.GetTool(ctx, g, "echo")
if err != nil {
log.Fatal(err)
}

addTool, err := client.GetTool(ctx, g, "add")
if err != nil {
log.Fatal(err)
}

// Get specific prompts from the everything server
simplePrompt, err := client.GetPrompt(ctx, g, "simple_prompt")
if err != nil {
log.Fatal(err)
}

// Get all available tools
tools, err := client.GetActiveTools(ctx, g)
if err != nil {
log.Fatal(err)
}

ctx := context.Background()
g := genkit.Init(ctx)

// Connect to the MCP everything server
client, err := mcp.NewGenkitMCPClient(mcp.MCPClientOptions{
Name: "everything-server",
Stdio: &mcp.StdioConfig{
Command: "npx",
Args: []string{"-y", "@modelcontextprotocol/server-everything"},
},
})
if err != nil {
log.Fatal(err)
}

// Get specific prompts from the everything server
simplePrompt, err := client.GetPrompt(ctx, g, "simple-prompt", nil)
if err != nil {
log.Fatal(err)
}

// Get all available tools
tools, err := client.GetActiveTools(ctx, g)
if err != nil {
log.Fatal(err)
}
}
```

Expand All @@ -69,15 +59,15 @@ package main
import (
"context"
"log"

"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/mcp"
)

func main() {
ctx := context.Background()
g, _ := genkit.Init(ctx)

// Create manager with multiple servers
manager, err := mcp.NewMCPManager(mcp.MCPManagerOptions{
Name: "my-app",
Expand All @@ -101,7 +91,7 @@ func main() {
if err != nil {
log.Fatal(err)
}

// Connect to new server at runtime
err = manager.ConnectServer(ctx, "weather", mcp.MCPClientOptions{
Name: "weather-server",
Expand All @@ -113,14 +103,14 @@ func main() {
if err != nil {
log.Fatal(err)
}

// Temporarily disable/enable servers
manager.DisableServer("filesystem")
manager.EnableServer("filesystem")

// Disconnect server
manager.DisconnectServer("weather")

// Get tools from all active servers
tools, err := manager.GetActiveTools(ctx, g)
if err != nil {
Expand All @@ -137,48 +127,72 @@ Turn your Genkit app into an MCP server:
package main

import (
"context"
"log"

"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/mcp"
"github.com/firebase/genkit/go/ai"
"context"
"log"

"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/mcp"
)

func main() {
ctx := context.Background()
g, _ := genkit.Init(ctx)

// Define some tools
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
})

multiplyTool := genkit.DefineTool(g, "multiply", "Multiply two numbers",
func(ctx *ai.ToolContext, input struct{X, Y int}) (int, error) {
return input.X * input.Y, nil
})

// Option 1: Auto-expose all tools
server := mcp.NewMCPServer(g, mcp.MCPServerOptions{
Name: "genkit-calculator",
Version: "1.0.0",
})

// Option 2: Expose specific tools only
server = mcp.NewMCPServer(g, mcp.MCPServerOptions{
Name: "genkit-calculator",
Version: "1.0.0",
Tools: []ai.Tool{addTool, multiplyTool},
})

// Start MCP server
log.Println("Starting MCP server...")
if err := server.ServeStdio(ctx); err != nil {
log.Fatal(err)
}
ctx := context.Background()
g := genkit.Init(ctx)

// Create a host with multiple servers
host, err := mcp.NewMCPHost(g, mcp.MCPHostOptions{
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: "fs-server",
Config: mcp.MCPClientOptions{
Name: "fs-server",
Stdio: &mcp.StdioConfig{
Command: "npx",
Args: []string{"@modelcontextprotocol/server-filesystem", "/tmp"},
},
},
},
},
})
if err != nil {
log.Fatal(err)
}

// Connect to new server at runtime
err = host.Connect(ctx, g, "weather", mcp.MCPClientOptions{
Name: "weather-server",
Stdio: &mcp.StdioConfig{
Command: "python",
Args: []string{"weather_server.py"},
},
})
if err != nil {
log.Fatal(err)
}

// Reconnect server
host.Reconnect(ctx, "fs-server")

// Disconnect server
host.Disconnect(ctx, "weather")

// Get tools from all active servers
tools, err := host.GetActiveTools(ctx, g)
if err != nil {
log.Fatal(err)
}
}

```

## Testing Your Server
Expand All @@ -194,6 +208,7 @@ npx @modelcontextprotocol/inspector go run main.go
## Transport Options

### Stdio (Standard)

```go
Stdio: &mcp.StdioConfig{
Command: "uvx",
Expand All @@ -203,6 +218,7 @@ Stdio: &mcp.StdioConfig{
```

### SSE (Web clients)

```go
SSE: &mcp.SSEConfig{
BaseURL: "http://localhost:3000/sse",
Expand Down
Loading