# MCP and A2A Protocols

LibreFang supports MCP (Model Context Protocol) and A2A (Agent to Agent) protocols.

<Note>
**Protocol Comparison**:
- **MCP**: Connects LLMs to external tools/services (1-to-many)
- **A2A**: Enables communication between Agents (many-to-many)
</Note>

---

## MCP (Model Context Protocol)

MCP is a standardized protocol for connecting LLMs to external tools and services.

### Overview

```
┌─────────────┐      MCP       ┌─────────────┐
│   LibreFang │ ◄─────────────► │  MCP Server │
│   (Client)  │   JSON-RPC 2.0  │  (Server)   │
└─────────────┘                  └─────────────┘
```

### MCP Server Configuration

```toml
[[mcp_servers]]
name = "filesystem"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]

[[mcp_servers]]
name = "github"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
env = { GITHUB_TOKEN = "your-token" }
```

### MCP Tool Naming

MCP tool naming format:
```
mcp_{server}_{tool}
```

For example:
- `mcp_filesystem_read_file`
- `mcp_github_create_issue`

### Built-in MCP Servers

LibreFang includes built-in MCP servers:

| Server | Tools |
|--------|-------|
| filesystem | read_file, write_file, list_directory |
| github | create_issue, get_pr, search_repos |
| postgres | query, execute, list_tables |

### MCP Client

Connect to external servers as an MCP client:

```toml
[[mcp_servers]]
name = "custom"
command = "python"
args = ["./mcp_server.py"]
```

### Developing MCP Servers

```python
from mcp.server import Server
from mcp.types import Tool, TextContent

app = Server("my-server")

@app.list_tools()
async def list_tools():
    return [
        Tool(
            name="my_tool",
            description="My custom tool",
            inputSchema={"type": "object", "properties": {}}
        )
    ]

@app.call_tool()
async def call_tool(name: str, arguments: dict):
    return [TextContent(type="text", text="result")]
```

### MCP Taint Policy

Outbound payloads to MCP tools are scanned for sensitive data (tokens, API keys, well-known secret prefixes, PII) by an outbound taint detector. By default every detector rule fires; specific rules can be muted **per tool** or **per path** when a particular MCP server legitimately needs to receive that data class.

```toml
# config.toml — global mute by tool-name pattern
[[mcp_taint_policy]]
tool = "mcp__github__create_pr"
skip_rules = ["AuthorizationLiteral"]   # let GitHub MCP forward bearer tokens
```

**Available rule ids** (the `TaintRuleId` enum):

| Rule | Detects |
|---|---|
| `AuthorizationLiteral` | `Authorization: Bearer ...` / `Authorization: Basic ...` headers in payloads |
| `KeyValueSecret` | `password=...`, `token=...`, `api_key=...` patterns |
| `WellKnownPrefix` | `sk-`, `ghp_`, `xoxb-`, etc. — known token prefixes |
| `OpaqueToken` | Long high-entropy strings without a known prefix |
| `PiiEmail` / `PiiPhone` / `PiiCreditCard` / `PiiSsn` | Personal info classes |
| `SensitiveKeyName` | JSON keys named `password`, `secret`, `private_key`, etc. |

**API**: callers can also use `check_outbound_text_violation_with_skip(payload, sink, skip_rules)` directly to skip rules per call. The original `check_outbound_text_violation` delegates with an empty skip set, so existing callers keep their current behaviour.

---

## A2A (Agent to Agent)

The A2A protocol enables communication between LibreFang agents.

### Overview

```
┌─────────────┐      A2A       ┌─────────────┐
│   Agent A   │ ◄─────────────► │   Agent B   │
└─────────────┘   JSON over    └─────────────┘
                  HTTP/WebSocket
```

### Agent Card

Each Agent publishes an Agent Card:

```json
{
  "name": "researcher",
  "description": "Deep research agent",
  "url": "http://localhost:4545/api/a2a",
  "version": "1.0.0",
  "capabilities": {
    "streaming": true,
    "pushNotifications": false
  },
  "skills": [
    { "id": "research", "name": "Research" }
  ]
}
```

### Client Endpoints (Send Tasks to External A2A Agents)

These endpoints allow LibreFang to act as a client, delegating tasks to external A2A agents:

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/a2a/agents` | GET | List discovered external A2A agents |
| `/api/a2a/discover` | POST | Discover an external A2A agent at a URL |
| `/api/a2a/send` | POST | Send a task to an external A2A agent |
| `/api/a2a/tasks/{id}/status` | GET | Check the status of a sent task |

### Server Endpoints (Accept External Tasks)

These endpoints are exposed by LibreFang, allowing other A2A agents to send tasks to this instance:

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/.well-known/agent.json` | GET | Agent Card (capability declaration) |
| `/api/a2a/tasks` | POST | Accept tasks from external agents |
| `/api/a2a/tasks/{id}` | GET | Get task status |
| `/api/a2a/tasks/{id}/messages` | GET | Get task message history |

### Discover and Send Tasks to External Agents

```bash
# Discover an external agent
curl -X POST http://localhost:4545/api/a2a/discover \
  -H "Content-Type: application/json" \
  -d '{"url": "http://other-agent:4545"}'

# Send a task to an external agent
curl -X POST http://localhost:4545/api/a2a/send \
  -H "Content-Type: application/json" \
  -d '{
    "agent_url": "http://other-agent:4545",
    "message": "Research AI trends and summarize"
  }'

# Check task status
curl http://localhost:4545/api/a2a/tasks/task-123/status
```

### Accept Tasks from External Agents

```bash
# External agent sends a task to this instance
curl -X POST http://localhost:4545/api/a2a/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "id": "task-456",
    "message": {
      "role": "user",
      "parts": [{ "type": "text", "text": "Research AI trends" }]
    }
  }'

# Poll for results
curl http://localhost:4545/api/a2a/tasks/task-456

# Or use SSE for streaming
curl -N http://localhost:4545/api/a2a/tasks/task-456/events
```

---

## Comparison

| Feature | MCP | A2A |
|---------|-----|-----|
| Purpose | LLM to Tools | Agent to Agent |
| Protocol | JSON-RPC 2.0 | HTTP/WebSocket |
| Direction | Unidirectional | Bidirectional |
| Examples | Filesystem, GitHub | Agent collaboration |

---

## Use Cases

### MCP Use Cases

- Filesystem operations
- Database queries
- GitHub API calls
- Custom tool integration

### A2A Use Cases

- Multi-agent collaboration
- Task delegation
- Cross-instance communication

---

## Configuration Example

### Complete MCP Configuration

```toml
# MCP Servers
[[mcp_servers]]
name = "filesystem"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]

[[mcp_servers]]
name = "github"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]

# A2A Configuration
[a2a]
enabled = true
listen_path = "/a2a"
```

---

## CLI Commands

```bash
# List MCP servers
librefang mcp list

# Test an MCP server
librefang mcp test filesystem

# Start MCP mode
librefang mcp
```
