> ## Documentation Index
> Fetch the complete documentation index at: https://hastekit.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Tools

MCP (Model Context Protocol) tools allow your agent to connect to external MCP servers and use their tools. This enables your agent to interact with various services and resources through standardized MCP tool interfaces.

## Connecting to an MCP Server

To use MCP tools, you first need to create an MCP client using the `mcpclient.NewClient` function.:

```go theme={null}
import (
    "context"
    "github.com/hastekit/hastekit-sdk-go/pkg/agents/mcpclient"
)

mcpClient, err := mcpclient.NewClient(context.Background(), "http://localhost:9001/sse",
    mcpclient.WithTransport("sse"),
)
if err != nil {
    log.Fatal(err)
}
```

### Parameters

* **`ctx`**: The context for the connection
* **`endpoint`**: The SSE endpoint URL of the MCP server (e.g., `"http://localhost:9001/sse"`)

## Custom Headers

You can also configure the MCP Client to send custom HTTP headers while interacting with the MCP server.

```go theme={null}
mcpClient, err := mcpclient.NewClient(context.Background(), "http://localhost:9001/sse",
    mcpclient.WithTransport("sse"),
	mcpclient.WithHeaders(map[string]string{
        "token": "your-token",
    }),
)
```

### Filtering Tools

You can optionally restrict which tools are exposed to the agent using the `WithToolFilter(...)` option. Only the named tools are surfaced; all others are dropped.

```go theme={null}
// Only use specific tools
mcpClient, err := mcpclient.NewClient(context.Background(), "http://localhost:9001/sse",
    mcpclient.WithTransport("sse"),
		mcpclient.WithToolFilter("list_users"),
	)
```

### Deferred (Lazy-Loaded) Tools

Use `WithDeferredTools(...)` to mark tools as deferred. Deferred tools are not added to the LLM's tool list upfront; instead they are discovered and activated on demand via the `ToolSearch` meta-tool. This keeps the prompt small when an MCP server exposes a large number of tools.

```go theme={null}
mcpClient, err := mcpclient.NewClient(context.Background(), "http://localhost:9001/sse",
    mcpclient.WithTransport("sse"),
    mcpclient.WithDeferredTools("rarely_used_tool"),
)
```

See [Deferred Tools](/docs/hastekit-sdk/agents/tools/deferred-tools) for how the activation flow works and when to defer a tool.

### Schema Caching

By default, the client connects to the MCP server to fetch tool schemas on every `ListTools` call. You can cache schemas to avoid repeated round-trips:

* `WithCacheTTL(ttl time.Duration)` sets how long cached schemas remain valid.
* `WithSchemaCache(cache SchemaCache)` injects a `SchemaCache` implementation. When set, `ListTools()` checks the cache before connecting to the MCP server. Back it with Redis (or a similar shared store) to share cached schemas across multiple pods.

```go theme={null}
mcpClient, err := mcpclient.NewClient(context.Background(), "http://localhost:9001/sse",
    mcpclient.WithTransport("sse"),
		mcpclient.WithCacheTTL(5*time.Minute),
		mcpclient.WithSchemaCache(myRedisSchemaCache),
	)
```

### Approval-Required Tools

Use `WithApprovalRequiredTools(...)` to mark specific MCP tools as requiring human approval before they run. See the [Human in the Loop](./human-in-the-loop) page for the full approval flow.

### Transport

You can set the transport to be used for the connection. Supported transports are `SSE` and `Streamable HTTP`. If not specified it defaults to `SSE`

```go theme={null}
mcpClient, err := mcpclient.NewClient(context.Background(), "http://localhost:9001/sse",
		mcpclient.WithTransport("streamable-http"), // or "sse"
	)
```

## Complete Example

Here's a complete example of an agent using MCP tools:

```go theme={null}
package main

import (
    "context"
    "fmt"
    "log"
    "os"

	"github.com/bytedance/sonic"
	"github.com/hastekit/hastekit-sdk-go/pkg/agents"
	"github.com/hastekit/hastekit-sdk-go/pkg/agents/history"
	"github.com/hastekit/hastekit-sdk-go/pkg/agents/mcpclient"
	"github.com/hastekit/hastekit-sdk-go/pkg/gateway/llm/responses"
	hastekit "github.com/hastekit/hastekit-sdk-go"
)

func main() {
    // Initialize LLM client
    client := hastekit.NewLLMClient([]hastekit.ProviderConfig{
        {
            ProviderName: hastekit.ProviderOpenAI,
            ApiKeys: []*hastekit.APIKeyConfig{
                {
                    Name:   "Key 1",
                    APIKey: os.Getenv("OPENAI_API_KEY"),
                },
            },
        },
    })

    // Bind a model
    model := client.Model("OpenAI/gpt-4o-mini")

    // Create conversation history
    conv := hastekit.NewFileHistory("./conversations")

    // Connect to MCP server
    mcpClient, err := mcpclient.NewClient(context.Background(), "http://localhost:9001/sse",
		mcpclient.WithHeaders(map[string]string{
			"token": "your-token",
		}),
		mcpclient.WithToolFilter("list_users"),
	)

    // Create agent with MCP tools
    agent := hastekit.NewAgent(&hastekit.AgentConfig{
        Name:        "Hello world agent",
        Instruction: hastekit.NewPrompt("You are helpful assistant."),
        LLM:         model,
        History:     conv,
        McpServers:  []agents.MCPToolset{mcpClient},
    })

    // Execute agent
    handle, err := agent.Execute(context.Background(), &agents.AgentInput{
        Message: history.Message{
            Messages: []responses.InputMessageUnion{
                responses.UserMessage("Hello!"),
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }
    out, err := handle.Result()
    if err != nil {
        log.Fatal(err)
    }

    b, _ := sonic.Marshal(out)
    fmt.Println(string(b))
}
```
