Documentation

Worker API

Unix HTTP API from MCP tools to Telegram.

MCP tools run inside (or beside) the agent process and must not hold the Telegram bot token. They call the acpbot worker over HTTP on a Unix socket; the worker owns the token and session → topic map.

Socket

Default path$state_dir/worker-api.sock (from config.toml / state_dir)
OverrideACPBOT_WORKER_API_SOCK (absolute preferred)
ServerWorker daemon (src/core/worker-api-server.ts)
ClientHost MCP (src/mcp/worker-api.ts)

Boot log includes something like:

acpbot worker API: unix:///…/worker-api.sock

Endpoints (HTTP over Unix)

All bodies are JSON. Responses are JSON { ok: true, … } or { ok: false, error: "…" }.

Method / pathBodyEffect
POST /v1/telegram/messagesessionKey, text, optional kind (update | message)kind=update → edit (or create) the live working bubble; kind=message → new permanent message
POST /v1/telegram/photosessionKey, path, optional caption, filenamesendPhoto
POST /v1/telegram/documentsessionKey, path, optional caption, filenamesendDocument
POST /v1/telegram/speaksessionKey, textTTS + sendVoice
GET /v1/healthLiveness

Exact path strings are defined in src/mcp/worker-api.ts / the server; MCP tool wrappers hide them from agents.

The working bubble is owned by the worker (posted at turn start, deleted at turn end). Topic forum titles are not renamed for status — see Architecture.

Path safety (photo / file)

Agent-supplied paths are resolved with resolvePathUnderRepo (src/mcp/repo-path.ts):

  • Relative paths join under the session repo root
  • Absolute paths allowed only if they stay inside the repo after realpath
  • .. escapes rejected
  • Missing files fail with a clear error (containment still enforced on the candidate path)

Delivery path

MCP tools call this API directly (HTTP over the Unix socket). There is no disk queue.

On worker start, any leftover pre-API dirs under the state directory (telegram-queue/, speak-queue/) are removed once so stale .req.json jobs do not hang forever.

Start the API by starting the worker:

acpbot              # binary
# or from source: acpbot worker
# logs: acpbot worker API: unix://…/worker-api.sock

Tests: test/worker-api.test.ts.

Speech modes

Controlled in config.toml (see Configuration):

features.tts_modeBehavior
agent (default)Only when the model calls MCP speak
alwaysTTS more aggressively on agent text
offNo TTS
speech.tts_provider / stt_providerAPI used
auto (default)ElevenLabs if keyed, else OpenAI
openaiOpenAI Whisper / TTS (first-class)
elevenlabsElevenLabs Scribe / TTS
offThat side disabled

TTS and STT providers are independent (e.g. OpenAI TTS + ElevenLabs STT).

Why not put the token in MCP env?

  • Agent process escape would leak bot credentials
  • Session → topic resolution needs the live daemon store
  • Worker restart / reattach stays coherent if only the worker speaks Bot API