ollama/docs/mcp-integration.md

266 lines
7.6 KiB
Markdown

# MCP (Model Context Protocol) Integration
This document describes the MCP integration for Ollama agents, enabling agents to use external tools via the Model Context Protocol.
## Overview
MCP allows Ollama agents to communicate with external tool servers over JSON-RPC 2.0 via stdio. This enables agents to access capabilities like web search, file operations, databases, and more through standardized tool interfaces.
## Status
| Phase | Description | Status |
|-------|-------------|--------|
| Phase 1 | Types & Parser | ✅ Complete |
| Phase 2 | Layer Handling | ✅ Complete |
| Phase 3 | Runtime Manager | ✅ Complete |
| Phase 4 | CLI Commands | ✅ Complete |
## Agentfile Syntax
### Simple Command Format
```dockerfile
MCP <name> <command> [args...]
```
Example:
```dockerfile
FROM llama3.2
AGENT TYPE conversational
SYSTEM You are a helpful assistant with MCP tools.
MCP calculator python3 ./mcp-server.py
MCP websearch node ./search-server.js
```
### JSON Format
```dockerfile
MCP {"name": "custom", "command": "uv", "args": ["run", "server.py"], "env": {"API_KEY": "xxx"}}
```
## Architecture
### Type Definitions
**MCPRef** (`types/model/config.go`):
```go
type MCPRef struct {
Name string `json:"name,omitempty"`
Digest string `json:"digest,omitempty"`
Command string `json:"command,omitempty"`
Args []string `json:"args,omitempty"`
Env map[string]string `json:"env,omitempty"`
Type string `json:"type,omitempty"` // "stdio"
}
```
### Tool Namespacing
MCP tools are namespaced to avoid conflicts:
- Format: `mcp_{serverName}_{toolName}`
- Example: Server "calculator" with tool "add" → `mcp_calculator_add`
### Runtime Flow
1. Agent starts → MCP servers spawn as subprocesses
2. Initialize via JSON-RPC: `initialize``notifications/initialized`
3. Discover tools: `tools/list`
4. During chat, model calls tools → routed via `tools/call`
5. On shutdown, MCP servers are gracefully terminated
## Files
### Created
| File | Purpose |
|------|---------|
| `cmd/mcp.go` | Runtime MCP manager with JSON-RPC protocol |
| `cmd/mcp_cmd.go` | CLI commands for managing MCPs (push, pull, list, etc.) |
| `server/mcp.go` | MCP layer utilities (extraction, creation) |
### Modified
| File | Changes |
|------|---------|
| `types/model/config.go` | Added `MCPRef` type, `MCPs` field to `ConfigV2` |
| `types/model/name.go` | Added `"mcp"` to `ValidKinds` for 5-part name parsing |
| `api/types.go` | Added `MCPRef` alias, `MCPs` to `CreateRequest`/`ShowResponse` |
| `parser/parser.go` | Added `MCP` command parsing with JSON and simple formats |
| `server/create.go` | Added `setMCPLayers()` for MCP config handling |
| `server/routes.go` | Added `MCPs` to show response |
| `cmd/cmd.go` | MCP integration in `chat()` function |
| `cmd/interactive.go` | Added `/mcp` and `/mcps` REPL commands |
## Usage Example
### 1. Create an MCP Server
```python
#!/usr/bin/env python3
# mcp-server.py
import json
import sys
def handle_request(req):
method = req.get("method", "")
if method == "initialize":
return {
"protocolVersion": "2024-11-05",
"capabilities": {"tools": {}},
"serverInfo": {"name": "example", "version": "1.0"}
}
elif method == "tools/list":
return {
"tools": [{
"name": "add",
"description": "Adds two numbers",
"inputSchema": {
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"}
},
"required": ["a", "b"]
}
}]
}
elif method == "tools/call":
args = req["params"]["arguments"]
return {"content": [{"type": "text", "text": f"{args['a'] + args['b']}"}]}
return {}
for line in sys.stdin:
req = json.loads(line)
if "id" in req:
result = handle_request(req)
print(json.dumps({"jsonrpc": "2.0", "id": req["id"], "result": result}), flush=True)
```
### 2. Create an Agent
```dockerfile
# my-agent.Agentfile
FROM gpt-oss:20b
AGENT TYPE conversational
SYSTEM You have access to a calculator. Use the add tool when asked to add numbers.
MCP calculator python3 ./mcp-server.py
```
### 3. Build and Run
```bash
ollama create my-agent -f my-agent.Agentfile
ollama run my-agent "What is 15 + 27?"
```
Output:
```
Loaded MCP servers: calculator (1 tools)
Executing: mcp_calculator_add
Output: 42
The result is 42.
```
## CLI Commands
The `ollama mcp` command provides utilities for managing MCP servers:
### Global Config Commands
Add an MCP server to the global config (`~/.ollama/mcp.json`):
```bash
# Add MCP to global config (available to all agents)
ollama mcp add web-search uv run ./mcp-server.py
ollama mcp add calculator python3 /path/to/calc.py
# List global MCP servers (shows enabled/disabled status)
ollama mcp list-global
# Disable an MCP server (keeps in config but won't be loaded)
ollama mcp disable web-search
# Re-enable a disabled MCP server
ollama mcp enable web-search
# Remove from global config
ollama mcp remove-global web-search
```
### Registry Commands
Package and push MCPs to a registry:
```bash
# Push MCP to registry (creates locally first)
ollama mcp push mcp/websearch:1.0 ./my-mcp-server/
# Pull MCP from registry
ollama mcp pull mcp/websearch:1.0
# List installed MCPs (from registry)
ollama mcp list
# Show MCP details
ollama mcp show mcp/websearch:1.0
# Remove MCP
ollama mcp rm mcp/websearch:1.0
```
## REPL Commands
Inside `ollama run`, you can manage MCP servers dynamically:
```
>>> /mcp # Show all MCP servers (model + global)
>>> /mcp add calc python3 ./calc-server.py # Add MCP server to global config
>>> /mcp remove calc # Remove MCP server from global config
>>> /mcp disable calc # Disable an MCP server (keep in config)
>>> /mcp enable calc # Re-enable a disabled MCP server
>>> /? mcp # Get help for MCP commands
```
The `/mcp` command shows all available MCP servers (both bundled with the model and from global config). Disabled servers are shown with a `[disabled]` marker. Use `/mcp add` and `/mcp remove` to manage MCPs in `~/.ollama/mcp.json`. Changes take effect on the next message.
## Global Config
MCPs can be configured globally in `~/.ollama/mcp.json`:
```json
{
"mcpServers": {
"web-search": {
"type": "stdio",
"command": "uv",
"args": ["run", "./mcp-server.py"]
},
"calculator": {
"type": "stdio",
"command": "python3",
"args": ["/path/to/calc.py"],
"disabled": true
}
}
}
```
The `disabled` field is optional. When set to `true`, the MCP server will not be loaded when running agents.
## Future Enhancements
1. **Remote Registry Push/Pull**: Full support for pushing/pulling MCPs to/from remote registries
2. **Use go-sdk**: Consider using `github.com/modelcontextprotocol/go-sdk` for protocol handling
3. **Resource Support**: Add MCP resources (not just tools)
4. **Prompt Support**: Add MCP prompts
## Protocol Reference
MCP uses JSON-RPC 2.0 over stdio with these key methods:
| Method | Direction | Purpose |
|--------|-----------|---------|
| `initialize` | Client→Server | Handshake with capabilities |
| `notifications/initialized` | Client→Server | Confirm initialization |
| `tools/list` | Client→Server | Discover available tools |
| `tools/call` | Client→Server | Execute a tool |
See [MCP Specification](https://modelcontextprotocol.io/docs) for full details.