A Slack-native crisis coordination agent for monsoon flood response.
Built for the Slack Agent Builder Challenge, SentinelSwarm turns scattered Slack updates from responders, route teams, shelters, supply coordinators, volunteers, and risk signals into one evidence-linked Incident Control Room. A human coordinator reviews the plan, approves it, and only then posts the final action plan to #coordination.
The demo is intentionally focused: Zone B monsoon flood response for a campus, NGO, or volunteer operations team.
Track: Slack Agent for Good
Elevator pitch: Slack-native flood response coordination that turns scattered field reports into evidence-backed, human-approved action plans.
Required Slack technology: Slack Real-Time Search through assistant.search.context, initiated from a user app_mention event. Slack channel scan and deterministic local context are labeled fallbacks when RTS is unavailable.
Core proof:
@SentinelSwarm analyze Zone B risk
-> Incident Control Room
-> evidence and source statuses
-> Refresh Analysis after a new Slack route update
-> Approve Plan
-> Post to #coordinationThis is a new Slack agent for a real social-impact problem: helping campus, nonprofit, and mutual-aid responders coordinate flood relief without hiding uncertainty or giving an automated system authority to dispatch people.
During a fast-moving flood response, the hard part is not only knowing that something happened. It is finding the right context quickly enough to act safely:
- Which Slack reports are about the same incident?
- Which route is blocked, and which one is still usable?
- Which shelter has capacity?
- Which volunteers and supplies match the need?
- What evidence supports the recommendation?
- Who approved the final plan?
SentinelSwarm keeps that workflow inside Slack. It uses Slack Real-Time Search when available, combines the retrieved context with local operational data and weather/flood signals, and renders a concise Block Kit control room that is built for human review.
Flood response teams lose time when a blocked route, shelter capacity change, supply request, or volunteer update is buried in a busy channel. SentinelSwarm reduces that coordination cost by turning existing Slack reports into a shared operational picture with cited evidence, severity ranking, resource matching, and a clear handoff.
The intended users are campus safety teams, nonprofit responders, community organizers, and volunteer coordinators who may not have a dedicated emergency-operations platform. The system is deliberately decision support: it exposes the evidence and confidence, labels live versus fallback signals, and requires a human approval click before the plan reaches #coordination. This makes the workflow safer to review, easier to hand off across shifts, and useful even when one external service is unavailable.
The main interaction is one Slack mention:
@SentinelSwarm analyze Zone B riskSentinelSwarm replies in thread with an Incident Control Room that includes:
- Risk summary for Zone B.
- Source status for Slack context, weather, flood, and planner mode.
- Evidence Ledger with cited report snippets.
- Priority incidents and severity ranking.
- Route conflicts and safer route suggestions.
- Shelter, volunteer, and supply matches.
- Recommended action plan.
- Human approval controls.
- Decision-support disclaimer.
- Show Slack chaos across
#alerts,#field-reports,#routes,#shelters,#supplies, and#volunteers. - In
#field-reports, run@SentinelSwarm analyze Zone B risk. - Review the Incident Control Room: evidence, risk signals, severity, routes, shelter, volunteers, supplies, and recommended plan.
- Add a changed route update and click
Refresh Analysisto prove the plan can update from Slack context. - Click
Approve Plan. - Click
Post to Coordination. - Show the final approved action plan in
#coordination.
- Starts from a real Slack mention. The primary demo trigger is
app_mention, which is the safest path for Slack Real-Time Search because the event can provide the required action token. - Searches Slack context. SentinelSwarm attempts
assistant.search.contextbefore falling back to deterministic local context. - Uses Block Kit as the control surface. The plan is not a generic chatbot paragraph; it is a Slack Incident Control Room with sections, evidence, source statuses, and buttons.
- Requires human approval. The app never posts final assignments automatically.
- Posts where teams coordinate. Approved plans are sent to
#coordinationas clean responder-ready instructions.
The initial plan is built from multiple Slack channels and operational datasets. The refresh path is an explicit change test: add a new route update in Slack, click Refresh Analysis, and the app reruns retrieval, evidence assembly, scoring, and plan generation. The refreshed plan returns to draft and hides the final posting action until a coordinator approves it again.
The card makes the system inspectable instead of presenting an unexplained answer:
- Evidence Ledger snippets show the reports used by the planner.
- Source badges distinguish RTS, Slack scan enrichment, mock context, live weather, mock weather, live flood, mock flood, and deterministic planning.
- Route, shelter, volunteer, and supply recommendations are matched against local structured data.
- Confidence and the decision-support disclaimer remain visible at the approval boundary.
The demo continues to work even when external services fail. Every dependency has a deterministic fallback:
| Dependency | Primary path | Fallback |
|---|---|---|
| Slack context | Real-Time Search via assistant.search.context |
src/data/mockContext.json, optionally enriched by live channel scan |
| Weather | Open-Meteo weather API | src/data/mockWeather.json |
| Flood risk | Open-Meteo flood API | src/data/mockFlood.json |
| Planning refinement | Optional Gemini adapter | Deterministic fallback planner |
| LLM JSON | Zod-validated structured output | One schema retry, then fallback planner |
| Final posting | Configured SLACK_COORDINATION_CHANNEL_ID |
Readable Slack setup hint |
- Node.js 20+
- TypeScript strict mode
- Slack Bolt for JavaScript
- Slack Socket Mode
- Slack Web API and Real-Time Search
- Zod schemas for runtime validation
- Local JSON operational data
- Open-Meteo weather and flood signals
- Optional Gemini refinement with deterministic fallback
- Vitest test suite
The deployed service connects to Slack through Socket Mode; no inbound Slack webhook is required. In the provided Slack developer sandbox:
- Open
#field-reports. - Send
@SentinelSwarm pingto confirm the agent is online. - Send
@SentinelSwarm analyze Zone B risk. - Review the Incident Control Room, Evidence Ledger, source statuses, risk summary, and resource matches.
- Add this route update in the thread or channel:
Zone B route update: Route R2 through Riverside Lane is now open for emergency vehicles. Route R4 via Hill School Road is blocked by stalled traffic.- Click
Refresh Analysisand verify that the plan updates and returns to awaiting approval. - Click
Approve Plan, thenPost to Coordination. - Open
#coordinationand verify the approved handoff.
The same workflow remains runnable locally with npm.cmd run dev, and all external dependencies have deterministic fallbacks for reliable judging.
- Architecture diagram source
- Architecture notes
- Fresh live proof log
- Devpost submission draft
- Judge Q&A
The final submission video is kept under three minutes, shows the working Slack app rather than slides alone, and contains no tokens, private data, copyrighted music, or sensitive information. The Slack developer sandbox is shared with the required judge accounts before submission.
npm installCreate a Slack app from manifest.yaml, then enable Socket Mode and install the app to your Slack developer sandbox.
The manifest requests the core bot scopes used by the demo:
app_mentions:readchannels:joinchannels:readchannels:historychat:writesearch:read.public
Full setup notes are in docs/SLACK_SETUP.md.
Copy .env.example to .env and fill in:
SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...
SLACK_COORDINATION_CHANNEL_ID=C...
SENTINEL_FORCE_MOCKS=false
SENTINEL_USE_LLM=falseFor the most reliable judged demo, keep SENTINEL_USE_LLM=false. Gemini is optional and not required for the main workflow.
Create these public Slack channels and invite SentinelSwarm to each one:
#alerts
#field-reports
#routes
#shelters
#supplies
#volunteers
#coordinationnpm run smoke:slackOn Windows PowerShell, use:
npm.cmd run smoke:slackThe smoke test checks token format, Socket Mode readiness, demo channel access, and #coordination setup without printing secrets.
npm run devThen in Slack:
@SentinelSwarm analyze Zone B riskSentinelSwarm uses Socket Mode, so Slack does not need a public inbound webhook URL. For judge-accessible hosting, deploy the same repository to Railway using the root Dockerfile; see docs/RAILWAY_DEPLOY.md.
Preview the fictional Zone B seed pack without posting to Slack:
npm run seed:slackPost the seed messages after the Slack channels exist and the bot is invited:
npm run seed:slack -- --postThe seed command does not send the bot mention. Trigger the analysis yourself from #field-reports:
@SentinelSwarm analyze Zone B risknpm test
npm run build
npm run check:secretsOn Windows PowerShell:
npm.cmd test
npm.cmd run build
npm.cmd run check:secretsUseful additional checks:
npm run typecheck
npm run smoke:slackUse the optional write-path check only when you are comfortable posting a harmless test message to #coordination:
npm run smoke:slack -- --post-test- Slack setup
- Architecture
- Demo seed messages
- Devpost submission draft
- Judge Q&A
- Submission checklist
- Railway deployment
SentinelSwarm is decision support, not emergency authority. It helps coordinators organize evidence and draft a plan, but final dispatch requires explicit human approval. The app is designed for fictional demo data or authorized operational data only.
Optional Gemini refinement should stay disabled unless the Slack reports are fictional or approved for processing by Google. When enabled, SentinelSwarm redacts raw Slack user IDs, channel IDs, permalinks, and URLs before the optional Gemini call, but report text is still included for planning context. Never commit GOOGLE_API_KEY.



