Inspiration

AI agents waste their first five to ten turns on orientation. which python3. git status. docker ps. ls. Every session starts blind. After watching agents pay this cold-start tax thousands of times across hundreds of sessions, I built Perseus — a live context engine that pre-renders workspace state before the agent ever sees it. Zero orientation. The agent reads what's running, what branch you're on, what you worked on last, and what decisions you made — all in turn one.

The obvious next question: why should you need to SSH into a dev server to know what's happening? Developers live in Slack. The context should live there too. Perseus for Slack answers that question. One @perseus status replaces five ssh + docker ps + git log rituals.

What it does

Mention @perseus from any Slack channel. The bot connects to your local Perseus MCP server, resolves live workspace state, and replies in Slack. Everything runs locally — no cloud, no cloud API keys, nothing leaves your machine.

  • @perseus status — What's running? What branch? Recent commits? Active services?
  • @perseus checkpoint <task> — Save a session snapshot before context switching
  • @perseus recover — What was I doing last session? What's next?
  • @perseus health — Stale checkpoints, duplicate work, drift, old tasks
  • @perseus suggest [task] — AI task recommendation via Pythia through a local LLM (labeled fallback when no model is configured)
  • @perseus memory <query> — Search the Perseus Vault knowledge store for past decisions
  • @perseus services — Health-check all configured services
  • @perseus session [N] — Recent AI session history
  • @perseus skills — Available agent skills and capabilities
  • @perseus help — All commands

Natural language works. "What's running", "what was I doing", "decisions about X", "what should I work on" — 25 intent patterns handle conversational Slack queries without rigid command syntax.

What separates this from a Hubot-style status bot is mechanical, not cosmetic: the tool surface is generated (31 MCP tools from one directive registry — adding a directive to Perseus is adding a Slack capability), and context is durable (checkpoint → recover survives sessions, machines, and teammates; a status bot answers and forgets). Built team-first: checkpoints move work between people and timezones, services/health give a whole channel the same live picture during an incident, and memory makes past decisions channel-visible instead of living in one senior engineer's head. Local-first means it also fits teams whose code can't leave the building.

How we built it

Transport: MCP over JSON-RPC 2.0. The bot talks to a long-lived perseus mcp serve --transport sse process over HTTP on localhost, authenticated with a Bearer token — the server refuses to bind unauthenticated. The same JSON-RPC layer serves stdio for MCP clients like Claude Desktop, so one server definition covers both.

Tool surface: directive-driven generation. Perseus's directive registry is a single source of truth. Every directive — @query, @memory, @session, @services, @skills, @health, @waypoint, @agora, @inbox — is auto-exposed as an MCP tool with generated JSON Schema. No manual wiring. Add a directive to the registry, it appears in the next tools/list call. We get 31 tools for free (measured via tools/list).

Intent parsing: ordered regex with fallback. Users don't speak command syntax. They say "what's happening", "status", "what's up". Twenty-five ordered regex patterns catch these variations, with a contextual fallback handler that treats unknown input as a suggestion prompt. The ordering matters — checkpoint\s+(.+)$ is checked before the catch-all.

Dual transport: MCP + CLI. Perseus exposes context tools through MCP, but checkpoint, recover, and suggest are CLI-only commands. The bot routes transparently — get_context hits MCP tools/call, checkpoint runs subprocess.run(["perseus", "checkpoint", ...]). Same API, different transport. The caller never knows the difference.

Live AI suggestion engine. @perseus suggest renders the Pythia prompt (skills snapshot + task) and runs it through any OpenAI-compatible endpoint — Ollama, llama.cpp, LM Studio, Lemonade — configured with three env vars. No GPU required: CPU-class 3B models work. With no endpoint configured, the bot falls back to a deterministic keyword ranking over the same snapshot — and every response footer states which mode produced it, so model output and heuristics are never confused.

Challenges we ran into

The allowlist paradox. Perseus has a defense-in-depth security model. Sensitive tools (perseus_query, perseus_agent) require explicit mcp.tool_allowlist entries. But the allowlist is a whitelist — set it to [perseus_query] and every other tool is blocked. We solved this by routing shell execution through the CLI (which has its own PERSEUS_ALLOW_DANGEROUS gate) and using MCP exclusively for read-only context tools. The bot never calls sensitive MCP tools. It shells out via subprocess with the same environment gate, keeping the MCP channel clean.

Environment propagation across process boundaries. Perseus requires PERSEUS_ALLOW_DANGEROUS=1 for @query directives. The MCP server runs as a subprocess. Even with Popen(env=...), the rendered context showed warnings that the gate wasn't satisfied. Root cause: the MCP server's @query resolver spawns its own nested subprocess for shell commands, and the environment wasn't propagating through the resolver call chain. We worked around this by routing shell queries through the CLI path where subprocess.run(env=os.environ.copy()) guarantees the variable is present at every level.

Command parity gaps. Checkpoint, recover, and suggest aren't in the directive registry — they're CLI-only commands. We had to build a unified bot API that inspects which tools are available via MCP and falls back to CLI for the rest. The PerseusCLI wrapper handles argument formatting, workspace resolution, and error normalization so the bot code never branches on transport.

Natural language is messy. Five different phrases for one intent: "what's happening", "status", "what's up", "context", "what's running". Exact string matching broke on the first real test. We landed on ordered regex patterns with permissive matching (what.?s? catches "whats", "what's", "what is") and a fallback handler that treats unrecognized input as a contextual suggestion prompt rather than an error.

Accomplishments that we're proud of

31 MCP tools with zero manual wiring. Every Perseus directive becomes an MCP tool automatically. We didn't write a single tool schema by hand. The directive registry metadata (arg names, types, descriptions) generates valid JSON Schema. If someone adds a directive to Perseus tomorrow, it's available in Slack without touching bot code.

Zero cloud dependency. The entire pipeline — Slack → MCP Client → Perseus MCP Server → LLM suggestion — runs on a local machine. No API keys to rotate, no cloud bills, no network latency. We verified the full loop against a local OpenAI-compatible model server — full AI without data leaving your network.

A real, verified pipeline. The bot runs end-to-end in a real Slack workspace over Socket Mode — real MCP calls, real checkpoint files on disk, 12/12 intents verified against a live server. The submission video is a labeled UI walkthrough; to see the real thing, the README runs the full loop in two commands.

Checkpoint → recover is a complete loop. The bot doesn't just answer questions. You can save progress (@perseus checkpoint refactoring auth), switch contexts, come back the next day, and recover exactly where you left off. The health report even detects duplicate checkpoints and warns you. This turns Perseus from a query tool into a session management system.

Honest AI labeling. Every suggest response carries a footer that says exactly what produced it: ⚡ live LLM (provider + model) or 📊 deterministic keyword ranking. The one-config swap is real — we verified the live path end-to-end against a local OpenAI-compatible model server, and the deterministic path stays useful as a labeled fallback rather than a stand-in.

What we learned

Local-first still needs real auth. Perseus refuses to serve HTTP unauthenticated, so the bot ships Bearer-token support — 'localhost' is not a security boundary. Making the transport story production-honest (HTTP JSON-RPC against perseus mcp serve, token in the header) cost one afternoon and removed a whole class of demo-vs-reality gaps.

Directive-driven tool generation is a force multiplier. We got 31 MCP tools for the cost of one registry entry each. No per-tool boilerplate, no manual schema maintenance. The registry is the API. This pattern scales to any number of directives — add one, get a tool.

Mock-first, but ship real. Building the deterministic path first let us develop and test the full Pythia pipeline without waiting on inference. Then we wired in the real model — three env vars, any OpenAI-compatible server — and kept the deterministic path as a clearly labeled fallback instead of a stand-in.

Natural language intent parsing works better than you'd expect for this scope. Twenty-five regex patterns cover a surprisingly wide range of user expressions. The key insight: order matters. Specific patterns first, catch-all last. And unrecognized input shouldn't be an error — it should be a suggestion prompt.

What's next for Perseus

Slack Marketplace listing. Submit the app to the Slack Marketplace after the challenge — the manifest is ready and the listing JSON is written. (This entry competes in the New Slack Agent track; Marketplace submission is future work, not part of this submission.)

Deeper model integration. The OpenAI-compatible path (Ollama, llama.cpp, LM Studio, Lemonade) is live today; next up: streaming responses into Slack, per-channel model config, and outcome-weighted Pythia rankings learned from accepted suggestions.

Interactive Block Kit. Replace plain text with Slack Block Kit buttons: "Save Checkpoint", "Show Health", "Recover Session". One click instead of typing. Combine with a daily digest that posts workspace summaries to a channel.

Multi-workspace support. @perseus workspace <name> to switch context between projects. Perseus already handles multiple workspaces — the bot just needs a workspace registry and context switching.

Scheduled context digests. Cron-triggered @perseus status summaries posted to #dev every morning. "Here's what changed overnight." Combined with the health report, this gives teams ambient awareness of their workspace state.


Built for the Slack Agent Builder Challenge 2026 · github.com/Perseus-Computing-LLC/slack-perseus-agent · github.com/Perseus-Computing-LLC/perseus · MIT License

Built With

  • docker
  • markdown
  • mcp-(json-rpc-2.0)
  • perseus
  • perseus-mcp-server-(31-tools)
  • perseus-vault
  • pythia-local-llm-(openai-compatible)
  • python
  • slack-bolt-sdk
  • slack-events-api
  • slack-slash-commands
  • socket
  • sqlite-fts5
  • yaml
Share this project:

Updates

Submission history