ThreadHarbor is an agent runtime that can be connected to a Slack channel to be "a developer" that can answer questions and patch bugs in a connected repository. It's like having a 24/7 developer for the issues users are having, with the conversation happening in Slack.
ThreadHarbor can classify a report, route it to support, feature, incident, or engineering roles, search permitted knowledge, look for an existing Jira issue, collect attachments or a debug bundle, and keep the conversation tied to one durable record.
A debugging run can safely extract supplied evidence, read the selected repository, create an isolated Git worktree, run tests, and draft an implementation plan. Plans can be reviewed by independently configured review agents, rendered with a required architecture or flow diagram, and parked behind a human approval gate before implementation continues.
Configured jobs can monitor GitLab release pipelines, compose release notes, accept revision feedback, wait for an authorized approval, and publish to a target Slack channel. Channel profiles support mention-only general assistants, agentic triage, regex triggers, curated skills, owner-controlled rules, direct messages, and runtime onboarding when the app joins a new channel.
flowchart LR
Slack[Slack Socket Mode] --> Intake[Event normalization<br/>trust checks and deduplication]
Intake --> State[(SQLite state)]
Intake --> Router[Channel policy<br/>and role router]
Router --> Agent[Role instructions<br/>and curated skills]
Agent --> Executor[API model executor<br/>Agents SDK and LiteLLM]
Agent --> Bus[Per-run guarded tool bus]
Bus --> SlackTools[Slack tools]
Bus --> Jira[Jira adapter]
Bus --> Repo[Git worktrees<br/>GitLab MRs and CI]
Bus --> Knowledge[Knowledge and<br/>document proxy]
Bus --> MCP[Role-gated MCP bridge]
State --> Recovery[Retries, catch-up<br/>watches and recovery]
State --> TUI[Textual operations console]
Approval[Human approvals] --> Agent
Approval --> Repo
Every external connection is opt-in. Missing credentials disable or gracefully degrade that capability instead of removing its extension point from the system.
| Connection | Implemented capability | Activation boundary |
|---|---|---|
| Slack | Socket Mode intake, threads, mentions, reactions, direct and group messages, user lookup, file collection, safe replies, edits, deletes, images, channel triggers, and channel onboarding | A live deployment needs a Slack app plus SLACK_BOT_TOKEN and SLACK_APP_TOKEN. Local tests make no Slack writes. |
| Jira | JQL search, issue reads, duplicate-aware issue creation, comments, intake records, and attachment transfer from Slack | Optional. Enabled only when both JIRA_EMAIL and JIRA_API_TOKEN are present; partial credentials fail the configuration check. Project-specific policy remains deployment configuration. |
| Git and GitLab | Repository allowlist, public-repository bootstrap, isolated worktrees, guarded shell execution, commits, draft merge requests, explicit-human merges, CI failure inspection, pipeline waits, release watches, and branch ports | Local Git workflows need only an allowed repository. GitLab API operations use an authenticated glab session or GITLAB_PUSH_TOKEN. The Git-hosting boundary can be extended with another host adapter. |
| OpenAI Agents SDK / LiteLLM | API-backed role execution, structured classifier output, sessions, tool calls, usage, model settings, and independently configured reviews | The checked-in plain API model uses OPENAI_API_KEY. Other providers remain available through explicit litellm/<provider>/<model> configuration and their required credentials. |
| Knowledge-search proxy | Read-only, source-clamped Slack knowledge search through a Glean-compatible local gateway, plus operator-approved Google Doc reads for release feedback | Optional. Configure [mcp_bridge] or INTEGRATION_MCP_BRIDGE_URL; failures return a bounded result and do not crash the run. |
| Integration MCP bridge | Discovers skills and tools and calls operator-granted external MCP capabilities from selected engineering roles | Optional and disabled by default. Requires INTEGRATION_BRIDGE_URL, INTEGRATION_BRIDGE_TOKEN_FILE, and a role allowlist. The proxy refuses Slack identity writes so external tools cannot speak as the configured integration identity. |
| AI marketplace API | Read-only listing lookup and search for diagnosing publication, ownership, visibility, and install problems | Optional. Configure the base URL and a legacy or service API key. Mutating marketplace calls are blocked from agent shell workflows. |
| SQLite and local filesystem | Durable workflow state, transcripts, approvals, notes, downloaded evidence, model sessions, worktrees, and recovery metadata | Built in. Runtime data stays under ignored .local/ paths and is never part of the public repository. |
The MCP bridge is generic: a deployment can expose services such as documentation, source search, cloud operations, or other MCP servers without hard-coding those systems into the router. Adding a connection still requires an explicit adapter or bridge grant, configuration, authorization rules, and failure tests; agents cannot discover new authority on their own.
- Capability-based roles: each role receives a curated toolset; a skill can guide behavior but cannot grant a capability.
- Conversation- and run-scoped tools: every call is bound to one durable conversation and one recorded run.
- Repository isolation: coding work happens in managed Git worktrees with an allowlisted repository root and a scrubbed subprocess environment.
- Human authorization: implementation plans can wait for approval, and an MR cannot be merged without the human's explicit request for that MR.
- Outbound privacy checks: Slack messages, Jira comments, and uploads pass deterministic secret, private-path, identity, and file-location guards.
- Controlled external identity: raw access to local bridges is blocked from repository shells; selected roles receive only the configured proxy surface.
- Observable state: the TUI exposes active runs, transcripts, tool events, failures, retries, model assignments, and operator controls.
- Recoverable execution: transient connect failures retry only before a tool could have executed, avoiding accidental duplicate writes.
The main extension seams are version-controlled and reviewable:
- Add or modify a role in
agents.d/<role>/. - Add reusable task guidance under
skills/and attach it to a role or channel. - Register tools explicitly in
threadharbor/agents/registry.py. - Add a direct adapter around an external service, or grant selected roles access through the integration MCP bridge.
- Add repositories, channel policies, scheduled jobs, and release rules in an untracked deployment TOML.
- Select model backends per role without changing the intake or persistence layers.
The checked-in integration profile demonstrates the full support and
engineering pipeline. The generic profile is the portable starting point for
another team: it responds on mention with a smaller general-assistant toolset
and no product-specific support behavior.
Requirements: Python 3.12+, uv, and, for the
live end-to-end workflow, a Slack app configured for Socket Mode.
PNG plan diagrams additionally need the native Cairo library. On macOS, install
it with brew install cairo; Linux distributions should use their native
cairo package.
UV_NO_CONFIG=1 uv sync --locked --extra dev --default-index https://pypi.org/simple
cp .env.example .env
cp config/threadharbor.toml config/threadharbor.local.toml
./run-tests.shKeep deployment values out of the public example:
THREADHARBOR_CONFIG=config/threadharbor.local.toml
SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...
OPENAI_API_KEY=...Replace the placeholder workspace, channel, maintainer, and repository values
in config/threadharbor.local.toml. Jira, GitLab, marketplace, knowledge, and
integration-bridge credentials can remain empty until that connection is part
of the deployment.
.venv/bin/threadharbor check
.venv/bin/threadharbor tuiUse .venv/bin/threadharbor run for a headless process.
.venv/bin/python -m threadharbor is equivalent to the installed command. The
local demo runbook separates repository-only validation
from the Slack workspace, account, and token steps that require a human.
The repository uses behavioral tests around public functions, rendered output, captured adapter calls, and persisted state. The full local gate contains more than 2,000 automated tests, followed by whitespace validation:
./run-tests.sh
git diff --checkNo Slack, Jira, GitLab, marketplace, knowledge, or MCP account is required to run the test gate.
Read SECURITY.md before deploying. Do not place secrets in
TOML, Markdown, tests, screenshots, SQLite files, or issue reports. The privacy
guard is part of the runtime contract; adapter implementations must not bypass
it.
ThreadHarbor is released under the MIT License. See LICENSE.