Google's Gemini CLI added MCP support early and its config format will look immediately familiar if you've set up Claude Desktop before — a mcpServers object keyed by name, with command/args/env. Where it differs in practice is the underlying model's behavior on tool-heavy tasks: Gemini's tool-calling has matured a lot, but it still has its own personality around verbosity, retries, and how aggressively it paginates through large results — all of which matter once you're using it to pull requirements data out of a sprawling Notion workspace.
This topic covers wiring up the server, running database queries and requirements extraction directly from Gemini CLI, a worked example building a feature matrix from scattered pages, and a head-to-head comparison against Claude Code on the same task so you know what to expect before you commit a team workflow to either.
Installing and Connecting Notion MCP to Gemini CLI
Gemini CLI reads MCP server config from ~/.gemini/settings.json for global servers or .gemini/settings.json in the project root for project-scoped ones — the project file takes precedence and is the one worth committing to a repo.
{
"mcpServers": {
"notion": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer $NOTION_TOKEN\", \"Notion-Version\": \"2022-06-28\"}"
}
}
}
}
export NOTION_TOKEN="ntn_your_internal_integration_secret_here"
gemini
Inside a Gemini CLI session, confirm the server is live:
> /mcp list
notion - ready - 19 tools
A few Gemini-CLI-specific things worth knowing:
- Tool confirmation prompts. By default, Gemini CLI asks for confirmation before executing a tool call that writes data (create/update/delete). This is genuinely useful for Notion specifically, since it gives you a last look at the exact block JSON before it hits a real page. You can pre-approve a server for a session with
/mcp trust notionif you're doing rapid iterative work and the confirmation friction outweighs the safety benefit — do this deliberately, not as a default habit. - No native remote/OAuth MCP support in older CLI versions. Check your installed version — early Gemini CLI releases only supported
command-based stdio servers, noturl-based remote/SSE ones. If you want to use the hostedmcp.notion.comOAuth server, confirm your Gemini CLI version supports thehttpUrlconfig key before trying:
{
"mcpServers": {
"notion": {
"httpUrl": "https://mcp.notion.com/mcp"
}
}
}
- Environment variable interpolation in
envvalues uses$VARsyntax directly in the JSON string, resolved at server spawn time — same idea as the other clients, slightly different syntax.
gemini "List the tools available from the notion MCP server, then call
API-get-self to confirm which integration is authenticated."
Tips
- Check your Gemini CLI version before assuming remote/OAuth MCP support — thehttpUrlconfig key is a newer addition and older installs will silently ignore it.
- Leave write-tool confirmation prompts enabled for Notion by default — the one time you skip reviewing a block JSON payload before it writes is the one time it's malformed.
-/mcp listafter every config change; Gemini CLI, like most of these clients, doesn't always reload MCP servers without a session restart.
Querying Notion Databases and Extracting Requirements in Gemini CLI
Gemini CLI's tool-calling is notably thorough about pagination — where some clients stop after the first page of results, Gemini tends to keep calling API-post-database-query with the start_cursor from the previous response until has_more is false, which is exactly the right behavior for exhaustive requirements extraction but means a large database can burn more tool calls (and more time) than you'd expect from a single query.
gemini> Query the "Product Requirements" database. I need every row where
Status is not "Archived". For each one, retrieve the page content and
extract: the stated requirement, any linked Figma or GitHub URLs, and the
target release. Compile this into a single markdown table in your response —
don't create a Notion page yet, I just want to review the data first.
The underlying filter:
{
"filter": {
"property": "Status",
"status": { "does_not_equal": "Archived" }
}
}
Asking for a review pass before any write is a good default pattern regardless of client, but it matters more here — Gemini's tool-calling loop is more likely than Claude Code's to proceed straight to a write action once it decides a task calls for one, so an explicit "don't write yet" instruction is doing real work, not just being cautious for its own sake.
For extracting linked resources buried in rich text (a common real-world need — PRDs that reference a Figma link or a GitHub issue inline in a paragraph, not as a dedicated property):
gemini> For each page, look through the paragraph and bulleted_list_item
blocks for any URLs. Notion stores these as either plain text containing a
URL string, or as a "link" annotation on a rich_text span with type "text"
and a "href" field, or as a bookmark block. Check all three forms.
Being this explicit about the three ways a URL can show up in Notion's block model (plain text, an annotated link, a dedicated bookmark block) meaningfully improves recall — without it, extraction tends to catch only the most common form and silently miss the others.
Tips
- Let Gemini CLI's thorough pagination behavior work for you on exhaustive extraction tasks, but budget more time and rate-limit headroom than you would with a client that stops after the first page.
- Explicitly separate "gather and show me" from "write it" as two distinct steps — Gemini's loop is more write-eager than some alternatives once it infers a write is the goal.
- When extracting URLs or references from block content, name all three storage forms (plain text, rich_text link annotation, bookmark block) — recall drops noticeably if you don't.
Practical Example: Building a Feature Matrix from Scattered Notion Pages
A common, genuinely painful task: your product docs aren't in one clean database — some features are documented as standalone pages, some as rows in a "Roadmap" database, some only mentioned inside a larger "Q3 Planning" page. Building an accurate feature-by-platform support matrix means stitching all of that together.
gemini> I need a feature support matrix. Do this in stages:
1. Search Notion for pages/rows matching "feature" or "capability" across
both the "Roadmap" database and the general wiki search.
2. For roadmap database rows, pull the Platform (multi_select) and Status
(status) properties directly.
3. For standalone wiki pages that don't have structured properties, read the
page content and infer platform support from the text — flag these as
"inferred" rather than "confirmed" so I know which entries need a manual
check.
4. Combine everything into one table: Feature | Web | iOS | Android | Status
| Source (confirmed/inferred) | Source page link.
Show me the table before creating anything in Notion.
This is a good stress test for a Notion MCP integration because it deliberately mixes structured (database properties) and unstructured (free-text page content) sources, and forces the agent to be honest about confidence — the "confirmed vs inferred" column is doing real work, preventing a stale wiki mention from silently being treated with the same authority as a maintained database field.
Once reviewed, publishing the matrix back:
gemini> That looks right. Create a new page called "Feature Support Matrix —
Aug 2026" under the Roadmap section, with the table as a native Notion table
block (not a markdown-style pipe table). Add a callout block at the top
noting which rows were inferred vs confirmed, and link back to each source
page from the Source column.
Native Notion table blocks require a specific structure — a table block with a table_width and a table_row child block per row, each containing arrays of rich_text per cell:
{
"object": "block",
"type": "table",
"table": {
"table_width": 3,
"has_column_header": true,
"has_row_header": false,
"children": [
{
"object": "block",
"type": "table_row",
"table_row": {
"cells": [
[{ "type": "text", "text": { "content": "Feature" } }],
[{ "type": "text", "text": { "content": "Platform" } }],
[{ "type": "text", "text": { "content": "Status" } }]
]
}
}
]
}
}
Gemini CLI generates this shape correctly in most cases, but double-check table_width matches the actual cell count per row — a mismatch here is one of the more common silent failures (Notion either errors or renders a visibly broken table).
Tips
- Explicitly ask for a "confirmed vs inferred" confidence marker whenever mixing structured properties with free-text inference — it's the difference between a trustworthy matrix and a quietly wrong one.
- Insist on realtableblocks, not markdown-style pipe tables pasted as text — specify it by name if the first attempt comes back as plain text.
- Verifytable_widthmatches actual cell count when reviewing generated table blocks — it's a small mismatch that causes a real rendering failure.
Comparing Notion MCP Output Between Gemini CLI and Claude Code
Running the same feature-matrix task through both clients on the same workspace surfaces a few consistent differences worth knowing before you standardize on one for a team:
| Dimension | Gemini CLI | Claude Code |
|---|---|---|
| Pagination thoroughness | Exhaustive by default — follows has_more until done |
Also thorough, but slightly more likely to summarize "and N more" past a self-imposed cutoff unless told not to |
| Write eagerness | More likely to proceed to a write once it infers intent | More likely to pause and confirm scope with you first |
| Verbosity of intermediate reasoning shown | Higher — narrates search/retrieve steps more visibly | Lower — tool calls happen with less narrated commentary by default |
| Table block generation accuracy | Reliable, occasional table_width mismatches |
Reliable, rarely mismatches |
| Handling of mixed structured/unstructured sources | Good with explicit "confirmed vs inferred" instruction | Good with the same instruction; slightly better at inferring the need without being told |
| Nested block generation (toggles, deep lists) | Solid for 2 levels, degrades at 3+ | Solid for 2-3 levels |
None of these differences are dramatic enough to call one client objectively better at Notion MCP work — they're closer to accents than capability gaps. What matters more in practice is which client's default behavior matches your team's risk tolerance: if you'd rather the agent ask before writing, Claude Code's default posture needs less prompt scaffolding to get there; if you want maximal recall on an exhaustive extraction task and are comfortable adding an explicit "don't write yet" guardrail, Gemini CLI's thoroughness is a genuine asset.
Tips
- Pick based on default posture, not raw capability — both clients can do the same Notion tasks well with the right prompting, but their unprompted defaults differ enough to matter for a team workflow.
- If standardizing across a team, write down the "don't write until I say so" and "table blocks, not markdown tables" instructions as house-style prompt snippets rather than relying on everyone remembering the client's quirks.
- Re-run this comparison yourself periodically — both tools update frequently, and this table reflects a snapshot, not a permanent ranking.
Tips
Gemini CLI's confirmation-gated writes and thorough pagination make it a solid choice for extraction-heavy Notion work, provided you keep the "gather first, write second" separation explicit in your prompts.
Tips
- Confirm your Gemini CLI version's MCP transport support (httpUrlfor remote/OAuth) before assuming feature parity with newer releases.
- Leverage Gemini's exhaustive pagination for full-database extraction tasks, but budget for the extra tool-call volume against Notion's rate limit.
- Keep the review-before-write pattern as a hard habit here specifically — it's the biggest lever for avoiding an unwanted premature write.