operator-agent is a self-hosted Telegram copilot for understanding what happened to a user, an account, or a production issue.
Instead of opening the admin dashboard, logs, SQL, deploy history, and a support thread separately, you ask one question in chat. The agent checks the systems you connect, returns a grounded answer, and keeps the investigation in the same conversation.
- What happened to this user?
- Where did they get stuck?
- What errors did they hit?
- Did a deploy or outage affect them?
- What is this account's current state?
- Which users were affected by this issue?
- Can you send me the relevant export or evidence?
The best use case is follow-up investigation:
You: What happened to user 12345?
Agent: They completed signup, hit a billing error during onboarding, retried twice, and never finished activation. I found the failure in Datadog and confirmed the account state in Postgres.
You: Did the latest deploy cause it?
Agent: Likely yes. The first matching error appears three minutes after the deploy and affects the same endpoint. I found 11 similar failures in the last hour.
- founders who want direct visibility into customer issues
- support teams answering harder account questions
- ops teams investigating incidents and user journeys
- product teams diagnosing onboarding, activation, and retention friction
This is an internal operator copilot, not a public support chatbot or a replacement for every dashboard.
- answers in Telegram, where the operator is already working
- keeps per-chat memory so follow-up questions stay in context
- streams private DM drafts while the answer is forming
- shows live progress during longer group and Business chats
- can run from a user's connected Telegram Business / Chat Automation profile
- sends useful files, screenshots, exports, or other artifacts back to Telegram
- records SQLite audit events for prompts, failures, and reply delivery
- supports
/investigate,/timeline,/handoff,/case-save,/case-open,/case-list, and/resetworkflows
The default setup includes read-only connectors for:
- Postgres for account, user, and product state
- Datadog for logs and error investigation
You can add more pi/MCP tools over time, but the product works best when the connected tools are scoped to operator-safe investigation.
Telegram Business / Chat Automation is enabled by default.
Users still control this from Telegram. A user must opt in by connecting the bot from Telegram Settings > Chat Automation, and Telegram decides which chats the bot can access and whether it can reply. The app mirrors the latest connection state for audit/debugging and only replies when Telegram grants can_reply.
To disable Business automation entirely:
ENABLE_TELEGRAM_BUSINESS_AUTOMATION=falseTo limit which connected Telegram users may use Business automation:
TELEGRAM_BUSINESS_ALLOWED_OWNER_IDS=123456789,987654321Render storage is declared in render.yaml. Railway volumes are configured in the Railway template composer, not railway.json.
Install dependencies:
bun installCreate local config:
cp .env.example .env
cp .mcp.json.example .mcp.jsonSet at least:
TELEGRAM_BOT_TOKEN=...
ANTHROPIC_API_KEY=...
DATABASE_URL=...
DD_API_KEY=...
DD_APP_KEY=...
DD_SITE=datadoghq.comRuntime Telegram sessions, run lifecycle records, and audit events are stored in SQLite. By default local runs use:
OPERATOR_STATE_DB_PATH=./.operator/state/operator.sqliteUse a persistent volume path for deployments.
To import an old logs/audit-log.json file into SQLite:
bun run migrate:auditTo check the local runtime database:
bun run doctorStart the bot:
bun run startFor local iteration:
bun run devThe default model is Anthropic Claude Sonnet 4.5:
PI_MODEL=anthropic/claude-sonnet-4-5
ANTHROPIC_API_KEY=...To use OpenRouter:
PI_PROVIDER=openrouter
OPENROUTER_API_KEY=...
OPENROUTER_MODEL=google/gemini-3.1-flash-liteTo use OpenAI Codex:
PI_PROVIDER=openai-codex
OPENAI_CODEX_AUTH_JSON='{"openai-codex":{...}}'You can also set OPENAI_CODEX_ACCESS_TOKEN, OPENAI_CODEX_REFRESH_TOKEN, OPENAI_CODEX_EXPIRES_AT_MS, and OPENAI_CODEX_ACCOUNT_ID instead of OPENAI_CODEX_AUTH_JSON.
By default, anyone who can message the bot can use it. For internal deployments, set one or both:
ALLOWED_USER_IDS=123456789,987654321
ALLOWED_GROUP_ID=-1001234567890If ALLOWED_GROUP_ID is set, members of that group can use the bot in the group and in DMs, as long as the bot can verify membership.
/investigate <id>sets the active investigation subject for the chat and asks for a structured investigation./timelinebuilds a timeline for the active investigation./handoffproduces a concise support/engineering handoff./case-savesaves the active investigation to SQLite./case-open <case-id>restores a saved case into the current chat./case-listshows recent saved cases for the chat./resetclears the active investigation and in-memory agent session for the chat.
The agent can send generated artifacts back to Telegram, such as CSV exports, logs, images, and documents.
For safety, files must already exist on disk and stay inside TELEGRAM_ATTACHMENT_ROOTS.
TELEGRAM_ATTACHMENT_ROOTS=/data/artifacts,/app/artifactsoperator-agent is built for internal, self-hosted investigation. It is a strong fit for:
- support and ops workflows
- read-only production context
- account-level investigation
- incident triage and follow-up analysis
It is not meant to be:
- a consumer support bot
- a hosted multi-tenant SaaS product
- a system that automatically understands your business without connected tools
- a place to expose broad write access to production systems
Implementation notes live in:
docs/architecture.mddocs/investigation-workflows.mddocs/positioning.md
Validation:
bun run check
bun test tests
docker build -t operator-agent:local .