DEV Community

Cover image for Project Valkyrie: AI-Powered Crisis Logistics & Response Hub
Dickson Kanyingi
Dickson Kanyingi

Posted on

Project Valkyrie: AI-Powered Crisis Logistics & Response Hub

Notion MCP Challenge Submission 🧠

This is a submission for the Notion MCP Challenge

What I Built

Valkyrie is an AI-powered crisis response and logistics command center that uses the Model Context Protocol (MCP) to turn Notion into a real-time operations hub.

In modern logistics, "latency kills." When a natural disaster or geopolitical event occurs, operators lose precious minutes switching between news feeds, weather maps, and internal databases. Valkyrie solves this by:

  • Bridging external threat data with internal asset data via MCP
  • Autonomously staging incident responses in Notion for human approval
  • Maintaining relational integrity between incidents and affected assets

Key Features

Feature Description
🔍 Autonomous Threat Monitoring Scans simulated global feeds for risks near tracked assets
📋 Instant Incident Staging Creates Notion pages with threat analysis and mitigation steps
🔗 Relational Asset Resolver Maps coordinates to Notion Page IDs for data integrity
👤 Human-in-the-Loop AI proposes solutions; humans approve and execute

MCP Tools Exposed

analyze_global_threats  → Check asset for threats, stage incident if detected
scan_all_assets         → Batch scan all tracked assets
get_asset_details       → Retrieve full asset information
list_all_assets         → List assets with risk levels (🔴🟡🟢)
find_nearest_safe_asset → Find rerouting destination during crisis
Enter fullscreen mode Exit fullscreen mode

Video Demo


[Demo video - showing threat detection, incident staging, and human approval workflow]

Demo Workflow:

  1. Ask AI: "Valkyrie, scan all assets for threats"
  2. AI detects tropical storm near Singapore Hub
  3. Incident page created in Notion with status "Awaiting Approval"
  4. Operator reviews, changes status to "In Progress"
  5. Crisis Response Playbook triggered

Demo Workflow[Data Flow & Human-in-the-Loop Sequence - From threat detection to human approval]

Show us the code

GitHub Repository: kanyingidickson-dev/valkyrie-mcp-server

Tech Stack

  • MCP Server: TypeScript with @modelcontextprotocol/sdk
  • Notion API: v2022-06-28 with direct HTTP queries for database operations
  • Threat Simulator: Python FastAPI generating realistic crisis scenarios
  • Deployment: Docker Compose + GitHub Actions CI/CD

Project Structure

valkyrie-mcp-server/
├── src/                              # MCP server source code
│   ├── index.ts                      # MCP server entry point
│   ├── config.ts                     # Configuration management
│   ├── lib/                          # Core libraries
│   │   ├── assets.ts                 # Asset data utilities
│   │   └── assets.d.ts               # Type definitions
│   ├── tools/                        # MCP tool implementations
│   │   ├── index.ts                  # Tool exports
│   │   ├── analyze-threats.ts        # analyze_global_threats tool
│   │   ├── scan-assets.ts            # scan_all_assets tool
│   │   ├── get-asset-details.ts      # get_asset_details tool
│   │   ├── list-assets.ts            # list_all_assets tool
│   │   └── find-nearest-safe.ts      # find_nearest_safe_asset tool
│   └── types/                        # Type definitions
├── mock-api/                         # Threat simulator API
│   ├── valkyrie_mock_api.py          # FastAPI threat simulator
│   ├── requirements.txt
│   └── Dockerfile
├── scripts/                          # Orchestration & utility scripts
│   ├── seed_assets.py                # Populate Notion logistics DB
│   ├── clean_duplicates.py           # Remove duplicate assets
│   ├── scan_and_stage.js             # Scan assets and stage incidents
│   ├── trigger_and_stage.js          # Trigger threats and stage incidents
│   ├── notion_watcher.js             # Poll Notion for status changes
│   ├── webhook_server.js             # Handle Slack actions
│   ├── scheduler.js                  # Periodic scan scheduler
│   ├── notify.js                     # Notification utilities
│   └── requirements.txt
├── tests/                            # Test files
├── docs/                             # Documentation assets
│   ├── logical-overview.png
│   ├── deployment-overview.png
│   └── demo-workflow.png
├── .github/                          # CI/CD workflows
│   └── workflows/
│       └── valkyrie-deploy.yml
├── .data/                            # Local data storage
├── .husky/                           # Git hooks
├── dist/                             # Compiled output
├── package.json                      # Dependencies & scripts
├── tsconfig.json                     # TypeScript config
├── jest.config.cjs                   # Jest test config
├── .eslintrc.json                    # ESLint config
├── .prettierrc                       # Prettier config
├── docker-compose.yml                # Docker orchestration
├── Dockerfile                        # MCP server container
├── .env.example                      # Environment template
├── MCP_INSTRUCTIONS.md               # MCP usage guide
├── LICENSE
└── README.md
Enter fullscreen mode Exit fullscreen mode

Key Code: Relational Asset Resolver

From src/lib/assets.ts:

// Maps external telemetry coordinates to Notion Page IDs
export async function queryNotionDatabase(
  databaseId: string,
  filter?: Record<string, unknown>
): Promise<NotionPageObject[]> {
  const res = await fetch(`https://api.notion.com/v1/databases/${databaseId}/query`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.NOTION_TOKEN}`,
      'Content-Type': 'application/json',
      'Notion-Version': '2022-06-28',
    },
    body: JSON.stringify(filter ? { filter } : {}),
  });
  const data = await res.json();
  return data.results || [];
}
Enter fullscreen mode Exit fullscreen mode

Incident Staging with Human-in-the-Loop

From src/tools/analyze-threats.ts:

// Creates Notion page with "Awaiting Approval" status
async function createIncidentPage(params: {
  assetName: string;
  assetPageId: string | null;
  category: string;
  summary: string;
  threatLevel: number;
}): Promise<string> {
  const threatLevelText = params.threatLevel >= 8 ? 'Critical (Red)' : 'Elevated (Yellow)';

  const incidentPage = await notion.pages.create({
    parent: { database_id: DASHBOARD_DB_ID },
    properties: {
      'Incident Name': {
        title: [{ text: { content: `🚨 ALERT: ${params.category} - ${params.assetName}` } }],
      },
      Status: { status: { name: 'Awaiting Approval' } },
      'Threat Level': { select: { name: threatLevelText } },
      'Affected Assets': { relation: params.assetPageId ? [{ id: params.assetPageId }] : [] },
    },
  });
  return incidentPage.id;
}
Enter fullscreen mode Exit fullscreen mode

How I Used Notion MCP

The Integration

Valkyrie uses the Model Context Protocol to give AI assistants (like Windsurf's Cascade) direct access to Notion databases as tools. This unlocks:

  1. Autonomous Database Queries - AI can query assets without manual API calls
  2. Intelligent Incident Creation - AI stages responses with proper relations
  3. Contextual Awareness - AI understands asset locations and risk profiles

Notion Database Schema

Operations Dashboard (Incidents DB)

Property Type Description
Incident Name Title Auto-generated: 🚨 ALERT: {Category} - {Asset}
Status Status DraftAwaiting ApprovalIn ProgressResolved
Threat Level Select Critical (Red) / Elevated (Yellow) / Stable (Green)
Affected Assets Relation Links to Logistics DB for relational integrity
AI Assessments Rich Text Threat summary from simulation engine

Global Assets & Logistics DB

Property Type Description
Asset Name Title Unique facility identifier
Coordinates Text Latitude, Longitude (e.g., 1.2902, 103.8519)
Risk Sensitivity Number 1-10 scale for prioritization
Status Select Active / Inactive / Maintenance
Facility Type Select Distribution Hub / Transport Node / Data Center
Primary Contact Text On-site lead name
Primary Phone Phone Emergency contact number
Primary Email Email Escalation contact
Facility Manager Text Responsible party
Last Audit Date Compliance tracking

What This Unlocks

  • Zero-context-switching: Operators see threats and assets in one Notion workspace
  • AI-assisted decisions: AI proposes actions, humans approve
  • Relational data integrity: Incidents automatically link to affected assets
  • Real-time monitoring: Continuous scanning with instant notification

Deployment Overview[Technical Component Stack - Docker containers for MCP Server and Mock API]


Try It Yourself

# Clone and setup
git clone https://github.com/kanyingidickson-dev/valkyrie-mcp-server.git
cd valkyrie-mcp-server
npm install

# Configure Notion
cp .env.example .env
# Add your NOTION_TOKEN and database IDs

# Seed assets
pip install -r scripts/requirements.txt
python scripts/seed_assets.py

# Run mock API
python mock-api/valkyrie_mock_api.py

# Build and run MCP server
npm run build
npm start

# Run a one-off scan:
node scripts/scan_and_stage.js

# Optional scheduler:
node scripts/scheduler.js
Enter fullscreen mode Exit fullscreen mode

Add to your MCP client config:

{
  "mcpServers": {
    "valkyrie": {
      "command": "node",
      "args": ["/path/to/valkyrie-mcp-server/dist/index.js"],
      "env": {
        "NOTION_TOKEN": "your-token",
        "DASHBOARD_DB_ID": "your-dashboard-id",
        "LOGISTICS_DB_ID": "your-logistics-id"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Files of interest

  • src/index.ts — MCP server entry point and tool orchestration
  • src/lib/assets.ts — Relational Asset Resolver implementation
  • src/tools/analyze-threats.ts — Threat detection and incident staging
  • mock-api/valkyrie_mock_api.py — FastAPI threat simulator
  • scripts/seed_assets.py — Populate Notion databases with sample assets
  • scripts/scan_and_stage.js — Batch scan + incident staging
  • scripts/trigger_and_stage.js — Single-target trigger + staging
  • scripts/scheduler.js — Periodic scan runner
  • scripts/notion_watcher.js — Notion status change listener
  • scripts/notify.js — Slack and email notifications
  • scripts/webhook_server.js — Action link handler for approvals

Notes

  • The system is intentionally conservative: AI stages incidents as Awaiting Approval for human review.
  • The repo includes seeding and demo scripts to make the submission easy to reproduce.

Acknowledgments


Built for the Notion MCP Challenge 2026 🚀

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.