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
Video Demo
[Demo video - showing threat detection, incident staging, and human approval workflow]
Demo Workflow:
- Ask AI: "Valkyrie, scan all assets for threats"
- AI detects tropical storm near Singapore Hub
- Incident page created in Notion with status "Awaiting Approval"
- Operator reviews, changes status to "In Progress"
- Crisis Response Playbook triggered
[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
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 || [];
}
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;
}
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:
- Autonomous Database Queries - AI can query assets without manual API calls
- Intelligent Incident Creation - AI stages responses with proper relations
- 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 |
Draft → Awaiting Approval → In Progress → Resolved
|
| 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 | 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
[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
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"
}
}
}
}
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 Approvalfor human review. - The repo includes seeding and demo scripts to make the submission easy to reproduce.
Acknowledgments
- Notion for the MCP SDK and API
- Model Context Protocol for the integration framework
- DEV Community for the challenge platform
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.