API Reference

LibreFang exposes a REST API, WebSocket endpoints, and SSE streaming when the daemon is running. The default listen address is http://127.0.0.1:4545.

All responses include security headers (CSP, X-Frame-Options, X-Content-Type-Options, HSTS) and are protected by a GCRA cost-aware rate limiter with per-IP token bucket tracking and automatic stale entry cleanup. LibreFang implements 16 security systems including Merkle audit trails, taint tracking, WASM dual metering, Ed25519 manifest signing, SSRF protection, subprocess sandboxing, and secret zeroization.

Table of Contents


Authentication

When an API key is configured in config.toml, all endpoints (except /api/health and /) require a Bearer token:

Authorization: Bearer <your-api-key>

Setting the API Key

Add to ~/.librefang/config.toml:

api_key = "your-secret-api-key"

No Authentication

If api_key is empty or not set, the API is accessible without authentication. CORS is restricted to localhost origins in this mode.

Public Endpoints (No Auth Required)

  • GET /api/health
  • GET / (WebChat UI)

Agent Endpoints

GET /api/agents

List all running agents.

Response 200 OK:

[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "hello-world",
    "state": "Running",
    "created_at": "2025-01-15T10:30:00Z",
    "model_provider": "groq",
    "model_name": "llama-3.3-70b-versatile"
  }
]

POST /api/agents

Spawn a new agent from a TOML manifest.

Request Body (JSON):

{
  "manifest_toml": "name = \"my-agent\"\nversion = \"0.1.0\"\ndescription = \"Test agent\"\nauthor = \"me\"\nmodule = \"builtin:chat\"\n\n[model]\nprovider = \"groq\"\nmodel = \"llama-3.3-70b-versatile\"\n\n[capabilities]\ntools = [\"file_read\", \"web_fetch\"]\nmemory_read = [\"*\"]\nmemory_write = [\"self.*\"]\n"
}

Response 201 Created:

{
  "agent_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "my-agent"
}

POST /api/agents/bulk

Bulk create multiple agents in a single request.

DELETE /api/agents/bulk

Bulk delete multiple agents by ID list.

POST /api/agents/bulk/start

Start multiple stopped agents simultaneously.

POST /api/agents/bulk/stop

Stop multiple running agents simultaneously.

GET /api/agents/{id}

Returns detailed information about a single agent.

Response 200 OK:

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "hello-world",
  "state": "Running",
  "created_at": "2025-01-15T10:30:00Z",
  "session_id": "s1b2c3d4-...",
  "model": {
    "provider": "groq",
    "model": "llama-3.3-70b-versatile"
  },
  "capabilities": {
    "tools": ["file_read", "file_list", "web_fetch"],
    "network": []
  },
  "description": "A friendly greeting agent",
  "tags": []
}

DELETE /api/agents/{id}

Terminate an agent and remove it from the registry.

Response 200 OK:

{
  "status": "killed",
  "agent_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

PATCH /api/agents/{id}

Partially update an agent's fields.

PUT /api/agents/{id}/update

Update an agent's configuration at runtime.

Request Body:

{
  "description": "Updated description",
  "system_prompt": "You are a specialized assistant.",
  "tags": ["updated", "v2"]
}

Response 200 OK:

{
  "status": "updated",
  "agent_id": "a1b2c3d4-..."
}

PUT /api/agents/{id}/mode

Set an agent's operating mode. Stable mode pins the current model and freezes the skill registry. Normal mode restores default behavior.

Request Body:

{
  "mode": "Stable"
}

Response 200 OK:

{
  "status": "updated",
  "mode": "Stable",
  "agent_id": "a1b2c3d4-..."
}

PATCH /api/agents/{id}/identity

Update an agent's identity fields (name, avatar, persona).

PATCH /api/agents/{id}/config

Partially patch an agent's configuration object.

POST /api/agents/{id}/clone

Clone an existing agent into a new one with a fresh session.

POST /api/agents/{id}/message

Send a message to an agent and receive the complete response.

Request Body:

{
  "message": "What files are in the current directory?"
}

Response 200 OK:

{
  "response": "Here are the files in the current directory:\n- Cargo.toml\n- README.md\n...",
  "input_tokens": 142,
  "output_tokens": 87,
  "iterations": 1
}

POST /api/agents/{id}/message/stream

Send a message and receive the response as a Server-Sent Events stream (see SSE Streaming).

GET /api/agents/{id}/session

Returns the agent's current conversation history.

Response 200 OK:

{
  "session_id": "s1b2c3d4-...",
  "agent_id": "a1b2c3d4-...",
  "message_count": 4,
  "context_window_tokens": 1250,
  "messages": [
    {
      "role": "User",
      "content": "Hello"
    },
    {
      "role": "Assistant",
      "content": "Hello! How can I help you?"
    }
  ]
}

GET /api/agents/{id}/sessions

List all sessions for an agent.

POST /api/agents/{id}/sessions

Create a new session for an agent.

POST /api/agents/{id}/sessions/{session_id}/switch

Switch the agent to use a different session by ID.

GET /api/agents/{id}/sessions/by-label/{label}

Find a session by its user-assigned label.

DELETE /api/agents/{id}/history

Clear all conversation history for an agent without creating a new session.

POST /api/agents/{id}/session/reset

Reset an agent's session, clearing all conversation history.

Response 200 OK:

{
  "status": "reset",
  "agent_id": "a1b2c3d4-...",
  "new_session_id": "s5e6f7g8-..."
}

POST /api/agents/{id}/session/compact

Trigger LLM-based session compaction. The agent's conversation is summarized by an LLM, keeping only the most recent messages plus a generated summary.

Response 200 OK:

{
  "status": "compacted",
  "message": "Session compacted: 80 messages summarized, 20 kept"
}

POST /api/agents/{id}/stop

Cancel the agent's current LLM run. Aborts any in-progress generation.

Response 200 OK:

{
  "status": "stopped",
  "message": "Agent run cancelled"
}

PUT /api/agents/{id}/model

Switch an agent's LLM model at runtime.

Request Body:

{
  "model": "claude-sonnet-4-20250514"
}

Response 200 OK:

{
  "status": "updated",
  "model": "claude-sonnet-4-20250514"
}

GET /api/agents/{id}/tools

Get an agent's current tool list.

PUT /api/agents/{id}/tools

Replace an agent's tool list at runtime.

GET /api/agents/{id}/skills

Get an agent's current skill list.

PUT /api/agents/{id}/skills

Replace an agent's skill list at runtime.

GET /api/agents/{id}/mcp_servers

Get the MCP servers attached to a specific agent.

PUT /api/agents/{id}/mcp_servers

Set the MCP servers attached to a specific agent.

GET /api/agents/{id}/traces

Get execution traces for an agent (tool calls, LLM iterations, timings).

GET /api/agents/{id}/metrics

Get runtime metrics for an agent (token counts, latency, error rates).

GET /api/agents/{id}/logs

Get recent log lines emitted by an agent's process.

GET /api/agents/{id}/deliveries

Get inbound message deliveries received by an agent from channels.

GET /api/agents/{id}/files

List files stored in an agent's private file workspace.

GET /api/agents/{id}/files/{filename}

Download a specific file from an agent's workspace.

PUT /api/agents/{id}/files/{filename}

Upload or overwrite a file in an agent's workspace.

DELETE /api/agents/{id}/files/{filename}

Delete a file from an agent's workspace.

POST /api/agents/{id}/upload

Upload a file to an agent's workspace (multipart form data).

GET /api/uploads/{file_id}

Retrieve a previously uploaded file by its upload ID.

GET /api/agents/{id}/ws

WebSocket connection for real-time bidirectional chat (see WebSocket Protocol).

GET /api/agents/{id}/memory/export

Export all memory entries for an agent as JSON.

POST /api/agents/{id}/memory/import

Import memory entries for an agent from JSON.


Workflow Endpoints

GET /api/workflows

List all registered workflows.

Response 200 OK:

[
  {
    "id": "w1b2c3d4-...",
    "name": "code-review-pipeline",
    "description": "Automated code review workflow",
    "steps": 3,
    "created_at": "2025-01-15T10:30:00Z"
  }
]

POST /api/workflows

Create a new workflow definition.

Request Body (JSON):

{
  "name": "code-review-pipeline",
  "description": "Review code changes with multiple agents",
  "steps": [
    {
      "name": "analyze",
      "agent_name": "coder",
      "prompt": "Analyze this code for potential issues: {&lbrace;input&rbrace;}",
      "mode": "sequential",
      "timeout_secs": 120,
      "error_mode": "fail",
      "output_var": "analysis"
    }
  ]
}

Step configuration options:

FieldTypeDescription
namestringStep name
agent_idstringAgent UUID (use either this or agent_name)
agent_namestringAgent name (use either this or agent_id)
promptstringPrompt template with {&lbrace;input&rbrace;} and {&lbrace;output_var&rbrace;} placeholders
modestring"sequential", "fan_out", "collect", "conditional", "loop"
timeout_secsintegerTimeout per step (default: 120)
error_modestring"fail", "skip", "retry"
max_retriesintegerFor "retry" error mode (default: 3)
output_varstringVariable name to store output for later steps
conditionstringFor "conditional" mode
max_iterationsintegerFor "loop" mode (default: 5)
untilstringFor "loop" mode: stop condition

Response 201 Created:

{
  "workflow_id": "w1b2c3d4-..."
}

GET /api/workflows/{id}

Get a specific workflow definition.

PUT /api/workflows/{id}

Update an existing workflow definition.

DELETE /api/workflows/{id}

Delete a workflow definition.

POST /api/workflows/{id}/run

Execute a workflow.

Request Body:

{
  "input": "Review this pull request: ..."
}

Response 200 OK:

{
  "run_id": "r1b2c3d4-...",
  "output": "Code review summary:\n- No critical issues found\n...",
  "status": "completed"
}

GET /api/workflows/{id}/runs

List execution history for a workflow.

Response 200 OK:

[
  {
    "id": "r1b2c3d4-...",
    "workflow_name": "code-review-pipeline",
    "state": "Completed",
    "steps_completed": 3,
    "started_at": "2025-01-15T10:30:00Z",
    "completed_at": "2025-01-15T10:32:15Z"
  }
]

Trigger Endpoints

GET /api/triggers

List all triggers. Optionally filter by agent.

Query Parameters:

  • agent_id (optional): Filter by agent UUID

Response 200 OK:

[
  {
    "id": "t1b2c3d4-...",
    "agent_id": "a1b2c3d4-...",
    "pattern": {"lifecycle": {}},
    "prompt_template": "Event: {&lbrace;event&rbrace;}",
    "enabled": true,
    "fire_count": 5,
    "max_fires": 0,
    "created_at": "2025-01-15T10:30:00Z"
  }
]

POST /api/triggers

Create a new event trigger.

Request Body:

{
  "agent_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "pattern": {
    "agent_spawned": {
      "name_pattern": "*"
    }
  },
  "prompt_template": "A new agent was spawned: {&lbrace;event&rbrace;}. Review its capabilities.",
  "max_fires": 0
}

Supported pattern types:

PatternDescription
{"lifecycle": {}}All lifecycle events
{"agent_spawned": {"name_pattern": "*"}}Agent spawn events
{"agent_terminated": {}}Agent termination events
{"all": {}}All events

Response 201 Created:

{
  "trigger_id": "t1b2c3d4-...",
  "agent_id": "a1b2c3d4-..."
}

PUT /api/triggers/{id}

Update an existing trigger's configuration.

Request Body:

{
  "prompt_template": "Updated template: {&lbrace;event&rbrace;}",
  "enabled": false,
  "max_fires": 10
}

Response 200 OK:

{
  "status": "updated",
  "trigger_id": "t1b2c3d4-..."
}

DELETE /api/triggers/{id}

Remove a trigger.

Response 200 OK:

{
  "status": "removed",
  "trigger_id": "t1b2c3d4-..."
}

Schedule Endpoints

Time-based agent activation using cron expressions or interval syntax.

GET /api/schedules

List all configured schedules.

POST /api/schedules

Create a new schedule.

Request Body:

{
  "agent_id": "a1b2c3d4-...",
  "cron": "0 9 * * 1-5",
  "prompt": "Good morning! Summarize overnight events.",
  "enabled": true
}

GET /api/schedules/{id}

Get a specific schedule.

PUT /api/schedules/{id}

Update a schedule.

DELETE /api/schedules/{id}

Delete a schedule.

POST /api/schedules/{id}/run

Trigger a schedule to run immediately (ignores its cron expression for this one invocation).


Memory Endpoints

LibreFang provides two memory systems: a simple key-value store per agent and a proactive semantic memory system (mem0-style) with relationship graphs and decay.

GET /api/memory/agents/{id}/kv

List all key-value pairs for an agent.

Response 200 OK:

{
  "kv_pairs": [
    {"key": "preferences", "value": {"theme": "dark"}},
    {"key": "state", "value": {"step": 3}}
  ]
}

GET /api/memory/agents/{id}/kv/{key}

Get a specific key-value pair.

Response 200 OK:

{
  "key": "preferences",
  "value": {"theme": "dark"}
}

Response 404 Not Found (key does not exist):

{
  "error": "Key 'preferences' not found"
}

PUT /api/memory/agents/{id}/kv/{key}

Set a key-value pair. Creates or overwrites.

Request Body:

{
  "value": {"theme": "dark", "language": "en"}
}

Response 200 OK:

{
  "status": "stored",
  "key": "preferences"
}

DELETE /api/memory/agents/{id}/kv/{key}

Delete a key-value pair.

Response 200 OK:

{
  "status": "deleted",
  "key": "preferences"
}

GET /api/memory

List all proactive memory entries (global, across agents and users).

POST /api/memory

Add a new proactive memory entry.

Request Body:

{
  "content": "User prefers concise answers",
  "agent_id": "a1b2c3d4-...",
  "user_id": "user-1",
  "tags": ["preference"]
}

Search proactive memory using semantic similarity.

Query Parameters:

  • q (required): Search query string
  • agent_id (optional): Limit to a specific agent
  • limit (optional): Max results (default: 10)

GET /api/memory/stats

Get aggregate statistics for the proactive memory store.

POST /api/memory/cleanup

Remove expired or stale memory entries.

POST /api/memory/decay

Apply time-decay to memory entry scores (reduces relevance of old entries).

POST /api/memory/bulk-delete

Delete multiple memory entries by ID list.

PUT /api/memory/items/{memory_id}

Update a specific memory entry.

DELETE /api/memory/items/{memory_id}

Delete a specific memory entry.

GET /api/memory/items/{memory_id}/history

Get the edit history for a specific memory entry.

GET /api/memory/user/{user_id}

Get all memory entries associated with a user.

GET /api/memory/agents/{id}

List all proactive memory entries for a specific agent.

DELETE /api/memory/agents/{id}

Delete all proactive memory entries for a specific agent.

Search proactive memory for a specific agent.

GET /api/memory/agents/{id}/stats

Get memory statistics for a specific agent.

DELETE /api/memory/agents/{id}/level/{level}

Clear all memory entries at a specific importance level for an agent.

GET /api/memory/agents/{id}/duplicates

Find duplicate memory entries for an agent.

POST /api/memory/agents/{id}/consolidate

Consolidate and deduplicate memory entries for an agent.

GET /api/memory/agents/{id}/count

Get the total memory entry count for an agent.

GET /api/memory/agents/{id}/relations

Query relationship graph entries for an agent.

POST /api/memory/agents/{id}/relations

Store new relationship graph entries for an agent.

GET /api/memory/agents/{id}/export

Export all proactive memory entries for an agent as JSON.

POST /api/memory/agents/{id}/import

Import proactive memory entries for an agent from JSON.


Channel Endpoints

GET /api/channels

List configured channel adapters and their status. Supports 44 channel adapters including Telegram, Discord, Slack, WhatsApp, Matrix, Email, Teams, Mattermost, IRC, Google Chat, Twitch, Rocket.Chat, Zulip, XMPP, LINE, Viber, Messenger, Reddit, Mastodon, Bluesky, and more.

Response 200 OK:

{
  "channels": [
    {
      "name": "telegram",
      "enabled": true,
      "has_token": true
    },
    {
      "name": "discord",
      "enabled": true,
      "has_token": false
    }
  ],
  "total": 2
}

GET /api/channels/{name}

Get configuration and status for a specific channel adapter.

POST /api/channels/{name}/configure

Configure a channel adapter (set token, bot name, options).

Request Body (example for Telegram):

{
  "token": "123456:ABC-DEF...",
  "agent_name": "my-agent"
}

DELETE /api/channels/{name}/configure

Remove the configuration for a channel adapter.

POST /api/channels/{name}/test

Send a test message through a channel adapter to verify connectivity.

POST /api/channels/reload

Reload all channel adapters from config without restarting the daemon.

POST /api/channels/whatsapp/qr/start

Start a WhatsApp QR code authentication session.

GET /api/channels/whatsapp/qr/status

Get the current status of the WhatsApp QR code session (pending/scanned/authenticated).


Template Endpoints

GET /api/templates

List available agent templates from the agents directory.

Response 200 OK:

{
  "templates": [
    {
      "name": "hello-world",
      "description": "A friendly greeting agent",
      "path": "/home/user/.librefang/agents/hello-world/agent.toml"
    },
    {
      "name": "coder",
      "description": "Expert coding assistant",
      "path": "/home/user/.librefang/agents/coder/agent.toml"
    }
  ],
  "total": 30
}

GET /api/templates/{name}

Get a specific template's manifest and raw TOML.

Response 200 OK:

{
  "name": "hello-world",
  "manifest": {
    "name": "hello-world",
    "description": "A friendly greeting agent",
    "module": "builtin:chat",
    "tags": [],
    "model": {
      "provider": "groq",
      "model": "llama-3.3-70b-versatile"
    },
    "capabilities": {
      "tools": ["file_read", "file_list", "web_fetch"],
      "network": []
    }
  },
  "manifest_toml": "name = \"hello-world\"\nversion = \"0.1.0\"\n..."
}

System Endpoints

GET /api/health

Public health check. Does not require authentication. Returns a redacted subset of system status (no database or agent_count details).

Response 200 OK:

{
  "status": "ok",
  "uptime_seconds": 3600,
  "panic_count": 0,
  "restart_count": 0
}

The status field is "ok" when all systems are healthy, or "degraded" when the database is unreachable.

GET /api/health/detail

Full health check with all dependency status. Requires authentication. Unlike the public /api/health, this endpoint includes database connectivity and agent counts.

Response 200 OK:

{
  "status": "ok",
  "uptime_seconds": 3600,
  "panic_count": 0,
  "restart_count": 0,
  "agent_count": 3,
  "database": "connected",
  "config_warnings": []
}

GET /api/status

Detailed kernel status including all agents.

Response 200 OK:

{
  "status": "running",
  "agent_count": 2,
  "data_dir": "/home/user/.librefang/data",
  "default_provider": "groq",
  "default_model": "llama-3.3-70b-versatile",
  "uptime_seconds": 3600,
  "agents": [
    {
      "id": "a1b2c3d4-...",
      "name": "hello-world",
      "state": "Running",
      "created_at": "2025-01-15T10:30:00Z",
      "model_provider": "groq",
      "model_name": "llama-3.3-70b-versatile"
    }
  ]
}

GET /api/version

Build and version information.

Response 200 OK:

{
  "name": "librefang",
  "version": "0.1.0",
  "build_date": "2025-01-15",
  "git_sha": "abc1234",
  "rust_version": "1.82.0",
  "platform": "linux",
  "arch": "x86_64"
}

POST /api/shutdown

Initiate graceful shutdown. Agent states are preserved to SQLite for restore on next boot.

Response 200 OK:

{
  "status": "shutting_down"
}

GET /api/profiles

List available agent profiles (predefined configurations for common use cases).

Response 200 OK:

{
  "profiles": [
    {
      "name": "coder",
      "tier": "smart",
      "description": "Expert coding assistant"
    },
    {
      "name": "researcher",
      "tier": "frontier",
      "description": "Deep research and analysis"
    }
  ]
}

GET /api/profiles/{name}

Get a specific profile by name.

GET /api/tools

List all available tools that agents can use.

Response 200 OK:

{
  "tools": [
    "file_read",
    "file_write",
    "file_list",
    "web_fetch",
    "web_search",
    "shell_exec",
    "kv_get",
    "kv_set",
    "agent_call"
  ],
  "total": 60
}

GET /api/tools/{name}

Get detailed information about a specific tool including its input schema.

GET /api/metrics

Prometheus-format metrics endpoint for integration with Grafana, Prometheus, or compatible monitoring stacks.

GET /api/versions

API version discovery. Returns all available API versions and their stability status.

GET /api/openapi.json

Auto-generated OpenAPI 3.0 specification for all API endpoints.


Config Management Endpoints

GET /api/config

Retrieve current kernel configuration (secrets are redacted).

Response 200 OK:

{
  "data_dir": "/home/user/.librefang/data",
  "default_provider": "groq",
  "default_model": "llama-3.3-70b-versatile",
  "listen_addr": "127.0.0.1:4545",
  "api_key_set": true,
  "channels_configured": 2,
  "mcp_servers": 1
}

GET /api/config/schema

Get the JSON Schema for the full config file (~/.librefang/config.toml). Useful for editor integrations and config validation.

POST /api/config/set

Set one or more config values at runtime without restarting.

Request Body:

{
  "key": "default_model",
  "value": "gemini-2.5-flash"
}

POST /api/config/reload

Reload configuration from disk (~/.librefang/config.toml).


Model Catalog Endpoints

LibreFang maintains a built-in catalog of 130+ models across 28 providers. These endpoints allow you to browse available models, check provider authentication status, and resolve model aliases.

GET /api/models

List the full model catalog. Returns all known models with their provider, tier, context window, and pricing information.

Response 200 OK:

{
  "models": [
    {
      "id": "claude-sonnet-4-20250514",
      "provider": "anthropic",
      "display_name": "Claude Sonnet 4",
      "tier": "frontier",
      "context_window": 200000,
      "input_cost_per_1m": 3.0,
      "output_cost_per_1m": 15.0,
      "supports_tools": true,
      "supports_vision": true,
      "supports_streaming": true
    },
    {
      "id": "gemini-2.5-flash",
      "provider": "gemini",
      "display_name": "Gemini 2.5 Flash",
      "tier": "smart",
      "context_window": 1048576,
      "input_cost_per_1m": 0.15,
      "output_cost_per_1m": 0.6,
      "supports_tools": true,
      "supports_vision": true,
      "supports_streaming": true
    }
  ],
  "total": 130
}

GET /api/models/aliases

List all model aliases. Aliases provide short names that resolve to full model IDs (e.g., sonnet resolves to claude-sonnet-4-20250514).

Response 200 OK:

{
  "aliases": {
    "sonnet": "claude-sonnet-4-20250514",
    "opus": "claude-opus-4-20250514",
    "haiku": "claude-3-5-haiku-20241022",
    "flash": "gemini-2.5-flash",
    "gpt4": "gpt-4o",
    "llama": "llama-3.3-70b-versatile",
    "deepseek": "deepseek-chat",
    "grok": "grok-2",
    "jamba": "jamba-1.5-large"
  },
  "total": 23
}

POST /api/models/aliases

Create a new model alias.

Request Body:

{
  "alias": "mymodel",
  "model_id": "llama-3.3-70b-versatile"
}

DELETE /api/models/aliases/{alias}

Delete a model alias.

POST /api/models/custom

Register a custom model definition.

Request Body:

{
  "id": "my-local-model",
  "provider": "ollama",
  "display_name": "My Local LLM",
  "context_window": 32768
}

DELETE /api/models/custom/{id}

Remove a custom model definition. The id parameter supports slashes (e.g., ollama/my-model).

GET /api/models/{id}

Get detailed information about a specific model. The id parameter supports slashes.

Response 200 OK:

{
  "id": "llama-3.3-70b-versatile",
  "provider": "groq",
  "display_name": "Llama 3.3 70B",
  "tier": "fast",
  "context_window": 131072,
  "input_cost_per_1m": 0.59,
  "output_cost_per_1m": 0.79,
  "supports_tools": true,
  "supports_vision": false,
  "supports_streaming": true
}

POST /api/catalog/update

Trigger an update of the model catalog from the remote registry.

GET /api/catalog/status

Get the current catalog version, last update time, and available updates.


Provider Configuration Endpoints

Manage LLM provider API keys at runtime without editing config files or restarting the daemon.

GET /api/providers

List all known LLM providers and their authentication status. Auth status is detected by checking environment variable presence (never reads secret values).

Response 200 OK:

{
  "providers": [
    {
      "name": "anthropic",
      "display_name": "Anthropic",
      "auth_status": "configured",
      "env_var": "ANTHROPIC_API_KEY",
      "base_url": "https://api.anthropic.com",
      "model_count": 3
    },
    {
      "name": "groq",
      "display_name": "Groq",
      "auth_status": "configured",
      "env_var": "GROQ_API_KEY",
      "base_url": "https://api.groq.com/openai",
      "model_count": 4
    },
    {
      "name": "ollama",
      "display_name": "Ollama",
      "auth_status": "no_key_needed",
      "base_url": "http://localhost:11434",
      "model_count": 0
    }
  ],
  "total": 28
}

GET /api/providers/ollama/detect

Auto-detect a locally running Ollama instance and enumerate its available models.

POST /api/providers/github-copilot/oauth/start

Initiate GitHub Copilot device OAuth flow. Returns a device_code and user_code for the user to enter at github.com/login/device.

GET /api/providers/github-copilot/oauth/poll/{poll_id}

Poll the OAuth device flow status. Returns pending, authorized, or expired.

GET /api/providers/{name}

Get configuration and status for a specific provider.

POST /api/providers/{name}/key

Set an API key for a provider. The key is stored securely and takes effect immediately.

Request Body:

{
  "api_key": "sk-..."
}

Response 200 OK:

{
  "status": "configured",
  "provider": "anthropic"
}

DELETE /api/providers/{name}/key

Remove the API key for a provider. Agents using this provider will fall back to the FallbackDriver or fail.

Response 200 OK:

{
  "status": "removed",
  "provider": "anthropic"
}

POST /api/providers/{name}/test

Test provider connectivity by making a minimal API call. Verifies that the configured API key is valid and the provider endpoint is reachable.

Response 200 OK:

{
  "status": "ok",
  "provider": "anthropic",
  "latency_ms": 245,
  "model_tested": "claude-sonnet-4-20250514"
}

PUT /api/providers/{name}/url

Override the base URL for a provider (useful for self-hosted or proxy endpoints).

Request Body:

{
  "url": "https://my-openai-proxy.example.com/v1"
}

Skills & Marketplace Endpoints

Manage the skill registry. Skills extend agent capabilities with Python, Node.js, WASM, or prompt-only modules. All skill installations go through SHA256 verification and prompt injection scanning.

GET /api/skills

List all installed skills.

Response 200 OK:

{
  "skills": [
    {
      "name": "github",
      "version": "1.0.0",
      "runtime": "prompt_only",
      "description": "GitHub integration for issues, PRs, and repos",
      "bundled": true
    },
    {
      "name": "docker",
      "version": "1.0.0",
      "runtime": "prompt_only",
      "description": "Docker container management",
      "bundled": true
    }
  ],
  "total": 60
}

POST /api/skills/install

Install a skill from a local path or URL. The skill manifest is verified (SHA256 checksum) and scanned for prompt injection before installation.

Request Body:

{
  "source": "/path/to/skill",
  "verify": true
}

Response 201 Created:

{
  "status": "installed",
  "skill": "my-custom-skill",
  "version": "1.0.0"
}

POST /api/skills/uninstall

Remove an installed skill. Bundled skills cannot be uninstalled.

Request Body:

{
  "name": "my-custom-skill"
}

Response 200 OK:

{
  "status": "uninstalled",
  "skill": "my-custom-skill"
}

POST /api/skills/create

Create a new skill from a template.

Request Body:

{
  "name": "my-skill",
  "runtime": "python",
  "description": "A custom skill"
}

Response 201 Created:

{
  "status": "created",
  "skill": "my-skill",
  "path": "/home/user/.librefang/skills/my-skill"
}

Search the FangHub marketplace for community skills.

Query Parameters:

  • q (required): Search query string
  • page (optional): Page number (default: 1)

Response 200 OK:

{
  "results": [
    {
      "name": "weather-api",
      "author": "community",
      "description": "Real-time weather data integration",
      "downloads": 1250,
      "version": "2.1.0"
    }
  ],
  "total": 1,
  "page": 1
}

ClawHub Endpoints

Browse and install skills from ClawHub (OpenClaw ecosystem compatibility). All installations go through the full security pipeline: SHA256 verification, SKILL.md security scanning, and trust boundary enforcement.

Search ClawHub for compatible skills.

Query Parameters:

  • q (required): Search query

GET /api/clawhub/browse

Browse ClawHub categories.

Query Parameters:

  • category (optional): Filter by category
  • page (optional): Page number (default: 1)

GET /api/clawhub/skill/{slug}

Get detailed information about a specific ClawHub skill.

GET /api/clawhub/skill/{slug}/code

Get the raw source code of a ClawHub skill.

POST /api/clawhub/install

Install a skill from ClawHub. Downloads, verifies SHA256 checksum, scans for prompt injection, and converts SKILL.md format to LibreFang skill.toml automatically.

Request Body:

{
  "slug": "data-pipeline"
}

Response 201 Created:

{
  "status": "installed",
  "skill": "data-pipeline",
  "version": "1.2.0",
  "converted_from": "SKILL.md"
}

Hands Endpoints

Hands are persistent automation processes (browser automation, RPA, long-running bots) managed by the kernel.

GET /api/hands

List all installed hand definitions.

POST /api/hands/install

Install a hand from a manifest or registry slug.

GET /api/hands/active

List currently active (running) hand instances.

GET /api/hands/{hand_id}

Get detailed information about a specific hand definition.

POST /api/hands/{hand_id}/activate

Activate a hand, creating a new running instance.

POST /api/hands/{hand_id}/check-deps

Check whether all dependencies required by a hand are installed.

POST /api/hands/{hand_id}/install-deps

Install missing dependencies for a hand.

GET /api/hands/{hand_id}/settings

Get the current settings for a hand.

PUT /api/hands/{hand_id}/settings

Update the settings for a hand.

POST /api/hands/instances/{id}/pause

Pause a running hand instance.

POST /api/hands/instances/{id}/resume

Resume a paused hand instance.

DELETE /api/hands/instances/{id}

Deactivate and remove a hand instance.

GET /api/hands/instances/{id}/stats

Get runtime statistics for a hand instance (uptime, events processed, errors).

GET /api/hands/instances/{id}/browser

Get the current browser state for a browser-automation hand instance.


Extensions Endpoints

Extensions add new capabilities to the daemon itself (custom tools, routes, integrations) without modifying core code.

GET /api/extensions

List all installed extensions.

GET /api/extensions/{name}

Get information about a specific extension.

POST /api/extensions/install

Install an extension from a path or registry.

POST /api/extensions/uninstall

Uninstall an extension by name.


Plugins Endpoints

Context engine plugins extend the context assembly pipeline (RAG, preprocessing, document loaders, etc.).

GET /api/plugins/registries

List configured plugin registries (local and remote).

GET /api/plugins

List all installed plugins.

GET /api/plugins/{name}

Get information about a specific plugin.

POST /api/plugins/install

Install a plugin from a registry or local path.

POST /api/plugins/uninstall

Uninstall a plugin by name.

POST /api/plugins/scaffold

Scaffold a new plugin project from a template.

POST /api/plugins/{name}/install-deps

Install runtime dependencies for a plugin (e.g., Python packages, Node modules).


MCP & A2A Protocol Endpoints

LibreFang supports both Model Context Protocol (MCP) for tool interoperability and Agent-to-Agent (A2A) protocol for cross-system agent communication.

GET /api/mcp/servers

List configured and connected MCP servers with their available tools.

Response 200 OK:

{
  "servers": [
    {
      "name": "filesystem",
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem"],
      "connected": true,
      "tools": [
        {
          "name": "mcp_filesystem_read_file",
          "description": "Read a file from the filesystem"
        }
      ]
    }
  ],
  "total": 1
}

POST /api/mcp/servers

Add a new MCP server configuration.

Request Body:

{
  "name": "filesystem",
  "transport": "stdio",
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem"]
}

GET /api/mcp/servers/{name}

Get configuration and connection status for a specific MCP server.

PUT /api/mcp/servers/{name}

Update an MCP server configuration.

DELETE /api/mcp/servers/{name}

Remove an MCP server configuration.

GET /api/a2a/agents

List external A2A agents that have been discovered or registered.

GET /api/a2a/agents/{id}

Get details for a specific external A2A agent.

POST /api/a2a/discover

Discover an external A2A agent by URL (fetches its /.well-known/agent.json).

Request Body:

{
  "url": "https://other-instance.example.com"
}

POST /api/a2a/send

Send a task to an external A2A agent.

Request Body:

{
  "agent_id": "external-agent-id",
  "message": "Summarize this document: ..."
}

GET /api/a2a/tasks/{id}/status

Check the status of a task sent to an external A2A agent.

POST /mcp

MCP HTTP transport endpoint. Accepts JSON-RPC 2.0 requests and exposes LibreFang tools via the MCP protocol to external clients.

Request Body (JSON-RPC 2.0):

{
  "jsonrpc": "2.0",
  "method": "tools/list",
  "id": 1
}

Response 200 OK:

{
  "jsonrpc": "2.0",
  "result": {
    "tools": [
      {
        "name": "file_read",
        "description": "Read a file's contents",
        "inputSchema": {
          "type": "object",
          "properties": {
            "path": {"type": "string"}
          }
        }
      }
    ]
  },
  "id": 1
}

GET /.well-known/agent.json

A2A agent card discovery endpoint. Returns the server's A2A agent card, which describes its capabilities, supported protocols, and available agents.

Response 200 OK:

{
  "name": "LibreFang",
  "description": "LibreFang Agent Operating System",
  "url": "http://127.0.0.1:4545",
  "version": "0.1.0",
  "capabilities": {
    "streaming": true,
    "pushNotifications": false
  },
  "skills": [
    {
      "id": "chat",
      "name": "Chat",
      "description": "General-purpose chat with any agent"
    }
  ]
}

GET /a2a/agents

List local agents available via the A2A protocol (unversioned, protocol-level endpoint).

POST /a2a/tasks/send

Send a task to a local agent via A2A protocol (unversioned).

Request Body:

{
  "agent_id": "a1b2c3d4-...",
  "message": {
    "role": "user",
    "parts": [
      {"text": "Review this code for security issues"}
    ]
  }
}

Response 200 OK:

{
  "task_id": "task-1234-...",
  "status": "completed",
  "result": {
    "role": "agent",
    "parts": [
      {"text": "I found 2 potential security issues..."}
    ]
  }
}

GET /a2a/tasks/{id}

Get the status and result of an A2A task (unversioned).

POST /a2a/tasks/{id}/cancel

Cancel a running A2A task (unversioned).

Response 200 OK:

{
  "task_id": "task-1234-...",
  "status": "cancelled"
}

Audit & Security Endpoints

LibreFang maintains a Merkle hash chain audit trail for all security-relevant operations. These endpoints allow inspection and verification of the audit log integrity.

GET /api/audit/recent

Retrieve recent audit log entries.

Query Parameters:

  • limit (optional): Number of entries to return (default: 50, max: 500)

Response 200 OK:

{
  "entries": [
    {
      "id": 1042,
      "timestamp": "2025-01-15T10:30:00Z",
      "event_type": "agent_spawned",
      "agent_id": "a1b2c3d4-...",
      "details": "Agent 'coder' spawned with model groq/llama-3.3-70b-versatile",
      "hash": "a1b2c3d4e5f6...",
      "prev_hash": "f6e5d4c3b2a1..."
    }
  ],
  "total": 1042
}

GET /api/audit/verify

Verify the integrity of the Merkle hash chain audit trail. Walks the entire chain and reports any broken links.

Response 200 OK:

{
  "status": "valid",
  "chain_length": 1042,
  "first_entry": "2025-01-10T08:00:00Z",
  "last_entry": "2025-01-15T10:30:00Z"
}

GET /api/security

Security status overview showing the state of all 16 security systems.

Response 200 OK:

{
  "security_systems": {
    "merkle_audit_trail": "active",
    "taint_tracking": "active",
    "wasm_dual_metering": "active",
    "security_headers": "active",
    "health_redaction": "active",
    "subprocess_sandbox": "active",
    "manifest_signing": "active",
    "gcra_rate_limiter": "active",
    "secret_zeroization": "active",
    "path_traversal_prevention": "active",
    "ssrf_protection": "active",
    "capability_inheritance_validation": "active",
    "ofp_hmac_auth": "active",
    "prompt_injection_scanning": "active",
    "loop_guard": "active",
    "session_repair": "active"
  },
  "total_systems": 16,
  "all_active": true
}

GET /api/logs/stream

SSE stream of structured log lines emitted by the daemon. Useful for live dashboards and log tailing.


Usage & Analytics Endpoints

Track token usage, costs, and model utilization across all agents. Powered by the metering engine with cost estimation from the model catalog.

GET /api/usage

Get overall usage statistics.

Query Parameters:

  • period (optional): Time period (hour, day, week, month; default: day)

Response 200 OK:

{
  "period": "day",
  "total_input_tokens": 125000,
  "total_output_tokens": 87000,
  "total_cost_usd": 0.42,
  "request_count": 156,
  "active_agents": 5
}

GET /api/usage/summary

Get a high-level usage summary with quota information.

Response 200 OK:

{
  "today": {
    "input_tokens": 125000,
    "output_tokens": 87000,
    "cost_usd": 0.42,
    "requests": 156
  },
  "quota": {
    "hourly_token_limit": 1000000,
    "hourly_tokens_used": 45000,
    "hourly_reset_at": "2025-01-15T11:00:00Z"
  }
}

GET /api/usage/by-model

Get usage breakdown by model.

Response 200 OK:

{
  "models": [
    {
      "model": "llama-3.3-70b-versatile",
      "provider": "groq",
      "input_tokens": 80000,
      "output_tokens": 55000,
      "cost_usd": 0.09,
      "request_count": 120
    }
  ]
}

GET /api/usage/daily

Get per-day usage breakdown for charting and reporting.


Budget Endpoints

Set spending limits per agent and globally to prevent runaway costs.

GET /api/budget

Get global budget status and spending summary.

Response 200 OK:

{
  "daily_limit_usd": 10.0,
  "monthly_limit_usd": 200.0,
  "today_spent_usd": 1.42,
  "month_spent_usd": 38.50,
  "status": "ok"
}

PUT /api/budget

Update global budget limits.

Request Body:

{
  "daily_limit_usd": 15.0,
  "monthly_limit_usd": 300.0
}

GET /api/budget/agents

Get a ranked list of agents by their current spending.

Response 200 OK:

[
  {
    "agent_id": "a1b2c3d4-...",
    "agent_name": "coder",
    "total_cost_usd": 0.87,
    "today_cost_usd": 0.12
  }
]

GET /api/budget/agents/{id}

Get budget status and spending detail for a specific agent.

PUT /api/budget/agents/{id}

Set or update budget limits for a specific agent.

Request Body:

{
  "daily_limit_usd": 2.0,
  "monthly_limit_usd": 40.0
}

Session Management Endpoints

GET /api/sessions

List all active sessions across agents.

Response 200 OK:

{
  "sessions": [
    {
      "id": "s1b2c3d4-...",
      "agent_id": "a1b2c3d4-...",
      "agent_name": "coder",
      "message_count": 12,
      "created_at": "2025-01-15T10:30:00Z"
    }
  ]
}

POST /api/sessions/cleanup

Remove old or orphaned sessions from the database.

GET /api/sessions/{id}

Get full details for a specific session including message count and metadata.

DELETE /api/sessions/{id}

Delete a specific session and its conversation history.

Response 200 OK:

{
  "status": "deleted",
  "session_id": "s1b2c3d4-..."
}

PUT /api/sessions/{id}/label

Assign a human-readable label to a session for later retrieval.

Request Body:

{
  "label": "code-review-session-2025-01"
}

Goals Endpoints

Hierarchical goal tracking system for multi-step agent objectives.

GET /api/goals

List all goals.

POST /api/goals

Create a new goal.

Request Body:

{
  "title": "Migrate database to PostgreSQL",
  "description": "Complete migration with zero downtime",
  "agent_id": "a1b2c3d4-...",
  "parent_id": null,
  "due_at": "2025-02-01T00:00:00Z"
}

GET /api/goals/{id}

Get a specific goal.

PUT /api/goals/{id}

Update a goal (title, status, description, due date).

DELETE /api/goals/{id}

Delete a goal and all its children.

GET /api/goals/{id}/children

List sub-goals for a given parent goal.


Cron Endpoints

Schedule recurring jobs using standard cron expression syntax.

GET /api/cron/jobs

List all cron jobs.

POST /api/cron/jobs

Create a new cron job.

Request Body:

{
  "name": "daily-digest",
  "schedule": "0 8 * * *",
  "agent_id": "a1b2c3d4-...",
  "prompt": "Prepare the daily digest of overnight activity.",
  "enabled": true
}

GET /api/cron/jobs/{id}

Get details for a specific cron job.

PUT /api/cron/jobs/{id}

Update a cron job (schedule, prompt, agent, etc.).

DELETE /api/cron/jobs/{id}

Delete a cron job.

PUT /api/cron/jobs/{id}/enable

Toggle a cron job's enabled state.

Request Body:

{
  "enabled": false
}

GET /api/cron/jobs/{id}/status

Get the last run result and next scheduled time for a cron job.


Webhooks Endpoints

GET /api/webhooks/events

List event webhook subscriptions (inbound events that trigger agent actions).

POST /api/webhooks/events

Create a new event webhook subscription.

Request Body:

{
  "event_type": "agent_spawned",
  "url": "https://my-service.example.com/events",
  "secret": "webhook-secret"
}

PUT /api/webhooks/events/{id}

Update an event webhook subscription.

DELETE /api/webhooks/events/{id}

Delete an event webhook subscription.

GET /api/webhooks

List outbound webhook configurations.

POST /api/webhooks

Create a new outbound webhook.

GET /api/webhooks/{id}

Get a specific outbound webhook configuration.

PUT /api/webhooks/{id}

Update an outbound webhook configuration.

DELETE /api/webhooks/{id}

Delete an outbound webhook.

POST /api/webhooks/{id}/test

Send a test payload to an outbound webhook and return the result.

POST /api/hooks/wake

Webhook trigger endpoint (unversioned). Wakes an agent from an external HTTP call.

POST /api/hooks/agent

Webhook trigger endpoint (unversioned). Sends a message to an agent from an external HTTP caller.


Backup & Restore Endpoints

POST /api/backup

Create a full backup of the daemon state (agents, sessions, memory, config).

Response 200 OK:

{
  "filename": "librefang-backup-2025-01-15T10-30-00.tar.gz",
  "size_bytes": 2048576
}

GET /api/backups

List all available backup files.

DELETE /api/backups/{filename}

Delete a backup file.

POST /api/restore

Restore daemon state from a backup file.

Request Body:

{
  "filename": "librefang-backup-2025-01-15T10-30-00.tar.gz"
}

Integrations Endpoints

Connect LibreFang to external services (GitHub, Jira, Notion, Google Drive, etc.).

GET /api/integrations

List all connected integrations and their status.

GET /api/integrations/available

List all integrations available for installation.

GET /api/integrations/health

Get health status for all connected integrations.

POST /api/integrations/add

Add and connect a new integration.

Request Body:

{
  "type": "github",
  "token": "ghp_...",
  "name": "my-github"
}

POST /api/integrations/reload

Reload all integrations from config.

GET /api/integrations/{id}

Get details for a specific integration.

DELETE /api/integrations/{id}

Remove an integration.

POST /api/integrations/{id}/reconnect

Re-authenticate and reconnect a disconnected integration.


Pairing Endpoints

Pair mobile apps or secondary devices to the daemon for remote control and notifications.

POST /api/pairing/request

Initiate a pairing request. Returns a pairing code for the user to enter on the remote device.

Response 200 OK:

{
  "pairing_code": "XK9-47B",
  "expires_at": "2025-01-15T10:35:00Z"
}

POST /api/pairing/complete

Complete pairing by confirming the code from the remote device.

POST /api/pairing/notify

Send a push notification to all paired devices.

GET /api/pairing/devices

List all paired devices.

DELETE /api/pairing/devices/{id}

Remove a paired device.


OAuth / OIDC Endpoints

External authentication via OAuth 2.0 and OpenID Connect providers. Enables single sign-on for the WebChat dashboard.

GET /api/auth/providers

List configured OAuth/OIDC providers (e.g., Google, GitHub, Authentik).

GET /api/auth/login

Redirect to the default configured OAuth provider's login page.

GET /api/auth/login/{provider}

Redirect to a specific provider's OAuth login page.

GET /api/auth/callback

OAuth callback handler (GET). Receives the authorization code from the provider.

POST /api/auth/callback

OAuth callback handler (POST). Handles form-post style callbacks.

GET /api/auth/userinfo

Return the authenticated user's profile from the OIDC userinfo endpoint.

POST /api/auth/introspect

Token introspection endpoint. Validates and returns metadata for an OAuth access token.


Task Queue Endpoints

Inspect and manage the daemon's internal async task queue.

GET /api/tasks/status

Get summary status of the task queue (pending, running, failed counts).

GET /api/tasks/list

List queued and recently completed tasks.

DELETE /api/tasks/{id}

Cancel and remove a queued task.

POST /api/tasks/{id}/retry

Retry a failed task.

GET /api/queue/status

Get the current queue depth and throughput metrics.


Comms Endpoints

The comms layer manages inter-agent communication, event routing, and messaging topology.

GET /api/comms/topology

Get the current communication topology (agent graph, routing table).

GET /api/comms/events

Get recent communication events (messages routed between agents and channels).

GET /api/comms/events/stream

SSE stream of live communication events as they occur.

POST /api/comms/send

Send a message directly through the comms layer to an agent or channel.

Request Body:

{
  "to": "agent:a1b2c3d4-...",
  "content": "Please review the latest PR",
  "from": "system"
}

POST /api/comms/task

Dispatch a task via the comms layer (routed to the appropriate agent).


Approvals Endpoints

Human-in-the-loop approval workflow. Agents can request approval before executing sensitive actions.

GET /api/approvals

List pending and recent approval requests.

POST /api/approvals

Create an approval request (typically called by an agent tool).

Request Body:

{
  "agent_id": "a1b2c3d4-...",
  "action": "delete_file",
  "description": "Agent wants to delete /important/config.toml",
  "payload": {"path": "/important/config.toml"}
}

GET /api/approvals/{id}

Get details for a specific approval request.

POST /api/approvals/{id}/approve

Approve a pending request. The waiting agent proceeds with the action.

POST /api/approvals/{id}/reject

Reject a pending request. The waiting agent receives a rejection and halts the action.


Bindings & Commands Endpoints

GET /api/bindings

List current keyboard/event bindings for the WebChat UI.

POST /api/bindings

Add a new binding.

DELETE /api/bindings/{index}

Remove a binding by its index in the bindings list.

GET /api/commands

List all available slash commands for the WebChat input.

GET /api/commands/{name}

Get details for a specific slash command.


Network & Peers Endpoints

GET /api/peers

List OFP (LibreFang Protocol) wire peers and their connection status.

Response 200 OK:

{
  "peers": [
    {
      "node_id": "peer-1",
      "address": "192.168.1.100:4000",
      "state": "connected",
      "authenticated": true,
      "last_seen": "2025-01-15T10:30:00Z"
    }
  ]
}

GET /api/peers/{id}

Get details for a specific OFP peer.

GET /api/network/status

Get the overall OFP network status (node ID, connected peers, message throughput).


Migration Endpoints

Import data from OpenClaw or other agent frameworks. The migration engine handles YAML-to-TOML manifest conversion, SKILL.md parsing, and session history import.

GET /api/migrate/detect

Auto-detect migration sources on the system. Scans common locations for OpenClaw installations, config files, and agent data.

Response 200 OK:

{
  "sources": [
    {
      "type": "openclaw",
      "path": "/home/user/.openclaw",
      "version": "2.1.0",
      "agents_found": 12,
      "skills_found": 8
    }
  ]
}

POST /api/migrate/scan

Scan a specific path for importable data.

Request Body:

{
  "path": "/home/user/.openclaw"
}

Response 200 OK:

{
  "agents": [
    {
      "name": "my-agent",
      "format": "yaml",
      "convertible": true
    }
  ],
  "skills": [
    {
      "name": "custom-skill",
      "format": "SKILL.md",
      "convertible": true
    }
  ],
  "sessions": 45
}

POST /api/migrate

Run the migration. Converts manifests, imports skills, and optionally imports session history.

Request Body:

{
  "source": "/home/user/.openclaw",
  "import_agents": true,
  "import_skills": true,
  "import_sessions": false
}

Response 200 OK:

{
  "status": "completed",
  "agents_imported": 12,
  "skills_imported": 8,
  "sessions_imported": 0,
  "warnings": [
    "Skill 'legacy-plugin' uses unsupported runtime 'ruby', skipped"
  ]
}

WebSocket Protocol

Connecting

GET /api/agents/&lbrace;id&rbrace;/ws

Upgrades to a WebSocket connection for real-time bidirectional chat with an agent. Returns 400 if the agent ID is invalid, or 404 if the agent does not exist.

Message Format

All messages are JSON-encoded strings.

Client to Server

Send a message:

{
  "type": "message",
  "content": "What is the weather like?"
}

Plain text (non-JSON) is also accepted and treated as a message.

Chat commands (sent as messages with / prefix):

CommandDescription
/newStart a new session (clear history)
/compactTrigger LLM session compaction
/model <name>Switch the agent's model
/stopCancel current LLM run
/usageShow token usage and cost
/thinkToggle extended thinking mode
/modelsList available models
/providersList LLM providers and auth status

Ping:

{
  "type": "ping"
}

Server to Client

Connection confirmed (sent immediately on connect):

{
  "type": "connected",
  "agent_id": "a1b2c3d4-..."
}

Thinking indicator (sent when agent starts processing):

{
  "type": "thinking"
}

Text delta (streaming token, sent as the LLM generates output):

{
  "type": "text_delta",
  "content": "The weather"
}

Tool use started (sent when the agent invokes a tool):

{
  "type": "tool_start",
  "tool": "web_fetch"
}

Complete response (sent when agent finishes, contains final aggregated response):

{
  "type": "response",
  "content": "The weather today is sunny with a high of 72F.",
  "input_tokens": 245,
  "output_tokens": 32,
  "iterations": 2,
  "cost_usd": 0.0012
}

Error:

{
  "type": "error",
  "content": "Agent not found"
}

Agent list update (sent every 5 seconds with current agent states):

{
  "type": "agents_updated",
  "agents": [
    {
      "id": "a1b2c3d4-...",
      "name": "hello-world",
      "state": "Running",
      "model_provider": "groq",
      "model_name": "llama-3.3-70b-versatile"
    }
  ]
}

Pong (response to ping):

{
  "type": "pong"
}

Connection Lifecycle

  1. Client connects to ws://host:port/api/agents/&lbrace;id&rbrace;/ws.
  2. Server sends {"type": "connected"}.
  3. Client sends {"type": "message", "content": "..."}.
  4. Server sends {"type": "thinking"}, then zero or more {"type": "text_delta"} events, then {"type": "response"}.
  5. Server periodically sends {"type": "agents_updated"} every 5 seconds.
  6. Client sends a Close frame or disconnects to end the session.

SSE Streaming

POST /api/agents/{id}/message/stream

Send a message and receive the response as a Server-Sent Events stream. This enables real-time token-by-token streaming.

Request Body (JSON):

{
  "message": "Explain quantum computing"
}

SSE Event Stream:

event: chunk
data: {"content":"Quantum","done":false}

event: chunk
data: {"content":" computing","done":false}

event: chunk
data: {"content":" is a type","done":false}

event: tool_use
data: {"tool":"web_search"}

event: tool_result
data: {"tool":"web_search","input":{"query":"quantum computing basics"}}

event: done
data: {"done":true,"usage":{"input_tokens":150,"output_tokens":340}}

SSE Event Types

Event NameDescription
chunkText delta from the LLM. "done": false indicates more tokens are coming.
tool_useThe agent is invoking a tool. Contains the tool name.
tool_resultA tool invocation has completed. Contains the tool name and input.
doneFinal event. Contains "done": true and token usage statistics.

OpenAI-Compatible API

LibreFang exposes an OpenAI-compatible API for drop-in integration with tools that support the OpenAI API format (Cursor, Continue, Open WebUI, etc.).

POST /v1/chat/completions

Send a chat completion request using the OpenAI message format.

Request Body:

{
  "model": "librefang:coder",
  "messages": [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Hello!"}
  ],
  "stream": false,
  "temperature": 0.7,
  "max_tokens": 1024
}

Model resolution (the model field maps to an LibreFang agent):

FormatExampleBehavior
librefang:<name>librefang:coderFind agent by name
UUIDa1b2c3d4-...Find agent by ID
Plain stringcoderTry as agent name
Any othergpt-4oFalls back to first registered agent

Image support --- messages can include image content parts:

{
  "model": "librefang:analyst",
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "text", "text": "Describe this image"},
        {"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBOR..."}}
      ]
    }
  ]
}

Response (non-streaming) 200 OK:

{
  "id": "chatcmpl-a1b2c3d4-...",
  "object": "chat.completion",
  "created": 1708617600,
  "model": "coder",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Hello! How can I help you today?"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 25,
    "completion_tokens": 12,
    "total_tokens": 37
  }
}

Streaming --- Set "stream": true for SSE:

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":"Hello"},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":25,"completion_tokens":12,"total_tokens":37}}

data: [DONE]

GET /v1/models

List available models (agents) in OpenAI format.

Response 200 OK:

{
  "object": "list",
  "data": [
    {
      "id": "librefang:coder",
      "object": "model",
      "created": 1708617600,
      "owned_by": "librefang"
    },
    {
      "id": "librefang:researcher",
      "object": "model",
      "created": 1708617600,
      "owned_by": "librefang"
    }
  ]
}

Error Responses

All error responses use a consistent JSON format:

{
  "error": "Description of what went wrong"
}

HTTP Status Codes

CodeMeaning
200Success
201Created (spawn agent, create workflow, create trigger, install skill)
400Bad request (invalid UUID, missing required fields, malformed TOML/JSON)
401Unauthorized (missing or invalid Authorization: Bearer header)
404Not found (agent, workflow, trigger, template, model, skill, or KV key does not exist)
429Too many requests (GCRA rate limit exceeded)
500Internal server error (agent loop failure, database error, driver error)

Request IDs

Every response includes an x-request-id header with a UUID for tracing:

x-request-id: 550e8400-e29b-41d4-a716-446655440000

Use this value when reporting issues or correlating requests in logs.

Security Headers

Every response includes security headers:

HeaderValue
Content-Security-Policydefault-src 'self' (with appropriate directives)
X-Frame-OptionsDENY
X-Content-Type-Optionsnosniff
Strict-Transport-Securitymax-age=63072000; includeSubDomains
X-Request-IdUnique UUID per request

Rate Limiting

The GCRA (Generic Cell Rate Algorithm) rate limiter provides cost-aware token bucket rate limiting with per-IP tracking and automatic stale entry cleanup. Different endpoints consume different token costs (e.g., /api/agents/&lbrace;id&rbrace;/message costs more than /api/health). When the limit is exceeded, the server returns 429 Too Many Requests:

HTTP/1.1 429 Too Many Requests
Retry-After: 60

{"error": "Rate limit exceeded"}

The Retry-After header indicates the window duration in seconds.


Endpoint Summary

230+ endpoints total across 34 groups.

MethodPathDescription
System
GET/WebChat UI
GET/api/healthHealth check (no auth, redacted)
GET/api/health/detailFull health check (auth required)
GET/api/statusKernel status
GET/api/versionVersion info
POST/api/shutdownGraceful shutdown
GET/api/profilesList agent profiles
GET/api/profiles/{name}Get a specific profile
GET/api/toolsList available tools
GET/api/tools/{name}Get tool details
GET/api/metricsPrometheus metrics
GET/api/versionsAPI version discovery
GET/api/openapi.jsonOpenAPI specification
Config
GET/api/configConfiguration (secrets redacted)
GET/api/config/schemaConfig JSON Schema
POST/api/config/setSet a config value at runtime
POST/api/config/reloadReload config from disk
Agents
GET/api/agentsList agents
POST/api/agentsSpawn agent
POST/api/agents/bulkBulk create agents
DELETE/api/agents/bulkBulk delete agents
POST/api/agents/bulk/startBulk start agents
POST/api/agents/bulk/stopBulk stop agents
GET/api/agents/{id}Get agent details
DELETE/api/agents/{id}Kill agent
PATCH/api/agents/{id}Partial update agent
PUT/api/agents/{id}/updateFull update agent config
PUT/api/agents/{id}/modeSet agent mode (Stable/Normal)
PATCH/api/agents/{id}/identityUpdate agent identity
PATCH/api/agents/{id}/configPatch agent config
POST/api/agents/{id}/cloneClone agent
POST/api/agents/{id}/messageSend message (blocking)
POST/api/agents/{id}/message/streamSend message (SSE stream)
GET/api/agents/{id}/sessionGet current conversation history
GET/api/agents/{id}/sessionsList all agent sessions
POST/api/agents/{id}/sessionsCreate new session
POST/api/agents/{id}/sessions/{session_id}/switchSwitch active session
GET/api/agents/{id}/sessions/by-label/{label}Find session by label
DELETE/api/agents/{id}/historyClear conversation history
POST/api/agents/{id}/session/resetReset session
POST/api/agents/{id}/session/compactLLM-based compaction
POST/api/agents/{id}/stopCancel current run
PUT/api/agents/{id}/modelSwitch model
GET/api/agents/{id}/toolsGet agent tools
PUT/api/agents/{id}/toolsSet agent tools
GET/api/agents/{id}/skillsGet agent skills
PUT/api/agents/{id}/skillsSet agent skills
GET/api/agents/{id}/mcp_serversGet agent MCP servers
PUT/api/agents/{id}/mcp_serversSet agent MCP servers
GET/api/agents/{id}/tracesExecution traces
GET/api/agents/{id}/metricsAgent metrics
GET/api/agents/{id}/logsAgent log lines
GET/api/agents/{id}/deliveriesInbound deliveries
GET/api/agents/{id}/filesList workspace files
GET/api/agents/{id}/files/{filename}Get workspace file
PUT/api/agents/{id}/files/{filename}Set workspace file
DELETE/api/agents/{id}/files/{filename}Delete workspace file
POST/api/agents/{id}/uploadUpload file (multipart)
GET/api/uploads/{file_id}Retrieve uploaded file
GET/api/agents/{id}/wsWebSocket chat
GET/api/agents/{id}/memory/exportExport KV memory
POST/api/agents/{id}/memory/importImport KV memory
Workflows
GET/api/workflowsList workflows
POST/api/workflowsCreate workflow
GET/api/workflows/{id}Get workflow
PUT/api/workflows/{id}Update workflow
DELETE/api/workflows/{id}Delete workflow
POST/api/workflows/{id}/runRun workflow
GET/api/workflows/{id}/runsList workflow runs
Triggers
GET/api/triggersList triggers
POST/api/triggersCreate trigger
PUT/api/triggers/{id}Update trigger
DELETE/api/triggers/{id}Delete trigger
Schedules
GET/api/schedulesList schedules
POST/api/schedulesCreate schedule
GET/api/schedules/{id}Get schedule
PUT/api/schedules/{id}Update schedule
DELETE/api/schedules/{id}Delete schedule
POST/api/schedules/{id}/runRun schedule now
Memory (KV)
GET/api/memory/agents/{id}/kvList KV pairs
GET/api/memory/agents/{id}/kv/{key}Get KV value
PUT/api/memory/agents/{id}/kv/{key}Set KV value
DELETE/api/memory/agents/{id}/kv/{key}Delete KV value
Memory (Proactive)
GET/api/memoryList all proactive memories
POST/api/memoryAdd proactive memory
GET/api/memory/searchSearch memories (global)
GET/api/memory/statsMemory aggregate stats
POST/api/memory/cleanupRemove stale memories
POST/api/memory/decayApply time decay
POST/api/memory/bulk-deleteBulk delete memories
PUT/api/memory/items/{memory_id}Update memory entry
DELETE/api/memory/items/{memory_id}Delete memory entry
GET/api/memory/items/{memory_id}/historyMemory edit history
GET/api/memory/user/{user_id}Memories by user
GET/api/memory/agents/{id}Agent proactive memories
DELETE/api/memory/agents/{id}Clear agent memories
GET/api/memory/agents/{id}/searchSearch agent memories
GET/api/memory/agents/{id}/statsAgent memory stats
DELETE/api/memory/agents/{id}/level/{level}Clear memory by level
GET/api/memory/agents/{id}/duplicatesFind duplicate memories
POST/api/memory/agents/{id}/consolidateConsolidate memories
GET/api/memory/agents/{id}/countCount agent memories
GET/api/memory/agents/{id}/relationsQuery relations graph
POST/api/memory/agents/{id}/relationsStore relations
GET/api/memory/agents/{id}/exportExport agent memories
POST/api/memory/agents/{id}/importImport agent memories
Channels
GET/api/channelsList channels (44 adapters)
GET/api/channels/{name}Get channel config
POST/api/channels/{name}/configureConfigure channel
DELETE/api/channels/{name}/configureRemove channel config
POST/api/channels/{name}/testTest channel
POST/api/channels/reloadReload all channels
POST/api/channels/whatsapp/qr/startStart WhatsApp QR session
GET/api/channels/whatsapp/qr/statusWhatsApp QR status
Templates
GET/api/templatesList templates
GET/api/templates/{name}Get template
Sessions
GET/api/sessionsList all sessions
POST/api/sessions/cleanupCleanup orphaned sessions
GET/api/sessions/{id}Get session details
DELETE/api/sessions/{id}Delete session
PUT/api/sessions/{id}/labelLabel a session
Model Catalog
GET/api/modelsFull model catalog (130+ models)
GET/api/models/aliasesList model aliases
POST/api/models/aliasesCreate model alias
DELETE/api/models/aliases/{alias}Delete model alias
POST/api/models/customRegister custom model
DELETE/api/models/custom/{id}Remove custom model
GET/api/models/{id}Model details
GET/api/catalog/statusCatalog version and update info
POST/api/catalog/updateTrigger catalog update
Providers
GET/api/providersProvider list with auth status
GET/api/providers/ollama/detectAuto-detect Ollama
POST/api/providers/github-copilot/oauth/startStart Copilot OAuth
GET/api/providers/github-copilot/oauth/poll/{poll_id}Poll Copilot OAuth
GET/api/providers/{name}Get provider details
POST/api/providers/{name}/keySet provider API key
DELETE/api/providers/{name}/keyRemove provider API key
POST/api/providers/{name}/testTest provider connectivity
PUT/api/providers/{name}/urlOverride provider base URL
Skills & Marketplace
GET/api/skillsList installed skills (60 bundled)
POST/api/skills/installInstall skill
POST/api/skills/uninstallUninstall skill
POST/api/skills/createCreate new skill
GET/api/marketplace/searchSearch FangHub
ClawHub
GET/api/clawhub/searchSearch ClawHub
GET/api/clawhub/browseBrowse ClawHub
GET/api/clawhub/skill/{slug}Skill details
GET/api/clawhub/skill/{slug}/codeSkill source code
POST/api/clawhub/installInstall from ClawHub
Hands
GET/api/handsList hand definitions
POST/api/hands/installInstall a hand
GET/api/hands/activeList active hand instances
GET/api/hands/{hand_id}Get hand details
POST/api/hands/{hand_id}/activateActivate hand
POST/api/hands/{hand_id}/check-depsCheck hand dependencies
POST/api/hands/{hand_id}/install-depsInstall hand dependencies
GET/api/hands/{hand_id}/settingsGet hand settings
PUT/api/hands/{hand_id}/settingsUpdate hand settings
POST/api/hands/instances/{id}/pausePause hand instance
POST/api/hands/instances/{id}/resumeResume hand instance
DELETE/api/hands/instances/{id}Deactivate hand instance
GET/api/hands/instances/{id}/statsHand instance stats
GET/api/hands/instances/{id}/browserHand browser state
Extensions
GET/api/extensionsList extensions
GET/api/extensions/{name}Get extension
POST/api/extensions/installInstall extension
POST/api/extensions/uninstallUninstall extension
Plugins
GET/api/plugins/registriesList plugin registries
GET/api/pluginsList plugins
GET/api/plugins/{name}Get plugin
POST/api/plugins/installInstall plugin
POST/api/plugins/uninstallUninstall plugin
POST/api/plugins/scaffoldScaffold plugin
POST/api/plugins/{name}/install-depsInstall plugin deps
MCP (managed)
GET/api/mcp/serversMCP server connections
POST/api/mcp/serversAdd MCP server
GET/api/mcp/servers/{name}Get MCP server
PUT/api/mcp/servers/{name}Update MCP server
DELETE/api/mcp/servers/{name}Delete MCP server
A2A (external)
GET/api/a2a/agentsList external A2A agents
GET/api/a2a/agents/{id}Get external A2A agent
POST/api/a2a/discoverDiscover external A2A agent
POST/api/a2a/sendSend task to external A2A agent
GET/api/a2a/tasks/{id}/statusExternal A2A task status
MCP & A2A Protocol
POST/mcpMCP HTTP transport (JSON-RPC 2.0)
GET/.well-known/agent.jsonA2A agent card
GET/a2a/agentsA2A local agent list
POST/a2a/tasks/sendSend A2A task
GET/a2a/tasks/{id}Get A2A task status
POST/a2a/tasks/{id}/cancelCancel A2A task
Audit & Security
GET/api/audit/recentRecent audit logs
GET/api/audit/verifyVerify Merkle chain integrity
GET/api/securitySecurity status (16 systems)
GET/api/logs/streamSSE live log stream
Usage & Analytics
GET/api/usageUsage statistics
GET/api/usage/summaryUsage summary with quota
GET/api/usage/by-modelUsage by model breakdown
GET/api/usage/dailyDaily usage breakdown
Budget
GET/api/budgetGlobal budget status
PUT/api/budgetUpdate global budget
GET/api/budget/agentsAgent budget ranking
GET/api/budget/agents/{id}Agent budget details
PUT/api/budget/agents/{id}Set agent budget
Goals
GET/api/goalsList goals
POST/api/goalsCreate goal
GET/api/goals/{id}Get goal
PUT/api/goals/{id}Update goal
DELETE/api/goals/{id}Delete goal
GET/api/goals/{id}/childrenList sub-goals
Cron
GET/api/cron/jobsList cron jobs
POST/api/cron/jobsCreate cron job
GET/api/cron/jobs/{id}Get cron job
PUT/api/cron/jobs/{id}Update cron job
DELETE/api/cron/jobs/{id}Delete cron job
PUT/api/cron/jobs/{id}/enableToggle cron job
GET/api/cron/jobs/{id}/statusCron job status
Webhooks
GET/api/webhooks/eventsList event webhook subscriptions
POST/api/webhooks/eventsCreate event webhook
PUT/api/webhooks/events/{id}Update event webhook
DELETE/api/webhooks/events/{id}Delete event webhook
GET/api/webhooksList outbound webhooks
POST/api/webhooksCreate outbound webhook
GET/api/webhooks/{id}Get outbound webhook
PUT/api/webhooks/{id}Update outbound webhook
DELETE/api/webhooks/{id}Delete outbound webhook
POST/api/webhooks/{id}/testTest outbound webhook
POST/api/hooks/wakeWake trigger (unversioned)
POST/api/hooks/agentAgent trigger (unversioned)
Backup & Restore
POST/api/backupCreate backup
GET/api/backupsList backups
DELETE/api/backups/{filename}Delete backup
POST/api/restoreRestore from backup
Integrations
GET/api/integrationsList integrations
GET/api/integrations/availableAvailable integrations
GET/api/integrations/healthIntegrations health
POST/api/integrations/addAdd integration
POST/api/integrations/reloadReload integrations
GET/api/integrations/{id}Get integration
DELETE/api/integrations/{id}Remove integration
POST/api/integrations/{id}/reconnectReconnect integration
Pairing
POST/api/pairing/requestInitiate pairing
POST/api/pairing/completeComplete pairing
POST/api/pairing/notifyNotify paired devices
GET/api/pairing/devicesList paired devices
DELETE/api/pairing/devices/{id}Remove paired device
OAuth / OIDC
GET/api/auth/providersList OAuth providers
GET/api/auth/loginRedirect to default OAuth login
GET/api/auth/login/{provider}Redirect to specific OAuth login
GET/api/auth/callbackOAuth callback (GET)
POST/api/auth/callbackOAuth callback (POST)
GET/api/auth/userinfoOIDC user info
POST/api/auth/introspectToken introspection
Task Queue
GET/api/tasks/statusTask queue summary
GET/api/tasks/listList queued tasks
DELETE/api/tasks/{id}Cancel queued task
POST/api/tasks/{id}/retryRetry failed task
GET/api/queue/statusQueue depth and throughput
Comms
GET/api/comms/topologyCommunication topology
GET/api/comms/eventsRecent comms events
GET/api/comms/events/streamSSE comms event stream
POST/api/comms/sendSend via comms layer
POST/api/comms/taskDispatch comms task
Approvals
GET/api/approvalsList approval requests
POST/api/approvalsCreate approval request
GET/api/approvals/{id}Get approval request
POST/api/approvals/{id}/approveApprove request
POST/api/approvals/{id}/rejectReject request
Bindings & Commands
GET/api/bindingsList UI bindings
POST/api/bindingsAdd binding
DELETE/api/bindings/{index}Remove binding
GET/api/commandsList slash commands
GET/api/commands/{name}Get slash command
Network & Peers
GET/api/peersList OFP peers
GET/api/peers/{id}Get OFP peer
GET/api/network/statusOFP network status
Migration
GET/api/migrate/detectDetect migration sources
POST/api/migrate/scanScan for importable data
POST/api/migrateRun migration
OpenAI Compatible
POST/v1/chat/completionsOpenAI-compatible chat
GET/v1/modelsOpenAI-compatible model list