-
Notifications
You must be signed in to change notification settings - Fork 0
Server Side Agent
The agent (packages/agent) is the deployed app's reasoning layer. It is what
the web Chat talks to, so a teammate can analyze a ticket or structure a doc
from the browser without running a local agent of their own.
There are two integration surfaces, and only one is Claude-specific:
- The MCP server (
packages/mcp) is vendor-neutral. It exposes tachý's 35 tools over the Model Context Protocol. Any MCP client drives it: Claude Code, Codex CLI, VS Code Copilot, or an organization's own model. There is no Claude dependency on this path. - The server-side agent (
packages/agent) uses the Claude Agent SDK (@anthropic-ai/claude-agent-sdk). That is a headless programmatic library: the same engine that powers Claude Code, run in-process on the server, not the Claude Code CLI. It is Claude-specific.
So the SDK is Claude-coupled but headless and server-side; it is not "only for
Claude Code," and it is not the path a local agent takes. It is a thin wrapper:
the only LLM-vendor coupling in the whole project is one import in
packages/agent/src/index.ts, consumed only by
packages/api/src/routes/agent.ts. Everything else is provider-neutral. Swap the
agent out and the rest of tachý is unchanged.
startTurn(prompt, cfg) (packages/agent/src/index.ts) drives the SDK's
query() against a freshly spawned tachý MCP subprocess:
-
System prompt is the
claude_codepreset withCLAUDE.mdappended, plus a web-chat note that reinterprets "ask before saving" for the approval UI (the review box is the approval, so the agent proposes and calls the write tool directly rather than asking in prose first). -
settingSources: []ignores any local~/.claudeconfig, so server behavior is deterministic and independent of the host machine. -
Tools come only from the tachý MCP server. Read tools are on the
allowedToolsallowlist and auto-run. Every built-in file/shell/web tool is ondisallowedTools. Anything else falls through tocanUseTool. - The turn exposes an event stream (
text,tool_use,approval_request,approval_resolved,result,error) that the API route relays to the browser over SSE.
resume carries a prior sessionId so a chat is multi-turn.
canUseTool classifies every tool call (packages/agent/src/tools.ts):
- read → allowed immediately.
-
denied (a built-in, or anything not prefixed
mcp__tachy__) → refused with a message. -
write (
save_*,update_*,add_*,post_private_note,record_analysis_run, or any unknown tachý tool) → the turn emits anapproval_requestand blocks on a promise. The browser shows the exact tool input as editable JSON; the user approves (optionally editing the input) or denies viaPOST /api/agent/approve. Only then does the tool run.
An unknown tachý tool is treated as a write (approval-gated), never silently run. When a turn ends with an approval still outstanding, it is auto-denied so the SDK loop can unwind cleanly.
This applies only to the bundled agent; it adds no coupling to the MCP/core path, so an organization driving the tools with its own model is unaffected. All three settings come from Runtime Settings (DB wins over env) and are snapshotted into the MCP subprocess env at spawn.
-
Default model is
claude-sonnet-5(the "use Sonnet by default" cost guidance), overridable via theagent_modelsetting orTACHY_AGENT_MODEL. -
Allowed-models policy.
allowed_models(orTACHY_ALLOWED_MODELS, comma-separated) is an optional allowlist: a disallowed or unset model is clamped to the first entry (effectiveModel()). Empty means no restriction. -
Effort.
agent_effort(orTACHY_AGENT_EFFORT) sets the reasoning-effort level,lowthroughmax, defaultmedium. -
Cost surfacing.
recordRuncomputes an estimated USD cost from the run's model plus token counts intoanalysis_runs.meta.estimated_cost_usd. Audit only, no enforcement.
The agent authenticates with ANTHROPIC_API_KEY, or the server's Claude Code
login if that is unset. The MCP subprocess inherits the API env (DB URL, source
tokens) plus the logged-in user's email as TACHY_USER_EMAIL, so saved entries
are attributed to the person in the Chat, not to a shared service account.
Security specifics are consolidated in Security Model.
tachý - self-hosted knowledge engine for work items. README · AGPL-3.0-or-later
Design
Subsystems
Platform
Security