Skip to content

The-Public-Works/hydrant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

36 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Hydrant β€” incident knowledge on demand

AI knowledge layer for incident response. Open-source Β· MCP-native Β· Cited by design.

License: MIT Python 3.11+ MCP Native PRs Welcome

Watch the 2-minute demo β†’ Β· Quickstart Β· Tools Β· Wire into your AI client Β· Contributing


Hydrant in action β€” one prompt, two-minute diagnosis with cited sources

What it does

When production breaks at 2 a.m., the on-call engineer spends the next 25 minutes hunting through Slack threads, Linear tickets, GitHub PRs, runbooks, and CODEOWNERS for what already happened the last time this broke.

Hydrant turns that into a single prompt.

It indexes your team's incident knowledge across multiple sources, exposes them through an MCP server, and lets any AI agent (Cline, Claude Code, Claude Desktop) answer questions like:

"Auth is throwing 401s on prod after a deploy. Diagnose it, open a tracking ticket, and post the summary to #incident-…."

…in ~2 minutes end-to-end, with every claim citing a clickable source URL. No black-box answers.


✨ Why use Hydrant

Hydrant Closed alternatives
Cross-source synthesis (Slack + Linear + GitHub) βœ… Often telemetry-only
Every answer has clickable citations βœ… Mostly black-box
Runs inside your AI client of choice βœ… Standalone app you have to switch to
Posts the synthesis back to your incident channel βœ… Answer dies in their app
Self-hosted (your data, your DB) βœ… SaaS only
Open source βœ… MIT ❌

πŸš€ Quickstart (5 minutes)

The fastest path to the "wow" moment β€” just GitHub. Slack + Linear are optional and additive.

# 1. Clone
git clone https://github.com/the-public-works/hydrant && cd hydrant

# 2. Start Postgres + pgvector
docker compose up -d postgres

# 3. Configure 3 keys
cp .env.example .env
#    edit .env:
#      DATABASE_URL=postgresql://ctx:ctx@localhost:5432/ctx
#      GITHUB_TOKEN=ghp_…           (https://github.com/settings/tokens β€” public_repo)
#      OPENAI_API_KEY=sk-…          (https://platform.openai.com/api-keys)

# 4. Install + index a repo
python -m venv .venv && source .venv/bin/activate
pip install -e .
python -m indexer github <owner>/<repo>

# 5. Verify the MCP server boots
./bin/run-mcp.sh
#    expect: "hydrant ready" on stderr, then exits when you Ctrl-C

That's it. Now wire it into your AI client β€” pick one below.

Embedding dim: defaults to text-embedding-3-small at 1536 dims. Override OPENAI_EMBED_MODEL / EMBED_DIM in .env if you want a smaller (cheaper / faster) vector β€” e.g. EMBED_DIM=512. Changing the dim requires make db-reset (drops the chunks table) followed by a re-index, because pgvector columns are fixed-dim.


🧠 What you get

17 MCP tools organized into four families:

Cross-source synthesis (5 tools)
Tool What it returns
diagnose_incident(symptom) Composite call: similar past incidents + matching runbook + likely owner. Start here.
find_similar_incidents(symptom) Past incidents (Slack channels + Linear tickets) ranked by semantic similarity
get_runbook(topic) Matching runbook sections from your GitHub docs
who_owns(path) CODEOWNERS lookup with last-rule-wins semantics
search_all(query, source?) Cross-source kNN β€” pass source to scope to slack / linear / github
GitHub-flavored (7 tools)
Tool What it returns
trace_issue(issue_number) Issue β†’ suspect code β†’ recent PRs touching that code
get_pr_diff(pr_number) PR metadata + per-file diff
git_blame(path, line_start, line_end?) Blame for those lines, enriched with the indexed commit/PR nodes
get_node(id) / get_neighbors(id) Direct graph access
search_context(query, types?) kNN scoped to a single repo
list_repos() What's indexed and how much
Slack write (2 tools)
Tool What it does
create_slack_channel(name, topic?, purpose?, invite?, initial_message?) Spin up #incident-… on demand, optionally with the synthesis pre-posted
post_to_slack(channel, text, thread_ts?) Post into an indexed channel (by name or ID)
Linear write (3 tools)
Tool What it does
create_linear_issue(title, description, priority?, state?) Open a tracking ticket with full markdown body
add_linear_comment(issue_id, body) Comment on an existing ticket
update_linear_issue(issue_id, state?, priority?, …) Move state, change priority

πŸ”Œ Wire it into your AI client

Pick whichever client you use β€” Hydrant works the same way through all of them.

Claude Code β€” zero-config

Already done. The .mcp.json at the project root is auto-detected on session start. Just cd into the repo and Claude Code will prompt to approve the hydrant server.

To reload after editing: type /mcp in Claude Code.

Cline (VS Code extension)

Install Cline in VS Code β†’ click βš™οΈ β†’ "MCP Servers" β†’ "Edit Settings", or edit directly:

~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json

Add this block (swap in your absolute path):

{
  "mcpServers": {
    "hydrant": {
      "command": "/absolute/path/to/hydrant/bin/run-mcp.sh",
      "args": [],
      "disabled": false,
      "autoApprove": [
        "search_all", "find_similar_incidents", "get_runbook",
        "who_owns", "diagnose_incident",
        "search_context", "get_node", "get_neighbors", "list_repos",
        "trace_issue", "get_pr_diff", "git_blame",
        "create_slack_channel", "post_to_slack",
        "create_linear_issue", "add_linear_comment", "update_linear_issue"
      ]
    }
  }
}

Set Cline's API Provider to OpenRouter or Anthropic. Pick a Claude model (Sonnet 4.5 is great for tool calling).

Claude Desktop
open "$HOME/Library/Application Support/Claude/claude_desktop_config.json"

Paste the same mcpServers.hydrant block as above. Restart Claude Desktop.

Try it

Paste this into your AI client of choice:

"Use the hydrant MCP server. Diagnose this incident: 'auth is throwing 401s after a deploy.' Cite the most relevant Slack thread, Linear ticket, and runbook section by URL."

If the indexed repo has matching content, you'll see diagnose_incident fire and the model synthesize a cited answer.


πŸ“‘ Add more sources

The GitHub quickstart is the floor. Hydrant gets dramatically more useful with Slack + Linear plugged in.

Slack

Create a Slack app at api.slack.com/apps β†’ add the bot scopes:

channels:read         channels:history
users:read            users:read.email
channels:manage       chat:write
chat:write.customize  chat:write.public
groups:read           groups:history    (for private channels)

Install to your workspace and copy the Bot User OAuth Token (starts xoxb-):

# .env
SLACK_BOT_TOKEN=xoxb-…

# Invite the bot to channels you want indexed, then:
python -m indexer slack --channels 'incident-*'
Linear

Generate a personal API key at linear.app/settings/api:

# .env
LINEAR_API_KEY=lin_api_…

python -m indexer linear --teams ENG
Notion (alpha)

The connector exists but isn't wired into the demo. Internal-integration token from notion.so/profile/integrations:

# .env
NOTION_API_KEY=secret_…  # or ntn_…

python -m indexer notion

πŸ—οΈ Architecture

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Slack API β”‚   β”‚ Linear API β”‚   β”‚ GitHub APIβ”‚
  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
        β”‚               β”‚                 β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚              β”‚
            β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
            β”‚   indexer/ (Python CLI)  β”‚
            β”‚  Β· fetch Β· parse Β· chunk β”‚
            β”‚  Β· embed (OpenAI)        β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
                β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚  Postgres +    β”‚
                β”‚  pgvector      β”‚
                β”‚  (nodes,       β”‚
                β”‚   edges,       β”‚
                β”‚   chunks)      β”‚
                β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚   mcp_server/ (FastMCP stdio) β”‚
        β”‚   17 tools                    β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚  Your AI client of choice     β”‚
        β”‚  (Cline / Claude Code /       β”‚
        β”‚   Claude Desktop / …)         β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The graph is hybrid: nodes for entities (slack_message, slack_channel, linear_issue, file, pr, commit, author, …), edges for relationships (fixes, modifies, mentions, posted_in, replied_to, authored_by, …), and chunks for the embedded text (HNSW index over vector(512)).

A single SQL query can mix kNN over chunks with graph traversal β€” that's the trick that lets diagnose_incident correlate a Slack panic message to a Linear RCA to a GitHub commit in one round trip.


βš™οΈ Configuration

All config lives in .env (template at .env.example). The minimum to run Hydrant against a GitHub repo:

Variable Required for Where to get it
DATABASE_URL Always docker compose up postgres gives you postgresql://ctx:ctx@localhost:5432/ctx
GITHUB_TOKEN GitHub indexer github.com/settings/tokens β€” public_repo is enough for public repos
OPENAI_API_KEY Embeddings platform.openai.com/api-keys
SLACK_BOT_TOKEN Slack indexer + write tools Slack app β†’ OAuth & Permissions
LINEAR_API_KEY Linear indexer + write tools linear.app/settings/api
OPENROUTER_API_KEY Web demo only (optional) openrouter.ai
DEMO_INVITE_USERS create_slack_channel auto-invites Comma-separated Slack member IDs (e.g. U01ABC2DEF,U01XYZ4567)

πŸ—ΊοΈ Repo layout

hydrant/
β”œβ”€β”€ mcp_server/           # The 17 MCP tools (FastMCP / stdio)
β”œβ”€β”€ indexer/              # Source connectors: github, slack, linear, notion
β”œβ”€β”€ api/                  # FastAPI backend for the /demo page (optional)
β”œβ”€β”€ frontend/             # Next.js β€” landing, /present deck, /demo chat+graph
β”œβ”€β”€ scripts/              # Demo seeders (seed_slack_demo, seed_linear_demo)
β”œβ”€β”€ db/schema.sql         # nodes / edges / chunks / repos
β”œβ”€β”€ bin/run-mcp.sh        # Wrapper used by all MCP clients
β”œβ”€β”€ docker-compose.yml    # Postgres + pgvector (+ optional frontend)
β”œβ”€β”€ .mcp.json             # Auto-detected by Claude Code
β”œβ”€β”€ .env.example          # All env vars documented
└── pyproject.toml        # Python deps (mcp, asyncpg, pgvector, httpx, fastapi, …)

πŸ’‘ Example prompts

Paste any of these into an AI client connected to Hydrant.

"Auth is throwing 401s after a deploy β€” diagnose, open a Linear ticket, and post a summary to #incident-…. Link the ticket from the Slack post."

"We're seeing checkout 500s on the canary cohort. What past incidents match? Who owns src/checkout/?"

"Is there a runbook for postgres failover warmup? Cite the exact section."

"PR #2156 looks suspicious β€” what does its diff actually do, and does the description match?"

"Find every Slack thread in the last 30 days that mentions JWT_ACCESS_EXPIRATION_MINUTES."


πŸ—‚οΈ Roadmap

  • Sentry connector (currently the icon is on the landing page, not yet wired)
  • Datadog / OpsGenie / PagerDuty connectors
  • Confluence + Notion (Notion alpha exists in indexer/notion_*.py)
  • Auto-suggested incident channel name based on past patterns
  • Pluggable embedding providers (Voyage / Cohere / local) β€” currently OpenAI only
  • Helm chart for k8s deploys

Have an idea? Open a discussion.


🀝 Contributing

We'd love your help. See CONTRIBUTING.md for the workflow.

Specific things we'd welcome PRs for:

  • πŸ”Œ New source connectors (Sentry, Datadog, Confluence, …) β€” the existing indexer/*.py files are short and templated
  • πŸ› Bug reports with a reproduction
  • πŸ“– Docs improvements β€” typos, clarifications, screenshots
  • πŸ› οΈ New MCP tools that compose existing ones

If you're not sure where to start, open a discussion first.


πŸ“œ License

MIT β€” do whatever you want, just don't sue us.


πŸ› οΈ Built by

The Public Works

The Public Works β€” a small open-source studio building tools for engineers between hackathons.

πŸ₯‡ Won the Cline + 2Hero hackathon (Spotify Intelligent Context Navigation for Developer Knowledge challenge).

If Hydrant helps your team β€” drop a ⭐ on this repo. That's how we know to keep shipping.

About

Open-source AI knowledge layer for incident response. Indexes Slack, Linear & GitHub into one searchable graph; exposes 17 MCP tools any AI agent can call.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors