Inspiration

The inspiration was to learn new things and also to earn money. Well, getting experience was the most important inspiration for me as if I have experience, even if not today, I will earn money tomorrow.

What it does

  • Conversational AI Agent: Translates plain-English questions (e.g., "Who is working on the dark mode ticket?") into real database queries on-the-fly, returning natural-language answers directly in Slack chats.
  • Proactive Polling: Runs a background asyncio loop every 15 seconds to catch database error cascades before they blow up in production.
  • Auto-Alerts: If things break, it immediately pings the #alerts channel so the team knows exactly what's going on.
  • App Home Dashboard: Instead of typing chat commands, there's a live Block Kit UI right in the Slack App Home showing active vs. closed tickets.
  • One-Click Fixes: You can close out issues straight from the UI with a ⚡ Quick Resolve button—it updates the SQLite DB via MCP and refreshes the screen instantly.
  • Zero Downtime: Built with a try/except dual-model failover. If Claude 3.5 drops or hits a rate limit, it automatically swaps to Gemini 2.5 without missing a beat.

How we built it

The Architecture: A fully asynchronous, decoupled Slack agent built for instantaneous UI updates and zero downtime.

The Foundation: Async Python & Slack Bolt

I built the core application in Python using asyncio and the Slack Bolt framework over Socket Mode. This ensures real-time, non-blocking event handling securely behind the firewall.

The Database Bridge: Model Context Protocol

Instead of hardcoded SQL, I used MCP. A background daemon thread (mcp_loop) runs an AsyncMCPClient that communicates directly with a local Node.js SQLite MCP server, keeping the data layer strictly modular.

Agentic Conversational Orchestration

Rather than mapping specific keywords to hardcoded database queries, I implemented a true agentic loop. The bot inspects the tools exposed by the MCP server at startup, then forwards your question alongside the tool schemas to the active LLM. The model autonomously determines which SQL query to execute (using read_query), runs the command, and aggregates the results into a human-friendly response.

Proactive Monitor Logic

A background task evaluates error density. The alert trigger logic is defined formally as:

$$\text{Alert State} = \begin{cases} \text{Triggered} & \text{if } \sum_{i=1}^{n} \text{Errors}_i \ge 3 \text{ within } \Delta t = 15\text{s} \ \text{Standby} & \text{otherwise} \end{cases}$$

Dual-Model Failover

To guarantee maximum uptime, every LLM call is wrapped in a try/except block. If the primary model (Claude 3.5 Sonnet) hits a rate limit, the system dynamically remaps the MCP schemas and falls back to Gemini 2.5 Flash without dropping the user's request.

The Async-Sync Bridge

Slack Bolt UI events run synchronously, but the database loop is async. To prevent blocking, I bridged them using asyncio.run_coroutine_threadsafe() to safely mutate the database from the UI:

def resolve_ticket(ticket_id):
    async def _do():
        return await mcp_client.call_tool(
            "write_query",
            {"query": f"UPDATE tickets SET status='closed' WHERE id={int(ticket_id)}"}
        )

    return asyncio.run_coroutine_threadsafe(_do(), mcp_loop).result()

Challenges we ran into

The biggest hurdle was bridging Slack Bolt's synchronous event handlers with my asynchronous SQLite MCP loop. Initially, if a user clicked a button in the UI, the app would freeze or crash because the database call was blocking the main thread. I had to implement a thread-safe coroutine dispatcher (asyncio.run_coroutine_threadsafe) to keep the UI snappy.

Additionally, building the failover system was tough. Dynamically mapping the distinct tool-calling JSON schemas between the Anthropic SDK and the Google GenAI SDK on the fly required rigorous error handling.

Accomplishments that we're proud of

  • Zero-Downtime Failover: Building a custom wrapper that catches a Claude rate limit and instantly swaps to Gemini without dropping the user's request is a massive technical win.
  • Instantaneous UI: I am incredibly proud of the App Home dashboard. Making a Slack bot feel like a reactive desktop app with instant, in-place visual state updates completely elevates the user experience.
  • Proactive Autonomy: Writing a background loop that independently monitors, dedupes, and alerts on database cascades without waiting for human input.

What we learned

I learned the incredible power of the Model Context Protocol. By decoupling the database from the LLM logic, I realized how easy it is to hot-swap AI models without rewriting the entire data access layer. I also gained a much deeper practical understanding of Python concurrency, specifically managing daemon threads and event loops.

What's next for Sentinel

Sentinel is just getting started. The immediate next steps include:

  1. Multi-Server MCP Integration: Adding GitHub and Jira MCP servers so Sentinel can automatically open pull requests or create tracking tickets when it detects an incident cascade.
  2. Predictive Diagnostics: Upgrading the background monitor to use vector embeddings for log analysis rather than basic keyword matching, making its anomaly detection much smarter.
  3. Containerization: Packaging the entire architecture into a Docker container for seamless, one-click enterprise deployment.

Built With

Share this project:

Updates