DEV Community

Damola Adegbite
Damola Adegbite

Posted on

I built an MCP server that syncs GitHub into Notion and generates AI reports

Notion MCP Challenge Submission 🧠

This is a submission for the Notion MCP Challenge

What I Built

GitNotion is an MCP server that connects GitHub to Notion. Point it at any public repo and it pulls issues, PRs, and commits into structured Notion databases. It then uses Gemini to write weekly activity summaries, release notes, and contributor reports. All free APIs, published on npm.

Eight MCP tools, accessible from Claude Desktop, Copilot, or any MCP client:

Tool What it does
setup_workspace Creates 4 Notion databases under a parent page
sync_issues Pulls GitHub issues into Notion
sync_pull_requests Pulls PRs into Notion
sync_commits Logs recent commits to Notion
generate_summary Sends last week of activity to Gemini, writes a summary page
generate_release_notes Generates release notes from merged PRs and commits
get_contributor_insights Per-contributor stats with an AI written report
full_sync Runs everything above in sequence

Re-running any sync tool updates existing entries. No duplicates.

Notion page showing 4 databases created by setup_workspace: Issues, Pull Requests, Commits, and Summaries for vuejs/core

Video Demo

(screen recording of running full_sync and showing the Notion output — add here)

Show us the code

Repo: https://github.com/dax-side/gitnotion

npm: npx -y gitnotion

How I Used Notion MCP

GitNotion uses the Notion API as its core output layer. Every tool writes directly to Notion: setup_workspace calls databases.create() to scaffold four linked databases under a parent page. The sync tools use pages.create() and pages.update() with upsert logic so re-runs don't create duplicates. The AI tools call Gemini, then write the output as a structured Notion page using blocks.children.append().

The interesting part was the markdown-to-blocks conversion. Gemini returns markdown. Notion doesn't accept markdown — it wants structured block objects for every heading, list item, table row, and inline annotation. I wrote a converter that handles all of that, including Notion's table block format which requires declaring table_width upfront and passing each cell as a rich_text array.

The other Notion-specific issue: passing large content as children to pages.create() times out. The fix was to create the page first with no content, then append blocks in chunks of 100 via blocks.children.append().

It's published on npm so no cloning or building needed. Add this to your MCP client config:

{
  "mcpServers": {
    "gitnotion": {
      "command": "npx",
      "args": ["-y", "gitnotion"],
      "env": {
        "GITHUB_TOKEN": "...",
        "GITHUB_REPO": "owner/repo",
        "NOTION_TOKEN": "...",
        "NOTION_PARENT_PAGE_ID": "...",
        "GEMINI_API_KEY": "..."
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

You need four things to get started, all free: a GitHub token, a Notion integration token (connected to your target page via ••• > Connections), a Gemini API key, and your Notion parent page ID from the URL.

Restart your MCP client, ask it to run setup_workspace, then pass the returned database IDs to full_sync.

Weekly summary page in Notion for vuejs/core showing bullet points, bold highlights, and inline code rendered from Gemini output

Contributor insights page in Notion showing a table with columns for Contributor, Commits, PRs Created, PRs Merged, and Issues

Top comments (0)