Capability Layer

Tools & MCP

Wrap any Go function as a tool with auto-generated JSON Schema. Discover and consume MCP servers. Expose your tools as MCP services. Parallel DAG execution for independent tools.

FuncToolMCP Client/ServerParallel DAGRegistryBuilt-in Tools

Overview

The Beluga AI tool system provides a unified abstraction for integrating external capabilities into agents. At its core, the FuncTool wrapper lets you turn any Go function into an agent-callable tool with automatically generated JSON Schema for parameter validation. The system supports both local tools and remote tools accessed via the Model Context Protocol (MCP).

MCP integration is bidirectional: your agents can consume tools from any MCP-compatible server, and you can expose your own Go tools as MCP services for other systems to use. The Streamable HTTP transport provides efficient communication with session management and OAuth support.

For performance-critical workloads, the parallel DAG executor automatically identifies independent tool calls and runs them concurrently. Combined with the registry pattern for runtime tool discovery and middleware for cross-cutting concerns like auth and rate limiting, the tool system provides a complete foundation for building capable AI agents.

Capabilities

FuncTool

Wrap any Go function as an agent-callable tool with automatic JSON Schema generation from struct tags. The framework introspects function signatures to produce the parameter schema that LLMs use to invoke tools correctly.

searchTool := tool.NewFuncTool("search", searchFunc)

MCP Client

Discover and consume tools, resources, and prompts from any MCP-compatible server. The client uses Streamable HTTP transport with automatic session management, reconnection logic, and OAuth authentication for secured endpoints.

MCP Server

Expose your Go tools, resources, and prompts as a standards-compliant MCP server. Any MCP client -- including Claude Desktop, Cursor, and other AI editors -- can connect and use your tools directly.

MCP Registry

Search and discover MCP servers from public registries. Browse available tools by category, filter by capability, and connect to servers on demand. Enables dynamic tool discovery at runtime.

Tool Registry

The standard Beluga registry pattern for tools: Add, Get, List, and Remove at runtime. Agents can dynamically add or remove tools based on context, user permissions, or task requirements.

Parallel DAG Execution

When an agent requests multiple tool calls, the executor builds a dependency graph and runs independent tools in parallel using goroutines. Dependent tools wait for their prerequisites. This dramatically reduces latency for multi-tool operations.

Built-in Tools

Common tools included out of the box: Calculator for math expressions, HTTP client for API calls, Shell executor for system commands (sandboxed), and Code sandbox for safe code execution. All follow the same Tool interface and can be extended or replaced.

Middleware and Hooks

Apply cross-cutting concerns to any tool via middleware: authentication, rate limiting, timeout enforcement, and logging. Hooks provide fine-grained lifecycle control with BeforeExecute, AfterExecute, and OnError callbacks.

Architecture

FuncTool
MCP Client
Built-in Tools
Tool Registry
Middleware
Parallel DAG
Hooks
Agent Runtime

Full Example

Create tools from Go functions, connect to an MCP server, and wire everything into an agent:

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/lookatitude/beluga-ai/agent"
    "github.com/lookatitude/beluga-ai/llm"
    "github.com/lookatitude/beluga-ai/tool"
    "github.com/lookatitude/beluga-ai/tool/mcp"
)

// Define a search function
func searchWeb(ctx context.Context, params struct {
    Query string `json:"query" description:"Search query"`
    Limit int    `json:"limit" description:"Max results" default:"5"`
}) ([]SearchResult, error) {
    // ... implementation
    return results, nil
}

func main() {
    ctx := context.Background()

    // Wrap Go function as a tool with auto JSON Schema
    searchTool := tool.NewFuncTool("search_web", searchWeb,
        tool.WithDescription("Search the web for information"),
    )

    // Connect to an MCP server for additional tools
    mcpClient, err := mcp.NewClient(ctx, "https://tools.example.com/mcp",
        mcp.WithOAuth("client-id", "client-secret"),
        mcp.WithSessionManagement(true),
    )
    if err != nil {
        log.Fatal(err)
    }
    defer mcpClient.Close()

    // Discover tools from MCP server
    mcpTools, _ := mcpClient.ListTools(ctx)

    // Create tool registry and add all tools
    registry := tool.NewRegistry()
    registry.Add(searchTool)
    for _, t := range mcpTools {
        registry.Add(t)
    }

    // Create LLM and agent with tools
    model, _ := llm.New("openai", llm.WithModel("gpt-4o"))

    myAgent, _ := agent.New("research-agent",
        agent.WithModel(model),
        agent.WithTools(registry.List()...),
        agent.WithToolHooks(tool.Hooks{
            BeforeExecute: func(ctx context.Context, name string, input any) error {
                fmt.Printf("Calling tool: %s\n", name)
                return nil
            },
            AfterExecute: func(ctx context.Context, name string, result any, err error) {
                fmt.Printf("Tool %s completed\n", name)
            },
        }),
    )

    // Run the agent - parallel tool calls execute concurrently
    result, err := myAgent.Run(ctx, "Research the latest AI frameworks and compare them")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(result)
}

Related Features