Skip to main content

MCP (Model Context Protocol)

MCP is a standardized protocol that gives AI models access to external tools, APIs, and data sources. LlamaFarm supports MCP both as a client (connecting to external MCP servers) and as a server (exposing its own API as MCP tools).

Why MCP?

Instead of limiting your AI to text generation, MCP lets you connect models to:

  • File systems - Read and analyze local files
  • Databases - Query and modify data
  • APIs - Interact with external services (weather, CRM, calendars)
  • Custom tools - Expose your own business logic

Quick Start

1. Add an MCP Server to Your Project

In your llamafarm.yaml:

mcp:
servers:
- name: filesystem
transport: stdio
command: npx
args:
- '-y'
- '@modelcontextprotocol/server-filesystem'
- '/path/to/allowed/directory'

2. Assign It to a Model

runtime:
models:
- name: assistant
provider: ollama
model: llama3.1:8b
mcp_servers:
- filesystem

3. Chat with Tool Access

lf chat "What files are in my documents folder?"

The model can now use the filesystem tools to answer your question.


Transport Types

LlamaFarm supports three transport mechanisms for connecting to MCP servers:

STDIO (Local Process)

Spawns the MCP server as a local subprocess. Best for local tools.

mcp:
servers:
- name: filesystem
transport: stdio
command: npx
args:
- '-y'
- '@modelcontextprotocol/server-filesystem'
- '/Users/myuser/documents'
env:
NODE_ENV: production
FieldTypeRequiredDescription
commandstringYesCommand to launch the server
argsarrayNoArguments to pass to the command
envobjectNoEnvironment variables for the process

Common STDIO Servers:

# Official Anthropic filesystem server
- name: filesystem
transport: stdio
command: npx
args: ['-y', '@modelcontextprotocol/server-filesystem', '/path/to/dir']

# SQLite database server
- name: sqlite
transport: stdio
command: npx
args: ['-y', '@modelcontextprotocol/server-sqlite', 'path/to/database.db']

# Custom Python MCP server
- name: my-python-tool
transport: stdio
command: python
args: ['-m', 'my_mcp_server']

HTTP (Remote Server)

Connects to a remote MCP server via HTTP streaming. Best for cloud services and shared tools.

mcp:
servers:
- name: remote-api
transport: http
base_url: https://api.example.com/mcp
headers:
Authorization: Bearer ${env:API_TOKEN}
X-Custom-Header: my-value
FieldTypeRequiredDescription
base_urlstringYesBase URL of the MCP server
headersobjectNoHTTP headers (supports ${env:VAR} substitution)

Use Cases:

  • FastAPI-MCP servers
  • Cloud-hosted tool services
  • Shared team tools

SSE (Server-Sent Events)

Connects via Server-Sent Events for real-time streaming.

mcp:
servers:
- name: streaming-server
transport: sse
base_url: https://api.example.com/mcp/sse
FieldTypeRequiredDescription
base_urlstringYesBase URL of the SSE endpoint

Per-Model Tool Access

Control which models can access which MCP servers. This is essential for security and capability management.

mcp:
servers:
- name: filesystem
transport: stdio
command: npx
args: ['-y', '@modelcontextprotocol/server-filesystem', '/data']

- name: database
transport: http
base_url: http://localhost:8080/mcp

runtime:
models:
# Research assistant - read-only file access
- name: research-assistant
provider: openai
model: gpt-4
mcp_servers:
- filesystem

# Data analyst - database access only
- name: data-analyst
provider: openai
model: gpt-4
mcp_servers:
- database

# General chat - no tool access (safer)
- name: general-chat
provider: ollama
model: llama3.1:8b
mcp_servers: [] # Empty list = no MCP

Access Control Rules

ConfigurationBehavior
mcp_servers: [server1, server2]Model can only use listed servers
mcp_servers: []Model has no MCP access
mcp_servers omittedModel can use all configured servers

LlamaFarm as an MCP Server

LlamaFarm itself exposes its API as MCP tools, allowing external clients (like Claude Desktop or Cursor) to control it.

Connecting from Claude Desktop

Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
"mcpServers": {
"llamafarm": {
"transport": "http",
"url": "http://localhost:8000/mcp"
}
}
}

Or use the HTTP transport if your MCP client supports it:

{
"mcpServers": {
"llamafarm": {
"transport": "http",
"url": "http://localhost:8000/mcp"
}
}
}

Available Tools (Exposed by LlamaFarm)

When you connect to LlamaFarm as an MCP server, you get access to:

ToolDescription
List projectsGet all projects in a namespace
Create projectCreate a new LlamaFarm project
Get projectGet project details and configuration
Update projectModify project settings
Delete projectRemove a project
Chat completionsSend messages to AI models
RAG queryQuery documents in vector databases
List modelsGet available AI models

Self-Reference Configuration

You can configure your project to use its own LlamaFarm server as an MCP source:

mcp:
servers:
- name: llamafarm-server
transport: http
base_url: http://localhost:8000/mcp

runtime:
models:
- name: default
provider: ollama
model: llama3.1:8b
mcp_servers: [llamafarm-server]

This allows models to interact with other LlamaFarm features programmatically.


Tool Call Strategies

LlamaFarm supports two strategies for tool calling:

Uses the model provider's native tool calling capabilities.

runtime:
models:
- name: assistant
provider: openai
model: gpt-4
tool_call_strategy: native_api

Supported providers: OpenAI, Anthropic, most modern LLM APIs

Prompt-Based

Injects tool definitions into the system prompt for models that don't support native tool calling.

runtime:
models:
- name: assistant
provider: ollama
model: llama2
tool_call_strategy: prompt_based

Use when: Using older models or providers without native tool support


Complete Configuration Example

Here's a full llamafarm.yaml with MCP configured:

version: v1
name: my-project
namespace: default

mcp:
servers:
# Local filesystem access
- name: filesystem
transport: stdio
command: npx
args:
- '-y'
- '@modelcontextprotocol/server-filesystem'
- '/Users/myuser/projects'

# SQLite database access
- name: database
transport: stdio
command: npx
args:
- '-y'
- '@modelcontextprotocol/server-sqlite'
- './data/app.db'

# Remote API with authentication
- name: company-api
transport: http
base_url: https://api.mycompany.com/mcp
headers:
Authorization: Bearer ${env:COMPANY_API_KEY}

# LlamaFarm's own API
- name: llamafarm
transport: http
base_url: http://localhost:8000/mcp

runtime:
default_model: assistant
models:
# Full-featured assistant with all tools
- name: assistant
provider: openai
model: gpt-4
tool_call_strategy: native_api
mcp_servers:
- filesystem
- database
- company-api

# Restricted model for public use
- name: public-chat
provider: ollama
model: llama3.1:8b
mcp_servers: [] # No tool access

# Internal tool for automation
- name: automation
provider: openai
model: gpt-4
mcp_servers:
- llamafarm
- database

prompts:
- name: default
messages:
- role: system
content: |
You are a helpful assistant with access to various tools.
Use the available tools to help answer questions and complete tasks.

Environment Variable Substitution

Use ${env:VARIABLE_NAME} to inject environment variables into your configuration:

mcp:
servers:
- name: secure-api
transport: http
base_url: ${env:API_BASE_URL}
headers:
Authorization: Bearer ${env:API_TOKEN}
X-API-Key: ${env:API_KEY}

This keeps secrets out of your configuration files.


Session Management

LlamaFarm maintains persistent MCP sessions for better performance:

  • Connection pooling - Sessions are reused across requests
  • 5-minute cache - Tool lists are cached to reduce overhead
  • Graceful shutdown - Sessions are properly closed when the server stops
  • 1-hour timeout - Long-running sessions for persistent connections

Debugging MCP

Check Server Configuration

lf config show | grep -A 20 "mcp:"

Test MCP Connection

The server logs will show MCP initialization:

MCPService initialized [services.mcp_service] server_count=2
Created all MCP tools [tools.mcp_tool] servers=['filesystem', 'database'] total_tools=5
MCP tools loaded [agents.chat_orchestrator] tool_count=5 tool_names=['read_file', 'write_file', ...]

Common Issues

IssueSolution
"Server not found"Check server name matches in mcp_servers list
"Connection refused"Ensure HTTP server is running at base_url
"Command not found"Install required packages (e.g., npm install -g @modelcontextprotocol/server-filesystem)
"Permission denied"Check file/directory permissions for STDIO servers

Real-World Use Cases

Code Analysis Assistant

mcp:
servers:
- name: codebase
transport: stdio
command: npx
args: ['-y', '@modelcontextprotocol/server-filesystem', './src']

runtime:
models:
- name: code-reviewer
provider: openai
model: gpt-4
mcp_servers: [codebase]
prompts: [code-review]

prompts:
- name: code-review
messages:
- role: system
content: |
You are a senior software engineer reviewing code.
Use the filesystem tools to read and analyze source files.
Provide constructive feedback on code quality, patterns, and potential issues.

Database Query Assistant

mcp:
servers:
- name: analytics-db
transport: stdio
command: npx
args: ['-y', '@modelcontextprotocol/server-sqlite', './analytics.db']

runtime:
models:
- name: data-analyst
provider: openai
model: gpt-4
mcp_servers: [analytics-db]

Multi-Tool Automation

mcp:
servers:
- name: filesystem
transport: stdio
command: npx
args: ['-y', '@modelcontextprotocol/server-filesystem', '/data']

- name: github
transport: http
base_url: https://github-mcp.example.com/mcp
headers:
Authorization: Bearer ${env:GITHUB_TOKEN}

- name: slack
transport: http
base_url: https://slack-mcp.example.com/mcp
headers:
Authorization: Bearer ${env:SLACK_TOKEN}

runtime:
models:
- name: devops-bot
provider: openai
model: gpt-4
mcp_servers: [filesystem, github, slack]

Building Your Own MCP Server

You can create custom MCP servers to expose your own tools. See the MCP documentation for the full specification.

Example: Python MCP Server

from mcp.server import Server
from mcp.server.stdio import stdio_server

app = Server("my-tools")

@app.tool()
async def my_custom_tool(param1: str, param2: int) -> str:
"""Description of what this tool does."""
# Your implementation
return f"Result: {param1}, {param2}"

async def main():
async with stdio_server() as (read_stream, write_stream):
await app.run(read_stream, write_stream)

if __name__ == "__main__":
import asyncio
asyncio.run(main())

Then configure it in LlamaFarm:

mcp:
servers:
- name: my-tools
transport: stdio
command: python
args: ['-m', 'my_mcp_server']

Next Steps