MCP Server — Signet Docs

Docs / Reference

MCP Server

Model Context Protocol integration for native tool access.

MCP Server

The Signet Daemon exposes an MCP (Model Context Protocol) server that gives AI Harnesses native tool access to Memory operations. Instead of relying on shell commands or skill invocations, harnesses call Signet tools directly through MCP’s standardized interface.

Overview

MCP complements Signet’s existing hook-based integration:

  • Hooks handle lifecycle events (session start/end, prompt submission, compaction). They run automatically.
  • MCP tools provide on-demand operations (search, store, modify, forget). The agent invokes them when needed.

Both systems can be active simultaneously — they serve different purposes and don’t conflict.

When to Use MCP vs Hooks

ScenarioUse
Session start/end lifecycleHooks
Automatic memory extraction after each promptHooks
Agent wants to search memories mid-conversationMCP (memory_search)
Agent wants to store a specific factMCP (memory_store)
Agent needs to run a command with secretsMCP (secret_exec)
Compaction boundary handlingHooks
Agent-initiated memory edits or deletionsMCP (memory_modify, memory_forget)

Rule of thumb: hooks are for automatic, lifecycle-driven events. MCP is for agent-initiated, on-demand operations.

Tool Reference

All tools are defined in packages/daemon/src/mcp/tools.ts. Tool handlers call the daemon’s HTTP API internally — they don’t duplicate business logic.

Hybrid vector + keyword search over stored memories. Returns results ranked by combined BM25 + vector similarity score with optional graph boost and reranking.

Parameters:

NameTypeRequiredDescription
querystringyesSearch query text
limitnumbernoMax results to return (default 10)
typestringnoFilter by memory type (e.g. "preference", "fact")
min_scorenumbernoMinimum relevance score threshold

Returns: Array of memory objects with content, type, importance, tags, and relevance score.

Example:

{
  "query": "user prefers dark mode",
  "limit": 5,
  "type": "preference"
}

Daemon endpoint: POST /api/memory/recall

memory_store

Save a new memory to the database. Tags are prepended in [tag1,tag2]: format before being sent to the daemon.

Parameters:

NameTypeRequiredDescription
contentstringyesMemory content to save
typestringnoMemory type (fact, preference, decision, etc.)
importancenumbernoImportance score 0–1
tagsstringnoComma-separated tags for categorization

Returns: The created memory object with its assigned ID.

Example:

{
  "content": "User prefers Bun over npm for package management",
  "importance": 0.8,
  "tags": "preference,tooling"
}

Daemon endpoint: POST /api/memory/remember

memory_get

Retrieve a single memory by its ID.

Parameters:

NameTypeRequiredDescription
idstringyesMemory ID to retrieve

Returns: Full memory object including content, type, importance, tags, created/updated timestamps, and version history.

Example:

{
  "id": "a1b2c3d4-..."
}

Daemon endpoint: GET /api/memory/:id

memory_list

List memories with optional pagination and type filtering.

Parameters:

NameTypeRequiredDescription
limitnumbernoMax results (default 100)
offsetnumbernoPagination offset
typestringnoFilter by memory type

Returns: Array of memory objects.

Example:

{
  "limit": 20,
  "offset": 0,
  "type": "decision"
}

Daemon endpoint: GET /api/memories

memory_modify

Edit an existing memory. Requires a reason for the edit (used for version history tracking).

Parameters:

NameTypeRequiredDescription
idstringyesMemory ID to modify
reasonstringyesWhy this edit is being made
contentstringnoNew content
typestringnoNew type
importancenumbernoNew importance
tagsstringnoNew tags (comma-separated)

Returns: Updated memory object.

Example:

{
  "id": "a1b2c3d4-...",
  "content": "User prefers Bun for all JS projects",
  "reason": "Updated to reflect broader preference"
}

Daemon endpoint: PATCH /api/memory/:id

memory_forget

Soft-delete a memory. The memory is not physically removed — it’s marked as forgotten with a reason for auditability.

Parameters:

NameTypeRequiredDescription
idstringyesMemory ID to forget
reasonstringyesWhy this memory should be forgotten

Returns: Confirmation of deletion.

Example:

{
  "id": "a1b2c3d4-...",
  "reason": "User corrected this preference"
}

Daemon endpoint: DELETE /api/memory/:id

memory_feedback

Rate how relevant injected memories were to the current conversation. Scores update session_memories.relevance_score immediately, feeding the predictor scorer’s training pipeline and the aspect feedback loop.

Parameters:

NameTypeRequiredDescription
session_keystringyesCurrent session key
ratingsobjectyesMap of memory ID to relevance score (−1 to 1)

Score interpretation: 1 = directly helpful, 0 = unused/neutral, −1 = harmful or misleading.

Returns: Object with ok: true and recorded count.

Example:

{
  "session_key": "abc123",
  "ratings": {
    "a1b2c3d4-e5f6-...": 0.9,
    "b2c3d4e5-f6a7-...": 0.0,
    "c3d4e5f6-a7b8-...": -0.5
  }
}

Daemon endpoint: POST /api/memory/feedback

Note: Prefer this tool over embedding feedback as raw JSON text. Both are supported for backward compatibility, but the MCP tool is recorded immediately on the current turn.

agent_peers

List currently active peer sessions for cross-agent coordination.

Parameters:

NameTypeRequiredDescription
agent_idstringnoCurrent agent id (default default)
session_keystringnoCurrent session key (used to exclude self session)
include_selfbooleannoInclude this agent’s sessions (default false)
projectstringnoOptional project filter
limitnumbernoMax sessions to return

Returns: Object with sessions array and count.

Daemon endpoint: GET /api/cross-agent/presence

agent_message_send

Send a message to another agent/session or broadcast to all active peers. Supports local daemon delivery and optional ACP relay.

Parameters:

NameTypeRequiredDescription
contentstringyesMessage body
from_agent_idstringnoSender agent id
from_session_keystringnoSender session key
to_agent_idstringnoTarget agent id
to_session_keystringnoTarget session key
broadcastbooleannoBroadcast to all sessions
typeenumnoassist_request, decision_update, info, question
viaenumnolocal (default) or acp
acp_base_urlstringnoACP server URL (required if via=acp)
acp_target_agent_namestringnoACP target agent name (required if via=acp)
acp_timeout_msnumbernoACP relay timeout in milliseconds (used when via=acp)

Returns: Stored message object including delivery status.

Daemon endpoint: POST /api/cross-agent/messages

agent_message_inbox

Read recent inbound cross-agent messages for an agent/session.

Parameters:

NameTypeRequiredDescription
agent_idstringnoRecipient agent id (default default)
session_keystringnoRecipient session key
sincestringnoISO timestamp lower bound
limitnumbernoMax messages to return
include_sentbooleannoInclude messages sent by this agent
include_broadcastbooleannoInclude broadcast messages

Returns: Object with items array and count.

Daemon endpoint: GET /api/cross-agent/messages

session_bypass

Toggle per-session hook bypass. When enabled, all hook endpoints for the target session return empty no-op responses with bypassed: true. MCP tools (memory_search, memory_store, etc.) continue to work normally — only automatic hooks are silenced.

Parameters:

NameTypeRequiredDescription
session_keystringyesSession key to toggle bypass for
enabledbooleanyestrue to enable bypass, false to disable

Returns: Object with key and bypassed fields confirming the new state.

Example:

{
  "session_key": "session-uuid",
  "enabled": true
}

Daemon endpoint: POST /api/sessions/:key/bypass

secret_list

List available secret names. Returns names only — raw secret values are never exposed to agents.

Parameters: None.

Returns: Object with a secrets array of string names.

Example:

{}

Daemon endpoint: GET /api/secrets

secret_exec

Run a shell command with secrets injected as environment variables. Output is automatically redacted — secret values never appear in results.

Parameters:

NameTypeRequiredDescription
commandstringyesShell command to execute
secretsobjectyesMap of env var name to secret reference (Signet name or op://...)

Returns: Object with stdout, stderr, and code (exit code). Secret values in output are replaced with [REDACTED].

Example:

{
  "command": "curl -H \"Authorization: Bearer $OPENAI_API_KEY\" https://api.openai.com/v1/models",
  "secrets": {
    "OPENAI_API_KEY": "OPENAI_API_KEY"
  }
}

Daemon endpoint: POST /api/secrets/exec (30s timeout)

Discovery Protocol

AI harnesses discover Signet’s MCP server in one of two ways:

Automatic (via signet install)

The connector for each harness registers the MCP server in the harness’s configuration file during installation. No manual steps needed.

Manual discovery

  1. The daemon must be running (signet daemon start)
  2. The MCP server is available at:
    • Streamable HTTP: http://localhost:3850/mcp
    • stdio: spawn the signet-mcp binary as a subprocess
  3. The daemon port can be overridden via SIGNET_PORT (default: 3850)
  4. The daemon host can be overridden via SIGNET_HOST (default: localhost)

Clients can verify the server is reachable with the MCP initialize handshake:

echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","clientInfo":{"name":"test","version":"1.0"},"capabilities":{}},"id":1}' | signet-mcp

Transports

The MCP server supports two transports:

Streamable HTTP

Embedded in the daemon’s Hono server at /mcp. Uses the web-standard Streamable HTTP transport (MCP spec 2025-03-26). Runs stateless — each request gets a fresh server instance.

POST http://localhost:3850/mcp     # Send MCP messages
GET  http://localhost:3850/mcp     # SSE stream (server notifications)
DELETE http://localhost:3850/mcp   # Session termination (no-op, stateless)

stdio

The signet-mcp binary runs as a subprocess, reading JSON-RPC from stdin and writing to stdout. The daemon must be running — tool handlers call the daemon’s HTTP API internally.

signet-mcp

Environment variables:

SIGNET_DAEMON_URL   # Override daemon URL (default: http://localhost:3850)
SIGNET_HOST         # Override daemon host (default: localhost)
SIGNET_PORT         # Override daemon port (default: 3850)

Configuration per Harness

Claude Code

The Claude Code connector registers the MCP server in ~/.claude/settings.json during signet install:

{
  "mcpServers": {
    "signet": {
      "type": "stdio",
      "command": "signet-mcp",
      "args": []
    }
  }
}

OpenCode

The OpenCode connector registers the MCP server in ~/.config/opencode/opencode.json during signet install:

{
  "mcp": {
    "signet": {
      "type": "local",
      "command": ["signet-mcp"],
      "enabled": true
    }
  }
}

This coexists with the plugin (plugins/signet.mjs) — the plugin handles lifecycle hooks, MCP handles on-demand tool calls.

OpenClaw

OpenClaw uses the @signetai/adapter-openclaw runtime plugin, which already provides the same tool surface. MCP registration will be added when OpenClaw supports native mcpServers configuration.

Manual Setup

If you don’t use signet install, you can configure MCP manually:

  1. Ensure the daemon is running: signet daemon start
  2. Add the MCP server to your harness config (see examples above)
  3. Verify connectivity: echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","clientInfo":{"name":"test","version":"1.0"},"capabilities":{}},"id":1}' | signet-mcp

Authentication

MCP connections inherit the daemon’s auth model:

  • local (default): No authentication required.
  • team: Streamable HTTP requests require a Bearer token. The stdio bridge runs locally and connects to the daemon with the same auth context.
  • hybrid: Localhost requests (including MCP) are trusted; remote requests require a token.

Internals

The MCP tool handlers use a shared daemonFetch helper that sends HTTP requests to the daemon API with these headers:

  • x-signet-runtime-path: plugin — identifies this as a plugin-path request
  • x-signet-actor: mcp-server — identifies the calling actor
  • x-signet-actor-type: harness — actor type classification

The default request timeout is 10 seconds, except for secret_exec which uses 30 seconds to allow for longer-running commands.

Errors are returned as MCP error results with isError: true and a human-readable message.

Roadmap

Phase 2 tool candidates (not yet implemented):

  • secret_get — retrieve a secret value
  • skill_list — list installed skills
  • diagnostics — health score summary
  • config_read — read agent config
  • document_ingest — ingest a document