DEV Community

Cover image for DevOps KB Auto-Builder: I Built an AI That Documents Your Incidents So You Don't Have To
Nkechi Anna Ahanonye
Nkechi Anna Ahanonye

Posted on

DevOps KB Auto-Builder: I Built an AI That Documents Your Incidents So You Don't Have To

Notion MCP Challenge Submission ๐Ÿง 

This is a submission for the Notion MCP Challenge


What I Built

An AI-powered DevOps Knowledge Base Auto-Builder that turns raw, messy incident reports into structured, searchable Notion database entries โ€” automatically.

The problem is real: after a production incident, engineers are exhausted. The last thing anyone wants to do is write documentation. So knowledge dies. The same mistakes get made again. Teams keep fighting the same fires.

This tool fixes that. You paste your raw postmortem notes โ€” the kind you'd write in Slack at 2am after an outage โ€” and the system does the rest:

  • AI extracts the title, root cause, fix applied, prevention steps, tags, and severity
  • A structured Notion page gets created automatically
  • Your KB grows itself over time into a searchable library of every incident your team has ever faced

The entire thing runs on free tools โ€” WSL, Groq's free API tier, and a free Notion account. No paid subscriptions required.

Full project documentation with screenshots, errors, and fixes:
DevOps KB Auto-Builder โ€” Full Project Documentation


Video Demo


Show Us the Code

GitHub: github.com/nkydigitech/devops-kb-builder

The pipeline is three steps. Raw text goes in, structured Notion page comes out.

Step 1 โ€” AI extracts structure from raw incident text:

def extract_with_groq(incident_text):
    prompt = f"""You are a DevOps knowledge extractor. Given an incident report,
extract structured information and return ONLY valid JSON with these exact keys:
- title: short incident title (max 8 words)
- root_cause: one clear sentence
- fix_applied: one clear sentence
- prevention: one clear sentence
- tags: list of 2-4 lowercase tags
- severity: exactly one of Low, Medium, High, Critical

Incident report:
{incident_text}

Return only the JSON object, no markdown, no explanation."""

    response = groq_client.chat.completions.create(
        model="llama-3.3-70b-versatile",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.1
    )
    raw = response.choices[0].message.content.strip()
    if raw.startswith("```

"):
        raw = raw.split("

```")[1]
        if raw.startswith("json"):
            raw = raw[4:]
    return json.loads(raw.strip())
Enter fullscreen mode Exit fullscreen mode

Step 2 โ€” Notion page gets created automatically:

def create_notion_page(data, date):
    payload = {
        "parent": {"database_id": DATABASE_ID},
        "properties": {
            "Name": {"title": [{"text": {"content": data["title"]}}]},
            "Root Cause": {"rich_text": [{"text": {"content": data["root_cause"]}}]},
            "Fix Applied": {"rich_text": [{"text": {"content": data["fix_applied"]}}]},
            "Prevention": {"rich_text": [{"text": {"content": data["prevention"]}}]},
            "Tags": {"multi_select": [{"name": tag} for tag in data["tags"]]},
            "Severity": {"multi_select": [{"name": data["severity"]}]},
            "Date": {"date": {"start": date}}
        }
    }
    response = requests.post(
        "https://api.notion.com/v1/pages",
        headers=NOTION_HEADERS,
        json=payload
    )
    return response.json()
Enter fullscreen mode Exit fullscreen mode

Step 3 โ€” Run it:

python3 kb_builder.py
# paste your incident text, then press Enter and Ctrl+D
Enter fullscreen mode Exit fullscreen mode

How I Used Notion MCP

Notion MCP is the backbone of this entire workflow. Here is exactly how I integrated it:

Notion as the Knowledge Store

I created a Notion database with these properties:

Property Type
Name Title
Root Cause Text
Fix Applied Text
Prevention Text
Tags Multi-select
Severity Multi-select
Date Date

This becomes the living KB that grows with every incident your team faces.

Notion Internal Integration

I created a kb-builder internal integration via Notion's developer portal, generated an Internal Integration Secret, and connected it to the DevOps KB database. This gives the Python agent authenticated access to read and write to the workspace โ€” no OAuth flow, no user login required.

Notion API as the Agentic Output Layer

The agent calls POST /v1/pages on the Notion API to create structured database entries. Every field maps directly to a Notion property type โ€” rich_text, multi_select, date โ€” making the output immediately usable without any manual cleanup.

What Notion MCP Unlocks

Without Notion MCP, this is just a script that prints JSON to a terminal and goes nowhere. With it, every incident automatically lands in a structured, searchable, shareable workspace the whole team can access. Notion becomes the long-term memory of your DevOps operation โ€” it remembers everything so your team doesn't have to.


The Honest Build Story

I will be straight with you: this was not smooth. I built this on a Windows 32-bit machine with no paid subscriptions โ€” WSL for Linux, Groq's free API instead of Claude, Aider for AI-assisted coding. Every error below is real and documented with screenshots in the Notion doc.

Error 1 โ€” Aider not on PATH after install

Command 'aider' not found
Enter fullscreen mode Exit fullscreen mode

pip installs scripts to ~/.local/bin which was not on PATH by default.

export PATH="$HOME/.local/bin:$PATH"
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
Enter fullscreen mode Exit fullscreen mode

Error 2 โ€” Groq wrapping response in markdown fences

json.decoder.JSONDecodeError: Expecting value: line 1 column 1
Enter fullscreen mode Exit fullscreen mode

The LLM was returning code fences instead of raw JSON even when instructed not to. Fixed by stripping fences before parsing:

if raw.startswith("```

"):
    raw = raw.split("

```")[1]
    if raw.startswith("json"):
        raw = raw[4:]
Enter fullscreen mode Exit fullscreen mode

Error 3 โ€” Wrong database ID format from URL

body.parent.database_id should be a valid uuid,
instead was "/database-329bda4c72b58047ad87fcbeb115a45f?"
Enter fullscreen mode Exit fullscreen mode

Copying the URL directly included a /database- prefix and trailing ?. Had to strip it to the raw 32-character UUID.

Error 4 โ€” Page ID passed instead of database ID

Provided database_id is a page, not a database.
Enter fullscreen mode Exit fullscreen mode

This one took the longest. The page containing the table and the table itself have completely different IDs in Notion. Fixed by querying the Notion search API directly:

r = requests.post("https://api.notion.com/v1/search",
    headers=headers,
    json={"filter": {"value": "database", "property": "object"}}
)
for db in r.json().get("results", []):
    print("Title:", db["title"][0]["plain_text"])
    print("ID:", db["id"])
Enter fullscreen mode Exit fullscreen mode

Error 5 โ€” Severity property type mismatch

Severity is expected to be multi_select.
Enter fullscreen mode Exit fullscreen mode

Created Severity as Multi-select in Notion but sent it as select in the payload. One word change fixed it:

"Severity": {"multi_select": [{"name": data["severity"]}]}
Enter fullscreen mode Exit fullscreen mode

Every one of these errors is documented with terminal screenshots in the Notion doc.


Live Demo Output

$ python3 kb_builder.py
=== DevOps KB Auto-Builder ===
Paste your incident report below.
When done, press Enter then Ctrl+D

Database connection pool exhausted during peak traffic on March 20.
App servers couldn't get DB connections, causing 500 errors for 20 mins.
We increased the pool size and restarted the app. Need connection monitoring.
Services affected: user dashboard. Tags: database, connection-pool, performance.

Extracting with Groq...
Title: DB Connection Pool Exhausted
Severity: High
Tags: database, connectionpool, performance

Creating Notion page...

Success! Page created: https://www.notion.so/DB-Connection-Pool-Exhausted-329bda4c...
Enter fullscreen mode Exit fullscreen mode

Open Notion. The page is there. All fields populated. Zero manual work.


Stack

Tool Role Cost
Python 3.10 (WSL) Runtime Free
Groq API โ€” Llama 3.3 70B AI extraction Free tier
Notion API Knowledge base storage Free
Notion MCP Integration Workspace authentication Free
Aider AI-assisted coding Free
python-dotenv Secrets management Free

Total cost: $0


What I Would Build Next

  • A Slack bot watching #incidents that auto-creates KB entries with zero manual steps
  • A weekly digest agent surfacing trending failure patterns from the Notion database
  • Natural language queries: "show me all Critical incidents related to database in the last 30 days"
  • Full Notion MCP conversational access so Claude can read, search, and update the KB directly

Run It Yourself

git clone https://github.com/nkydigitech/devops-kb-builder
cd devops-kb-builder
pip install -r requirements.txt
cp .env.example .env
nano .env
python3 kb_builder.py
Enter fullscreen mode Exit fullscreen mode

You need:

  • A free Groq API key
  • A free Notion account + internal integration token
  • A Notion database set up with the schema above

Full setup guide with screenshots:
DevOps KB Auto-Builder โ€” Full Project Documentation


Built by @nkydigitech
GitHub: nkydigitech/devops-kb-builder
Full docs: Notion

Top comments (0)