MCP Providers — Tool Discovery
Beluga AI v2 provides full support for the Model Context Protocol (MCP), enabling agents to discover and use tools from remote MCP servers. The implementation includes an MCP client and server, a server discovery registry, an official Go SDK bridge, and provider integrations for tool platforms.
Architecture
Section titled “Architecture”MCP in Beluga AI spans two packages:
tool/— Tool interface, local registry, and MCP client stubprotocol/mcp/— Full MCP client, server, registry discovery, SDK bridge, and providers
┌─────────────┐ JSON-RPC 2.0 ┌─────────────┐│ MCP Client │ ───────────────────> │ MCP Server ││ (Beluga) │ <─────────────────── │ (Remote) │└─────────────┘ └─────────────┘ │ ▼┌─────────────┐│ tool.Tool │ ← Remote tools wrapped as native Tool interface└─────────────┘MCP Client
Section titled “MCP Client”Connect to any MCP server and use its tools as native tool.Tool instances:
import "github.com/lookatitude/beluga-ai/protocol/mcp"
// Discover and wrap all tools from an MCP servertools, err := mcp.FromMCP(ctx, "https://mcp-server.example.com/mcp")if err != nil { log.Fatal(err)}
for _, t := range tools { fmt.Printf("Tool: %s — %s\n", t.Name(), t.Description())}
// Execute a toolresult, err := tools[0].Execute(ctx, map[string]any{ "query": "example input",})if err != nil { log.Fatal(err)}Client Methods
Section titled “Client Methods”The MCPClient provides low-level access to the MCP protocol:
client := mcp.NewClient("https://mcp-server.example.com/mcp")
// Initialize the session and discover server capabilitiescaps, err := client.Initialize(ctx)if err != nil { log.Fatal(err)}fmt.Printf("Server: %s v%s\n", caps.Tools != nil, caps.Resources != nil)
// List available toolstools, err := client.ListTools(ctx)if err != nil { log.Fatal(err)}
// Call a specific toolresult, err := client.CallTool(ctx, "get_weather", map[string]any{ "location": "Paris",})if err != nil { log.Fatal(err)}MCP Server
Section titled “MCP Server”Expose Beluga tools as an MCP server over HTTP:
import ( "github.com/lookatitude/beluga-ai/protocol/mcp" "github.com/lookatitude/beluga-ai/tool")
weatherTool := tool.NewFuncTool("get_weather", "Get current weather", func(ctx context.Context, input struct { Location string `json:"location" description:"City name"` }) (*tool.Result, error) { return tool.TextResult(fmt.Sprintf("Sunny in %s", input.Location)), nil },)
server := mcp.NewServer("my-server", "1.0.0")server.AddTool(weatherTool)
err := server.Serve(ctx, ":8080")if err != nil { log.Fatal(err)}The server implements JSON-RPC 2.0 over HTTP POST and handles:
initialize— Returns server capabilities and protocol versiontools/list— Lists all registered tools with their schemastools/call— Executes a tool and returns the resultresources/list— Lists registered resourcesprompts/list— Lists registered prompts
Server Discovery Registry
Section titled “Server Discovery Registry”The MCP registry discovers and aggregates tools from multiple MCP servers:
import "github.com/lookatitude/beluga-ai/protocol/mcp/registry"
reg := registry.New()reg.AddServer("weather", "https://weather-mcp.example.com/mcp", "weather", "utilities")reg.AddServer("search", "https://search-mcp.example.com/mcp", "search", "rag")
// Discover all tools across all serversdiscovered, err := reg.DiscoverTools(ctx)if err != nil { log.Fatal(err)}
for _, d := range discovered { fmt.Printf("[%s] %s: %s\n", d.ServerName, d.Tool.Name, d.Tool.Description)}
// Filter servers by tagweatherServers := reg.ServersByTag("weather")
// Get all tools as a flat slice (ready for agent use)tools, err := reg.Tools(ctx)if err != nil { log.Fatal(err)}Official SDK Bridge
Section titled “Official SDK Bridge”Bridge between Beluga tools and the official MCP Go SDK:
import "github.com/lookatitude/beluga-ai/protocol/mcp/sdk"
// Create an SDK-native MCP server from Beluga toolssdkServer := sdk.NewServer("my-server", "1.0.0", weatherTool, searchTool)
// Create a client from an SDK transport and get Beluga toolsclient, session, err := sdk.NewClient(ctx, transport)if err != nil { log.Fatal(err)}
tools, err := sdk.FromSession(ctx, session)if err != nil { log.Fatal(err)}Tool Interface
Section titled “Tool Interface”All tools from MCP servers are wrapped as native tool.Tool instances:
type Tool interface { Name() string Description() string InputSchema() map[string]any Execute(ctx context.Context, input map[string]any) (*Result, error)}This means MCP-sourced tools work identically with agents, middleware, hooks, and all other Beluga components that accept tool.Tool.
Static MCP Registry
Section titled “Static MCP Registry”For environments where MCP servers are known at compile time, use the static registry in the tool package:
import "github.com/lookatitude/beluga-ai/tool"
reg := tool.NewStaticMCPRegistry( tool.MCPServerInfo{ Name: "weather", URL: "https://weather-mcp.example.com/mcp", }, tool.MCPServerInfo{ Name: "search", URL: "https://search-mcp.example.com/mcp", },)
// Search for servers by name or URLservers, err := reg.Search(ctx, "weather")if err != nil { log.Fatal(err)}
// Discover all registered serversall, err := reg.Discover(ctx)if err != nil { log.Fatal(err)}Available Providers
Section titled “Available Providers”| Provider | Description |
|---|---|
| Composio | Access 250+ SaaS integrations as MCP tools via the Composio API |