MCP Server
The @curate-me/mcp-server package exposes Curate-Me platform governance capabilities as Model Context Protocol (MCP) tools. It runs inside runner containers alongside OpenClaw agents, giving them self-awareness about budgets, fleet peers, session memory, and the ability to communicate with other agents.
Overview
When an OpenClaw agent runs inside a Curate-Me managed runner, the MCP server provides 21 tools across two tiers:
- Tier 1 — Foundation (16 tools): Budget, status, events, skills, peers, A2A, approvals, health, session memory, memory search, desktop screenshots, timeline recording, credentials, extended thinking, and session recordings
- Tier 2 — Collaboration (5 tools): Subagent spawning, agent handoff, fleet messaging, task dispatch, and conversation persistence
OpenClaw Agent → MCP Server (stdio) → Gateway REST API → Control PlaneInstallation
The MCP server is pre-installed in all Curate-Me runner container images. For manual installation:
npm install -g @curate-me/mcp-serverConfiguration
The MCP server reads configuration from environment variables, automatically injected into runner containers at startup:
| Variable | Description | Default |
|---|---|---|
CM_API_KEY | Runner auth token (cm_rt_...), auto-issued at session start | Auto-injected |
CM_GATEWAY_URL | Gateway URL | http://localhost:8002 |
CM_RUNNER_ID | This runner’s ID | Auto-detected |
CM_SESSION_ID | Active session ID | Auto-detected |
CM_ORG_ID | Organization ID | From API key |
CM_FLEET_ID | Fleet ID (if in a fleet) | Optional |
OpenClaw Configuration
Add the MCP server to your OpenClaw config’s MCP server list:
{
"mcpServers": {
"curate-me": {
"command": "curate-me-mcp",
"args": []
}
}
}Tier 1: Foundation Tools (16)
curate_check_budget
Check remaining daily LLM budget for this organization. Returns current spend, daily limit, remaining budget, request count, and whether budget is exceeded.
curate_get_status
Get this runner’s current status including state, resource usage, installed skills, and active session info.
| Parameter | Type | Description |
|---|---|---|
runner_id | string | Runner ID (defaults to CM_RUNNER_ID) |
curate_emit_event
Emit an audit event to the control plane. Events are recorded in the immutable audit trail and visible in the dashboard.
| Parameter | Type | Required | Description |
|---|---|---|---|
event_type | string | Yes | Event type (e.g. task_completed, error_encountered) |
detail | object | No | Event payload with contextual data |
curate_install_skill
Install a skill pack on this runner. Skill packs provide additional capabilities (MCP servers, tools, integrations).
| Parameter | Type | Required | Description |
|---|---|---|---|
skill_pack_id | string | Yes | Skill pack ID (e.g. spack_mcp_integrations) |
curate_list_skills
List all available skill packs in the gallery, or list skills installed on this runner.
| Parameter | Type | Description |
|---|---|---|
installed_only | boolean | If true, show only installed skills (default: false) |
curate_discover_peers
Discover other runners in the fleet. Returns online peers with their capabilities and current workload.
| Parameter | Type | Description |
|---|---|---|
state_filter | string | Filter by state: online, busy, all (default: online) |
curate_send_a2a_task
Send a task to another agent via the A2A (Agent-to-Agent) protocol. The task goes through governance checks (rate limits, PII scanning, cost caps).
| Parameter | Type | Required | Description |
|---|---|---|---|
to_agent | string | Yes | Target agent ID |
content | string | Yes | Task content/instructions |
priority | string | No | low, normal, high, urgent (default: normal) |
curate_request_approval
Request human-in-the-loop (HITL) approval before proceeding with a sensitive action. Creates an approval request in the dashboard queue.
| Parameter | Type | Required | Description |
|---|---|---|---|
action_type | string | Yes | Type of action (e.g. deploy, delete_data) |
description | string | Yes | Human-readable description of the action |
estimated_cost_usd | number | No | Estimated cost in USD |
curate_gateway_health
Check the health of the Curate-Me gateway and connected services. No parameters required.
curate_session_memory
Restore context from prior runner sessions. Returns conversation summaries, key findings, and carried-forward data from previous runs. Enables stateful multi-run workflows.
| Parameter | Type | Description |
|---|---|---|
runner_id | string | Runner ID (defaults to CM_RUNNER_ID) |
template_id | string | Filter memories by template ID |
limit | integer | Number of memories to retrieve (default 10, max 100) |
curate_memory_search
Search across all runner session memories for relevant context. Enables knowledge retrieval from past executions across the fleet.
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search query (e.g. customer complaints, pricing) |
runner_id | string | No | Filter to specific runner |
limit | integer | No | Number of results (default 20, max 100) |
curate_desktop_screenshot
Capture a screenshot of the runner’s desktop for visual debugging. Returns base64-encoded image data.
| Parameter | Type | Description |
|---|---|---|
runner_id | string | Runner ID (defaults to CM_RUNNER_ID) |
session_id | string | Session ID (defaults to CM_SESSION_ID) |
curate_timeline_record
Record an event into the session timeline for time-travel debugging. Enables replay and inspection of agent execution in the dashboard.
| Parameter | Type | Required | Description |
|---|---|---|---|
event_type | string | Yes | Event type (e.g. function_call, decision, error) |
duration_ms | integer | No | Duration in milliseconds |
input_data | object | No | Input to the event |
output_data | object | No | Output from the event |
cost_usd | number | No | Cost of this operation |
metadata | object | No | Additional context |
curate_credential_store
Store, list, or delete credentials in the encrypted credential vault.
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | Yes | store, list, or delete |
name | string | For store | Credential name |
credential_type | string | No | api_key, service_token, password (default: api_key) |
provider_hint | string | No | Provider context (e.g. stripe, postgres) |
value | string | For store | Secret value to encrypt |
credential_id | string | For delete | Credential ID to delete |
curate_extended_thinking
Get, set, or check usage of extended thinking configuration.
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | Yes | get, set, or usage |
budget_tokens | integer | For set | Max tokens for thinking |
cost_warning_threshold_usd | number | For set | Cost warning threshold |
curate_recording_save
Save or list session recordings (rrweb events) for visual replay.
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | Yes | save or list |
recording_data | object | For save | Recording data to save |
runner_id | string | No | Runner ID (defaults to CM_RUNNER_ID) |
session_id | string | No | Session ID (defaults to CM_SESSION_ID) |
Tier 2: Collaboration Tools (5)
curate_subagent_spawn
Create, list, or view policy for subagent specs. Each subagent has its own model, tools, cost limit, and conversation budget.
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | Yes | create, list, or policy |
name | string | For create | Subagent name |
agent_type | string | No | task, workflow, chat (default: task) |
model | string | No | Model for subagent |
allowed_tools | array | No | Tool IDs the subagent can use |
max_turns | integer | No | Max conversation turns |
cost_limit_usd | number | No | Cost budget for this subagent |
description | string | No | What this subagent does |
curate_agent_handoff
Hand off work from this agent to another with full context (findings, artifacts, instructions). Enables multi-step workflow pipelines.
| Parameter | Type | Required | Description |
|---|---|---|---|
to_agent | string | Yes | Target agent/runner ID |
summary | string | Yes | Summary of work completed |
findings | array | No | Key findings as list of strings |
artifacts | array | No | Output file paths to pass along |
instructions | string | No | Instructions for receiving agent |
priority | string | No | low, normal, high, urgent |
curate_fleet_message
Send a message to other agents in the fleet. Supports broadcast to all agents or direct messaging.
| Parameter | Type | Required | Description |
|---|---|---|---|
content | string | Yes | Message content |
fleet_id | string | No | Fleet ID (defaults to CM_FLEET_ID) |
agent_id | string | No | Target agent for direct message |
broadcast | boolean | No | If true, broadcast to all agents |
curate_task_dispatch
Poll for dispatched tasks from the dashboard or report task completion.
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | Yes | poll or report |
task_id | string | For report | Task ID to report on |
result | string | For report | Result/output of the task |
status | string | For report | completed, failed, in_progress |
curate_conversation
Store or retrieve conversation entries for audit trail and context continuity.
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | Yes | save or get |
entry_type | string | For save | user_message, bot_message, vm_action, system_event |
content | string | For save | Entry content |
metadata | object | No | Optional metadata |
limit | integer | For get | Number of entries (default 50) |
Usage Examples
Budget-Aware Agent
// Check budget before expensive operation
const budget = await mcp.call("curate_check_budget");
if (budget.budget_exceeded) {
await mcp.call("curate_emit_event", {
event_type: "budget_exceeded",
detail: { action: "skipped_expensive_analysis" }
});
return "Budget exceeded - deferring to next cycle";
}Stateful Multi-Run Agent
// Restore context from prior session
const memories = await mcp.call("curate_session_memory", {
template_id: "daily_report",
limit: 1
});
// Search for specific knowledge
const insights = await mcp.call("curate_memory_search", {
query: "customer objections pricing"
});
// Record decisions in timeline
await mcp.call("curate_timeline_record", {
event_type: "decision",
input_data: { context: "Found 3 prior insights" },
output_data: { decision: "Using revised pricing strategy" }
});Fleet Collaboration
// Discover peers
const peers = await mcp.call("curate_discover_peers", { state_filter: "online" });
// Delegate sub-task
await mcp.call("curate_send_a2a_task", {
to_agent: peers[0].runner_id,
content: "Analyze the uploaded CSV and generate a summary report",
priority: "normal"
});
// Broadcast learning to fleet
await mcp.call("curate_fleet_message", {
content: "Found that CSV headers must be normalized before processing",
broadcast: true
});Multi-Step Workflow Pipeline
// Agent A completes analysis, hands off to Agent B
await mcp.call("curate_agent_handoff", {
to_agent: "runner_compliance_reviewer",
summary: "Completed financial analysis for Q4",
findings: ["Revenue up 15%", "Costs down 8%", "New market opportunity in APAC"],
artifacts: ["/workspace/q4_analysis.pdf", "/workspace/charts.xlsx"],
instructions: "Review for regulatory compliance before publishing"
});Secure Credential Management
// Store API key securely
await mcp.call("curate_credential_store", {
action: "store",
name: "stripe_api_key",
credential_type: "api_key",
provider_hint: "stripe",
value: "sk_live_xxx"
});
// List stored credentials
const creds = await mcp.call("curate_credential_store", { action: "list" });HITL for Sensitive Operations
// Request approval before destructive action
await mcp.call("curate_request_approval", {
action_type: "delete_data",
description: "Delete 1,247 stale user records older than 2 years",
estimated_cost_usd: 0
});Architecture
┌─────────────────────────────────────────┐
│ Runner Container │
│ │
│ ┌──────────┐ ┌──────────────────┐ │
│ │ OpenClaw │────→│ MCP Server │ │
│ │ Agent │stdio│ (21 tools) │ │
│ └──────────┘ └────────┬─────────┘ │
│ │ HTTP │
└────────────────────────────┼────────────┘
│
┌────────▼────────┐
│ Gateway :8002 │
│ (governance │
│ chain + proxy) │
└────────┬────────┘
│
┌────────▼────────┐
│ Control Plane │
│ (MongoDB + │
│ Redis) │
└─────────────────┘Tool Categories
| Category | Tools | Purpose |
|---|---|---|
| Governance | check_budget, request_approval, gateway_health | Cost control + safety gates |
| Status | get_status, emit_event | Runner awareness + audit trail |
| Skills | install_skill, list_skills | Dynamic capability management |
| Fleet | discover_peers, send_a2a_task, fleet_message | Multi-agent coordination |
| Memory | session_memory, memory_search, conversation | Stateful execution + knowledge |
| Debugging | desktop_screenshot, timeline_record, recording_save | Visual + time-travel debugging |
| Security | credential_store | Encrypted secret management |
| Config | extended_thinking, subagent_spawn | Runtime optimization |
| Workflow | agent_handoff, task_dispatch | Pipeline orchestration |
Development
cd packages/mcp-server
# Install dependencies
npm install
# Run the server (for testing)
npm start
# Development with auto-reload
npm run devTesting MCP Tools Locally
# Start the gateway first
cd services/backend
poetry run uvicorn src.main_gateway:app --reload --port 8002
# Test the MCP server — list all tools
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | node packages/mcp-server/src/index.js
# Call a specific tool
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"curate_gateway_health","arguments":{}}}' | CM_GATEWAY_URL=http://localhost:8002 node packages/mcp-server/src/index.jsRelated
- CLI Reference - Command-line tool also installed in containers
- Managed Runners - Runner container lifecycle and management
- AI Gateway - The governance proxy that MCP tools communicate with