notion-agent-hub
# ๐ค Notion Agent Hub
> **AI Agent Hub for Notion** โ orchestrate AI agents through Notion databases with human-in-the-loop approval. Built with MCP.
<!-- Hero Banner -->
<div align="center">






**Turn your Notion workspace into an AI command center.**
[Quick Start](#-quick-start) ยท [Architecture](#-architecture) ยท [Tools](#-tools) ยท [Agents](#-agent-workflows) ยท [Setup Guide](docs/setup.md)
</div>
---
## โจ What It Does
Notion Agent Hub is an **MCP (Model Context Protocol) server** that connects AI assistants (Claude, GPT, etc.) to your Notion workspace. It provides:
1. **๐ Research Agent** โ Search the web, compile findings, and write structured research pages to Notion
2. **๐ GitHub Tracker** โ Monitor GitHub PRs and sync their status to a Notion database
3. **๐ Content Pipeline** โ Read outlines from Notion, generate drafts, and submit for human review
All tasks flow through a **Notion-native task queue** with human-in-the-loop approval โ you stay in control.
## ๐ Architecture
```mermaid
graph TB
subgraph "AI Assistant"
C[Claude / GPT / etc.]
end
subgraph "MCP Server โ notion-agent-hub"
direction TB
S[Server Entry Point]
subgraph "Tools Layer"
NR[๐ notion-read]
NW[โ๏ธ notion-write]
NQ[๐ notion-query]
WS[๐ web-search]
CR[๐ป code-run]
end
subgraph "Agent Layer"
RA[๐ฌ Research]
GT[๐ GitHub Tracker]
CP[๐ Content Pipeline]
end
TQ[๐ Task Queue]
end
subgraph "Your Notion Workspace"
TD[(Task Database)]
RP[Research Pages]
DP[Draft Pages]
PR[(PR Tracker DB)]
end
C <-->|MCP Protocol| S
S --> NR & NW & NQ & WS & CR
TQ -->|Poll| TD
RA -->|Write| RP
GT -->|Sync| PR
CP -->|Write| DP
TD -->|Human creates tasks| TQ
```
For a deeper dive, see [docs/architecture.md](docs/architecture.md).
## ๐ Project Structure
```
notion-agent-hub/
โโโ .github/
โ โโโ workflows/
โ โโโ ci.yml # CI: type-check + tests (Node 22)
โโโ docs/
โ โโโ architecture.md # System architecture & data flow
โ โโโ setup.md # Detailed setup guide
โ โโโ images/ # Diagrams
โโโ scripts/ # Standalone agent test scripts
โ โโโ test-research.ts
โ โโโ test-github-tracker.ts
โ โโโ test-content-pipeline.ts
โโโ src/
โ โโโ index.ts # MCP server entry point (stdio)
โ โโโ agents/ # Higher-level agent workflows
โ โ โโโ research.ts
โ โ โโโ github-tracker.ts
โ โ โโโ content-pipeline.ts
โ โโโ queue/
โ โ โโโ task-queue.ts # Notion-native human-in-the-loop queue
โ โโโ tools/ # MCP tool implementations
โ โ โโโ notion-read.ts
โ โ โโโ notion-write.ts
โ โ โโโ notion-query.ts
โ โ โโโ web-search.ts
โ โ โโโ code-run.ts
โ โโโ utils/
โ โโโ notion-client.ts # Shared Notion API client
โ โโโ logger.ts
โโโ tests/ # Vitest unit tests for tools
โโโ .env.example # Environment variable template
โโโ package.json
โโโ tsconfig.json
โโโ LICENSE # MIT
```
## ๐ Quick Start
### Prerequisites
- **Node.js 22+**
- A Notion account with API access
- A Notion integration (API key)
### 1. Clone & Install
```bash
git clone https://github.com/girishlade111/notion-agent-hub.git
cd notion-agent-hub
npm install
```
### 2. Configure
```bash
cp .env.example .env
```
Edit `.env` with your keys:
```env
NOTION_API_KEY=ntn_your_integration_secret
NOTION_DATABASE_ID=your_task_database_id
OPENAI_API_KEY=sk-your_openai_key # Optional
```
> ๐ See the [Setup Guide](docs/setup.md) for detailed instructions on creating a Notion integration and task database.
### 3. Build & Run
```bash
npm run build
npm start
```
### 4. Connect to Claude Desktop
Add to your Claude Desktop config:
```json
{
"mcpServers": {
"notion-agent-hub": {
"command": "node",
"args": ["/path/to/notion-agent-hub/dist/index.js"],
"env": {
"NOTION_API_KEY": "ntn_your_key",
"NOTION_DATABASE_ID": "your_db_id"
}
}
}
}
```
## ๐ Tools
### `notion-read`
Read pages, databases, and blocks from Notion.
```
Input: { page_id?: string, database_id?: string, block_id?: string }
Output: Page content with properties and child blocks
```
### `notion-write`
Create or update Notion pages with rich content.
```
Input: { action: "create" | "update" | "append", parent_id?, page_id?, title?, blocks? }
Output: { id, url, created/updated/appended: true }
```
Supported block types: `paragraph`, `heading_1/2/3`, `bulleted_list_item`, `numbered_list_item`, `toggle`, `quote`, `callout`, `divider`, `code`
### `notion-query`
Query databases with filters and sorting.
```
Input: { database_id, filter?, sorts?, page_size? }
Output: { results: [...pages], has_more, next_cursor }
```
### `web-search`
Search the web using Brave Search (or DuckDuckGo fallback).
```
Input: { query: string, count?: number }
Output: { results: [{ title, url, snippet }], source }
```
### `code-run`
Execute JavaScript in a sandboxed environment (Node.js vm module).
```
Input: { code: string, timeout_ms?: number }
Output: { success, result?, stdout, stderr }
```
## ๐ค Agent Workflows
### ๐ฌ Research Agent
**Input:** Topic + parent page ID
**Process:** Web search โ compile sources โ create structured Notion page
**Output:** Research page with sources, findings, and review checklist
### ๐ GitHub Tracker
**Input:** GitHub repo + Notion database ID
**Process:** Fetch PRs โ compare with existing entries โ create/update pages
**Output:** Synced PR database in Notion
### ๐ Content Pipeline
**Input:** Outline page ID + parent page ID
**Process:** Read outline โ (optional research) โ generate draft โ create page
**Output:** Draft page with review checklist, ready for human editing
## ๐ Human-in-the-Loop
The task queue uses your Notion database as the control plane:
```
You create a task โ Status: Pending
Agent picks it up โ Status: Running
Agent writes results โ Status: Done โ
Something went wrong? โ Status: Failed โ (with error details)
```
**You're always in control.** Tasks only run when you create them. Results are always written back to Notion for your review.
### Task Database Schema
| Property | Type | Description |
|----------|--------|---------------------------------|
| Name | Title | Task description |
| Status | Status | Pending โ Running โ Done/Failed |
| Type | Select | research / github-tracker / content-pipeline |
| Input | Text | JSON input parameters |
| Output | Text | JSON results |
| Error | Text | Error message (if failed) |
## ๐งฐ Tech Stack
| Layer | Technology |
|------------|------------|
| Language | TypeScript (ESM, strict) |
| Runtime | Node.js 22+ |
| Protocol | Model Context Protocol (`@modelcontextprotocol/sdk`) |
| Notion API | `@notionhq/client` |
| Validation | Zod |
| AI (optional) | OpenAI SDK |
| Tests | Vitest |
| CI | GitHub Actions |
## ๐งช Development
```bash
# Run tests
npm test
# Watch mode
npm run test:watch
# Type checking
npm run lint
# Build
npm run build
# Dev mode (watch + rebuild)
npm run dev
```
### Available Scripts
| Script | Description |
|-----------------|------------------------------------|
| `npm run build` | Compile TypeScript to `dist/` |
| `npm run dev` | Type-check in watch mode |
| `npm start` | Run the compiled MCP server |
| `npm test` | Run Vitest suite once |
| `npm run test:watch` | Run Vitest in watch mode |
| `npm run lint` | TypeScript type-check (`--noEmit`) |
### CI
Every push and pull request to `main` runs `.github/workflows/ci.yml`:
1. Install dependencies (`npm ci`)
2. TypeScript compile check (`tsc --noEmit`)
3. Run tests (`npm test`)
## ๐ Environment Variables
| Variable | Required | Description |
|---------------------|----------|------------------------------------------|
| `NOTION_API_KEY` | โ
Yes | Notion internal integration secret (`ntn_โฆ`) |
| `NOTION_DATABASE_ID`| โ
Yes | Task database ID |
| `OPENAI_API_KEY` | โ No | Enables AI content generation |
Never commit `.env` โ it is gitignored. Use `.env.example` as a template.
## โ Troubleshooting
| Issue | Fix |
|-------|-----|
| `Unauthorized` from Notion | Verify `NOTION_API_KEY` and that the integration is connected to the page/database (โฏ โ Connections) |
| Empty query results | Check `NOTION_DATABASE_ID` and database permissions |
| MCP server not showing in Claude | Ensure `npm run build` was run and the path in config points to `dist/index.js` |
| Type errors after changes | Run `npm install` then `npm run lint` |
## ๐ธ Demo
<!-- TODO: Add demo GIF showing the workflow -->

## ๐ค Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit changes (`git commit -m "Add amazing feature"`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
Please ensure `npm run lint` and `npm test` pass before submitting.
## ๐ License
MIT โ see [LICENSE](LICENSE).
---
<div align="center">
**Built for the [Notion MCP Challenge](https://notion.so)** ๐
Powered by [Model Context Protocol](https://modelcontextprotocol.io)
</div>
TDQS
Scored across 5 tools
The Notion tools are mostly distinct: notion-read retrieves content, notion-write creates/updates pages, and notion-query filters databases. There is slight overlap between notion-read and notion-query when reading database contents, but descriptions clarify that query is for filtered/sorted lookups. Web-search and code-run are completely separate domains, so misselection is unlikely.
Tool names follow a readable lowercase-with-hyphen style, and verbs are action-oriented (read, write, query, search, run). However, the prefix convention is inconsistent: Notion tools use 'notion-' while web-search and code-run do not. This mixed pattern makes it less predictable than a uniform verb_noun scheme.
With 5 tools, the server is appropriately scoped for a small agent hub. Each tool serves a clear purpose, and the count is neither too thin nor bloated. Slightly more Notion-specific tools could be justified, but the current number feels reasonable.
The Notion tools cover core operations (read, write/update, query), but delete and block-level editing are missing, which could be a dead-end for some workflows. Web-search and code-run add generality but do not fill Notion-specific gaps. Overall, the surface is functional but not fully comprehensive for a Notion agent.