Skip to main content
Glama
roaming-panda-llc

rp-herdr-core-mcp

Official

rp-herdr-core-mcp

A small single-user MCP adapter for herdr-core 0.1.15, using the official MCP SDK. Version 0.1.3. MIT licensed. macOS/Linux; no Windows pipe support.

Three tools expose existing local terminals: list_sessions, read_output, and send_prompt. No extra LLM, agent spawning, shell-execution tool, or core lifecycle management. The adapter uses an existing Unix socket and never starts, stops or updates hc. Output is untrusted data and may contain secrets.

Quick start

Use Node.js 22+ and an existing hc 0.1.15 installation:

npm ci --ignore-scripts
npm run check
npm run test:integration

Copy examples/config.stdio.json to a private location outside the repository, set the actual absolute socketPath, and keep sendAllowlist: [] initially. The example path is not discovery: HC_SOCKET, hc config, XDG directories and the selected session can change the endpoint. Do not move core state or replace sockets.

node scripts/inspect-core.js /absolute/private/config.json

This read-only probe prints core ID and terminal lifetime metadata. Configure your MCP host using examples/mcp.json, replacing all absolute paths. Run Node directly for stdio, not npm, so package-manager output cannot pollute protocol stdout. Discover the tools and verify list/screen reads before enabling writes. See AGENT-HANDOFF.md for migration and verification.

Related MCP server: wingman

Tools and bounds

  • list_sessions: local terminal records, optionally finished, paginated at 25 by default (maximum 100). Non-atomic snapshot; no reconstructed chat history.

  • read_output: current screen only, last 12,000 characters by default (maximum 32,768), with truncation/completeness flags. Always lines: 0: hc history stitching can inject scrolling input, so it is deliberately not exposed.

  • send_prompt: paste text and submit using the terminal's configured key (Enter by default). Maximum 16,000 characters; terminal control characters rejected. Never force, never waits for task completion, never automatically retries.

Core connections are capped at eight, received bytes at 1 MiB per call, and timeout at 15 seconds by default (configurable 100–60,000 ms). Large upstream lists can exceed the byte limit before pagination; this fails explicitly. The adapter checks JSON-RPC IDs and reply shape, generation 1, plain framing, and exact version 0.1.15. Shutdown closes adapter connections only; existing terminals continue.

Approving writes and send modes

Sending requires an operator-approved terminal address and creation timestamp plus the actual core ID from the probe. Keep private config outside Git. Example:

{
  "socketPath": "/absolute/private/existing.sock",
  "transport": "stdio",
  "coreId": "COPY-ACTUAL-CORE-ID",
  "sendMode": "normal",
  "sendAllowlist": [{ "address": "t1b", "created_ms": 1234567890000 }]
}

sendMode is operator configuration, not a caller-controlled tool argument:

Mode

Behavior

idle-only (default)

Existing behavior: always sends with core's atomic if: "idle" check. A done terminal is rejected.

normal (opt-in)

Preflight must report idle or done; working, blocked, error and unknown states are rejected before dispatch. Idle retains if: "idle"; done uses hc's documented normal send with no if, still force:false.

Normal mode is not an atomic idle-or-done guarantee. hc 0.1.15 only accepts idle or working in if; done is not expressible. After a done preflight the program may become working before input arrives. Core serializes input, waits for keyboard quiet and refuses blocked programs, but does not wait for task completion. Normal-mode approval accepts that race. Results expose send_mode, preflight_status, and atomic_status_guard (null when absent), as well as core's observed send status. No false idle report, interruption, forced send or core fork is used. Pi normally reports done after successful work, so idle-only is too restrictive for that follow-up workflow.

Only approve dedicated trusted agent terminals. Core ID and creation timestamp checks mitigate stale-ID reuse, but do not authenticate the executable. OSC 7501 status is self-reported; a terminal's foreground program can change. A prompt can cause the downstream agent to execute commands or change files. Approval grants that program's effective authority; never repurpose an approved terminal as a shell.

Read before each consequential follow-up. A successful send is not task completion. The exact validated core status_mismatch rejection (-32000, after the pinned handshake) is labeled NOT SENT because core rejects it before input writes. Other post-dispatch errors/timeouts remain conservatively UNKNOWN. Neither classification triggers automatic replay; inspect and make a fresh decision. Cancellation during preflight prevents a subsequent send; cancellation after submission cannot undo terminal input.

Optional authenticated HTTP

examples/config.http.json enables stateless MCP Streamable HTTP at /mcp, bound only to 127.0.0.1. Supply a private HERDR_MCP_TOKEN of at least 32 high-entropy bytes through your existing secret environment; missing or placeholder credentials fail startup closed. No credential is generated or included by this project.

Remote use requires operator-managed HTTPS proxy/private transport. Preserve Authorization and configured Host; reject untrusted forwarding headers, disable sensitive logging/caching, and apply connection/rate limits. Never expose raw hc sockets or a plaintext public listener. Every /mcp request requires bearer auth; Host/Origin validation runs first and request bodies are capped at 64 KiB.

Only exact GET/HEAD probes to /.well-known/oauth-protected-resource/mcp and /.well-known/oauth-protected-resource return unauthenticated 404, without a challenge: the documents are unsupported. Other paths/methods remain protected.

This is not an OAuth authorization server. A client choosing “No authentication” will not supply HTTP bearer credentials. Clients requiring OAuth need a separately configured compatible gateway; never remove auth to work around incompatibility. An authenticated tunnel that owns a local stdio process is an alternative only if its access controls are independently verified. Stdio uses process access instead of HTTP bearer auth; it does not authorize an unprotected public HTTP endpoint.

Verification and provenance

See VALIDATION.md for performed checks and limitations and PATCH-NOTES.md for changes. No deployment or live integration is implied by passing mocked tests.

Verified core contract: tag v0.1.15, commit 9e934dff8513710d3c5111fe28bc5b23564805db:

The adapter does not depend on oldherdrTUI. Review and test source/schema changes before relaxing the pinned core version guard.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables users to drive visible terminals in a locally running Termius desktop app by creating, sending to, reading from, resizing, and closing local terminals or existing SSH sessions through MCP tools.
    ISC
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP hosts to connect to local Codex sessions for listing, reading, messaging, and interrupting them without hijacking the terminal.
    1
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Enables MCP clients to remotely control a running Herdr session: see agent status, arrange tabs and panes, start and prompt coding agents, and run worktree-isolated jobs over stdio or Streamable HTTP. Includes policy controls such as allowlists, read-only mode, disabled tools, and an audit log.
    32
    2
    MIT