Inspiration

Every team has asked "wait, why did we decide that?" and gotten silence. The uncomfortable truth is that most decisions are never written in Slack: they're spoken in standups, buried in threads, or living in one person's head. Slack search can't find what was never typed. I built Rhecall because the problem isn't finding documents, it's that decisions aren't first-class objects anywhere.

What it does

Rhecall is a Slack agent with a durable decision ledger; every record holds what was decided, why, who, when, its status, and verbatim provenance. Three capabilities:

  1. Recover: /rhecall why did we move the ledger off Postgres? The agent gathers evidence from three lanes in parallel: live Slack channel history, meeting transcripts (via a custom MCP server), and the existing ledger. An LLM fuses them into one answer under a strict cite-only contract, every claim carries a verbatim quote from its source. If the decision was made aloud in a meeting and never typed into Slack, Rhecall finds it anyway. One click saves it to the ledger (capture-on-answer).

  2. Conscience: Rhecall listens. When someone posts a message that contradicts an active recorded decision ("gonna spin up the new tables in Postgres…"), it interjects in-thread with the receipt: the decision, who made it, when, and why. If the team really has changed course, one click marks the record superseded, the ledger stays honest instead of silently rotting. A local keyword prefilter plus a 10-minute debounce means the LLM check only fires when a message genuinely overlaps an active decision.

  3. Capture: @Rhecall capture this thread distills a messy thread into a ledger-ready decision record, attributing the call to the actual people (real Slack mentions) with quoted evidence.

How we built it

  • Custom MCP server (MCP TypeScript SDK, stdio transport) exposing four tools: search_transcripts, list_decisions, record_decision, supersede_decision over a meeting-transcript store and the decision ledger. The transcript store is seeded JSON today and deliberately API-shaped: swapping in Fireflies or Granola changes the tool implementation, not the agent.
  • Slack agent in Bolt for JavaScript (Socket Mode), acting as an MCP client: slash command, @mention thread capture, a message listener for the conscience, and Block Kit interactivity (save / supersede / dismiss).
  • LLM fusion via OpenRouter (Claude Sonnet 4.6) with a hard rule: quotes must be verbatim substrings of provided evidence, and citations are passed through from tool results, the model can never invent a source.

Challenges we ran into

  • Cite-only integrity: making hallucinated citations structurally impossible, not just discouraged. Source refs travel from tool output to Block Kit untouched by the model.
  • A conscience that isn't annoying: naive "check every message with an LLM" is expensive and noisy. The two-stage design (vocabulary-overlap prefilter → conservative LLM verdict → per-decision debounce) keeps it silent until it genuinely matters.
  • Deadline scoping: cutting everything that didn't serve the three beats, while keeping the architecture honestly extensible.

Accomplishments that we're proud of

  • A decision recovered from a meeting that was never written in Slack, answered in seconds with verbatim citations.
  • An agent that acts unprompted, catching a contradiction before it ships.
  • A clean MCP tool contract that makes "add Jira / Notion / Fireflies" a one-tool change.

What we learned

Retrieval is commodity; memory with provenance and a status lifecycle is not. Treating a decision as a first-class object (with supersession, not deletion) is what separates an agent from a search box.

What's next for Rhecall

  • Real transcript connectors (Fireflies / Granola / Fathom) behind the same MCP tool.
  • Slack Real-Time Search API for workspace-wide grounding beyond one channel.
  • Auto-capture: drafting ledger entries from transcripts as meetings end, one-tap confirm.
  • An App Home ledger browser and per-team ledgers.

Built With

Share this project:

Updates