AI-Powered Orchestration Gateway for the Model Context Protocol
Transform natural language into executable, multi-step business workflows — powered by Gemini 2.5 Flash
NexusMCP is an AI-powered orchestration gateway that connects multiple third-party services through the Model Context Protocol (MCP). It takes a natural language prompt, decomposes it into a Directed Acyclic Graph (DAG) of tool executions via Gemini 2.5 Flash, and executes them in topological order with real-time WebSocket feedback — while supporting Human-in-the-Loop (HITL) approval gates for sensitive operations.
"Alert the #general Slack channel about a P1 API incident, create a hotfix branch in GitHub, and log the incident in Google Sheets"
NexusMCP will automatically:
- 💬 Send a Slack alert to
#general - 🔀 Create a
hotfix/incident-responsebranch in GitHub (requires human approval) - 📊 Append a row with incident data to your Google Sheet
All in real-time, with live status updates on a beautiful dashboard.
| Service | Capabilities | Auth Method |
|---|---|---|
| Slack | Send messages, thread replies | Bot Token (xoxb-*) |
| GitHub | Create branches, repos, pull requests | Fine-Grained PAT |
| Google Sheets | Append rows, read data | Service Account JSON |
- LLM-Powered Decomposition — Gemini 2.5 Flash breaks prompts into execution graphs
- Topological Execution — Nodes execute in dependency order
- Pydantic Validation — Strict schema validation with auto-retry on malformed responses
- Parameterized Edges — Output from one node flows as input to the next
- Sensitive operations (branch creation, repo creation) pause for human approval
- Real-time HITL approval modal with payload preview
- Approve/Reject directly from the dashboard or the Logs page
- Live Dashboard — Total workflows, invocations, success rate (animated SVG ring), active executions
- Activity Feed — Chronological execution log with latency metrics
- Server Health — Live ping to GitHub API, Slack API, and Google Sheets with latency tracking
- 5-second polling via Zustand store with automatic cleanup
- Dark theme with glassmorphism, kinetic gradients, and micro-animations
- React Flow DAG canvas with custom
NexusNodecomponents - Real-time WebSocket node status updates (PENDING → RUNNING → SUCCESS/FAILED/HITL)
- Responsive layout with sidebar navigation
┌─────────────────────────────────────────────────────────────┐
│ FRONTEND │
│ Next.js 16 + React 19 + Zustand + React Flow + Tailwind │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌──────────────┐ │
│ │Dashboard │ │Workflows │ │MCP Servers│ │Execution Logs│ │
│ │(KPIs) │ │(DAG+HITL)│ │(Health) │ │(Feed+Filter) │ │
│ └──────────┘ └──────────┘ └───────────┘ └──────────────┘ │
│ │ │ │ │ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ useStatsStore (Zustand) — 5s polling │ │
│ │ useDAGStore (Zustand) — WebSocket │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────────────┘
│ REST + WebSocket
┌──────────────────────▼──────────────────────────────────────┐
│ BACKEND │
│ FastAPI + Google ADK Agents │
│ │
│ ┌────────────┐ ┌─────────────┐ ┌───────────────────┐ │
│ │ /orchestrate│ │ /execute/ │ │ /stats + /activity│ │
│ │ (LLM→DAG) │ │ (Run DAG) │ │ (Real-time KPIs) │ │
│ └─────┬──────┘ └──────┬──────┘ └───────────────────┘ │
│ │ │ │
│ ┌─────▼────────────────▼──────────────────────────────┐ │
│ │ DAG Executor (Topological) │ │
│ │ ┌──────────────────────────────────────┐ │ │
│ │ │ StatsTracker │ │ │
│ │ │ (In-memory metrics & activity feed) │ │ │
│ │ └──────────────────────────────────────┘ │ │
│ └──────┬──────────────┬──────────────┬────────────────┘ │
│ │ │ │ │
│ ┌──────▼──────┐┌──────▼──────┐┌──────▼──────┐ │
│ │ Slack Agent ││GitHub Agent ││Sheets Agent │ │
│ │ (Google ADK)││(Google ADK) ││(gspread) │ │
│ └─────────────┘└─────────────┘└─────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │ │
Slack API GitHub API Google Sheets API
NexusMCP/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI entry point + Slack startup notify
│ │ ├── api/
│ │ │ ├── endpoints.py # REST: /orchestrate, /execute, /stats, /activity, /approve
│ │ │ └── ws.py # WebSocket: real-time node status updates
│ │ ├── agents/
│ │ │ ├── slack_agent/ # Slack: send_message, send_thread_reply
│ │ │ ├── github_agent/ # GitHub: create_branch, create_repo, create_pr
│ │ │ └── sheets_agent/ # Sheets: append_row, read_last_rows (real API via gspread)
│ │ ├── models/
│ │ │ └── dag.py # Pydantic schemas: DAGNode, DAGEdge, OrchestrationResponse
│ │ └── services/
│ │ ├── llm.py # Gemini 2.5 Flash integration + DAG generation
│ │ ├── executor.py # Topological DAG executor + HITL gates
│ │ └── stats.py # In-memory StatsTracker singleton
│ └── requirements.txt
│
├── frontend/
│ ├── src/
│ │ ├── app/
│ │ │ ├── layout.tsx # Root layout + Google Fonts + dark theme
│ │ │ ├── dashboard/page.tsx # Live KPI dashboard
│ │ │ ├── workflows/page.tsx # DAG builder + executor + HITL modal
│ │ │ ├── logs/page.tsx # Execution log feed with filters
│ │ │ ├── mcp-servers/page.tsx # Service health cards
│ │ │ └── settings/page.tsx # Configuration panel
│ │ ├── components/
│ │ │ ├── CommandCenter.tsx # Natural language prompt interface
│ │ │ ├── Canvas/
│ │ │ │ ├── Canvas.tsx # React Flow wrapper
│ │ │ │ └── NexusNode.tsx # Custom DAG node with status glow
│ │ │ ├── Observability/
│ │ │ │ ├── AuditDrawer.tsx # Execution audit panel
│ │ │ │ └── HITLModal.tsx # Human approval modal
│ │ │ ├── Configuration/
│ │ │ │ └── ConfigDrawer.tsx # Service config drawer
│ │ │ └── layout/
│ │ │ ├── Sidebar.tsx # Navigation sidebar
│ │ │ ├── TopNav.tsx # Top navigation bar
│ │ │ └── AppShell.tsx # Page wrapper with sidebar
│ │ └── store/
│ │ ├── useDAGStore.ts # DAG state + WebSocket + HITL
│ │ └── useStatsStore.ts # Real-time stats polling
│ └── package.json
│
├── .env # Environment variables (secrets)
├── .env.example # Template for .env
├── docker-compose.yml # Docker setup
└── README.md
- Python 3.11+
- Node.js 18+ and npm
- A Gemini API Key from Google AI Studio
git clone https://github.com/Dharm3112/Tic-Tech-Toe.git
cd Tic-Tech-Toecp .env.example .envEdit .env with your actual keys:
GEMINI_API_KEY=your_gemini_api_key
NEXT_PUBLIC_API_URL=http://localhost:8000
GITHUB_TOKEN=ghp_your_github_token
SLACK_BOT_TOKEN=xoxb-your-slack-bot-token
GOOGLE_SHEETS_CREDENTIALS=./credentials.json
GOOGLE_SHEETS_SPREADSHEET_ID=your_spreadsheet_idcd backend
pip install -r requirements.txt
pip install gspread # For Google Sheets integration
uvicorn app.main:app --reload --port 8000The backend will:
- Start on
http://localhost:8000 - Send a "Bot Connected" message to Slack
#generalon startup - Expose health check at
/health
cd frontend
npm install
npm run devThe frontend will be live at http://localhost:3000
Navigate to http://localhost:3000 and try:
"Alert the #general Slack channel about a P1 API incident, create a hotfix branch in GitHub, and log the incident in Google Sheets"
- Go to api.slack.com/apps → Create New App
- Under OAuth & Permissions, add scopes:
chat:write,channels:read - Install the app to your workspace
- Copy the Bot User OAuth Token (
xoxb-...) → paste in.envasSLACK_BOT_TOKEN - Invite the bot to
#general: type/invite @YourBotNamein Slack
- Go to GitHub → Settings → Developer settings → Fine-grained tokens
- Create a token with permissions:
Contents: Read and Write,Pull Requests: Read and Write - Copy the token → paste in
.envasGITHUB_TOKEN
- Go to Google Cloud Console → Create/select a project
- Enable Google Sheets API and Google Drive API
- Create a Service Account → download the JSON key file
- Save it as
credentials.jsonin the project root - Create a Google Sheet → share it with the service account email
- Copy the Spreadsheet ID from the URL → paste in
.env
⚠️ The sharing step is critical — without it, the API returns a 403 even with valid credentials.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/orchestrate |
Accepts {prompt}, returns a DAG via Gemini |
POST |
/api/v1/execute/{dag_id} |
Starts background execution of a stored DAG |
POST |
/api/v1/approve/{node_id} |
Approves a HITL-paused node |
GET |
/api/v1/stats |
Returns real-time dashboard KPIs + server health |
GET |
/api/v1/activity?limit=20 |
Returns recent activity feed entries |
POST |
/api/v1/config |
Updates service tokens in .env at runtime |
WS |
/ws/{dag_id} |
WebSocket for real-time node status updates |
GET |
/health |
Health check endpoint |
{
"nodes": [
{
"id": "slack_1",
"tool_name": "slack_send_message",
"parameters": { "channel": "#general", "text": "🚨 P1 Incident!" },
"requires_approval": false,
"status": "PENDING"
}
],
"edges": [
{
"source": "slack_1",
"target": "github_1",
"param_mappings": {}
}
]
}{
"node_id": "github_1",
"status": "RUNNING",
"result": null
}Status transitions: PENDING → RUNNING → SUCCESS | FAILED | HITL
| Tool Name | Service | Parameters | HITL |
|---|---|---|---|
slack_send_message |
Slack | channel, text |
No |
slack_send_thread_reply |
Slack | channel, thread_ts, text |
No |
github_create_branch |
GitHub | repo, name |
Yes |
github_create_repository |
GitHub | name, description?, private? |
Yes |
github_create_pull_request |
GitHub | repo, title, head, base, body? |
No |
sheets_append_row |
Sheets | sheet, data |
No |
sheets_read_last_rows |
Sheets | sheet, count? |
No |
| Layer | Technology | Purpose |
|---|---|---|
| LLM | Gemini 2.5 Flash | Natural language → DAG decomposition |
| Agent Framework | Google ADK | Agent definitions with tool functions |
| Backend | FastAPI + Uvicorn | REST API + WebSocket server |
| Frontend | Next.js 16 + React 19 | Server components + client interactivity |
| State Management | Zustand 5 | Global stores with polling + WebSocket |
| DAG Visualization | React Flow 12 | Interactive graph canvas |
| Styling | Tailwind CSS 4 | Dark theme with custom design tokens |
| Google Sheets | gspread | Service account–based Sheets API client |
| Validation | Pydantic v2 | Schema validation with auto-retry |
| Metric | Source | Update Interval |
|---|---|---|
| Total Workflows | Backend StatsTracker |
5s polling |
| Tool Invocations | Per-node execution count | 5s polling |
| Active Executions | Currently running DAGs | 5s polling |
| Success Rate | successful / (successful + failed) |
5s polling |
| Server Health | Live API pings (GitHub, Slack, Sheets) | 6s polling |
| Activity Feed | Chronological execution log (last 50) | 4s polling |
docker-compose up --buildThis starts the gateway and mock MCP servers. For production, connect to the real APIs using your .env tokens.
- Never commit
.envorcredentials.jsonto version control - Both are listed in
.gitignore - In production, restrict
CORS allow_originsfrom["*"]to your specific domain - Use environment-variable–based secrets management (e.g., GCP Secret Manager)
- Jira Integration — Add Atlassian Jira for issue tracking
- Persistent Stats — Migrate
StatsTrackerto Redis/PostgreSQL - Parallel Node Execution — Execute independent DAG branches concurrently
- Workflow Templates — Save and replay common workflows
- Multi-user Auth — Role-based access control with OAuth
- Production Deployment — Docker + GCP Cloud Run
This project is licensed under the MIT License — see the LICENSE file for details.
Built with ❤️ Team: Code Connect