Source profileQuality 93/100

MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory/.opencode/skills/mcp-tooling/mcp-notion/SKILL.md

mcp-notion

Operates a Notion workspace through the official Notion MCP (@notionhq/notion-mcp-server, 24 tools) over Code Mode, fills 5 API gaps with direct Notion API calls, and routes between the headless local-stdio backend and the interactive remote OAuth backend. Carries a Notion knowledge layer (data-source model, 22 property types, relations, rollups, Formulas 2.0). Embedded registration and agent safety invariants.

Source repository stars
34
Declared platforms
0
Static risk flags
1
Last source update
2026-08-28
Source checked
2026-08-28

Decision brief

What it does: where it fits

Notion workspace operations via the official Notion MCP (@notionhq/notion-mcp-server, 24 tools) over Code Mode, plus direct Notion API calls for the five capabilities the MCP does not expose. It knows Notion's data model at the schema layer — data sources, 22 property types, rel…

Best for

  • Activation Triggers (explicit user phrases)
  • Automatic Triggers (keyword patterns)
  • When NOT to Use

Not for

  • Tasks that require unconfirmed production actions or broad system permissions.
  • Environments where the pinned source and install steps cannot be inspected.

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeNot declaredNo explicit evidencePortability before use
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory --skill ".opencode/skills/mcp-tooling/mcp-notion"
Safe inspection promptEditorial

Inspect the Agent Skill "mcp-notion" from https://github.com/MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory/blob/3d386ee21366523774d89c0aff3ebbbc8fa7ff10/.opencode/skills/mcp-tooling/mcp-notion/SKILL.md at commit 3d386ee21366523774d89c0aff3ebbbc8fa7ff10. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    MARKDOWN + DATA-SOURCE CONTRACT — READ BEFORE ANY NOTION WRITE

    Two shape rules cause most Notion write failures:

    Page bodies vs page properties are different surfaces. A page's content is a tree of blocks (append/update via block tools, or the markdown round-trip tools). A page's metadata is properties typed by its parent data sou…API 2.0 replaced "databases" with "data sources" (API version 2025-09-03). A database is now a container of one or more data sources; queries, schema, relations, and rollups all target a data source id, not a database i…Two shape rules cause most Notion write failures:
  2. 02

    1. WHEN TO USE

    "notion", "notion mcp", "notion api", "mcp-notion"

    "notion", "notion mcp", "notion api", "mcp-notion""notion page", "notion database", "notion data source", "query notion""create a notion page", "add a row", "notion property", "notion relation", "notion rollup", "notion formula"
  3. 03

    Activation Triggers (explicit user phrases)

    "notion", "notion mcp", "notion api", "mcp-notion"

    "notion", "notion mcp", "notion api", "mcp-notion""notion page", "notion database", "notion data source", "query notion""create a notion page", "add a row", "notion property", "notion relation", "notion rollup", "notion formula"
  4. 04

    Automatic Triggers (keyword patterns)

    notion + any action verb (create, read, update, query, search, append, archive)

    notion + any action verb (create, read, update, query, search, append, archive)"data source" / "property" / "rollup" / "relation" in a Notion contextMCP tool names: create-a-page, query-data-source, retrieve-a-page (namespaced notion.notion)
  5. 05

    When NOT to Use

    Community Notion MCP servers (suekou/mcp-notion-server, awkoy/notion-mcp-server) — this mode uses the official @notionhq/notion-mcp-server only.

    Community Notion MCP servers (suekou/mcp-notion-server, awkoy/notion-mcp-server) — this mode uses the official @notionhq/notion-mcp-server only.Notion→Obsidian migration mechanics (running the importer itself) — the importer runs inside the Obsidian desktop app, not here; this mode is the read-side inventory enabler (references/migration-inventory.md), not the…Generic markdown authoring with no Notion workspace — use @markdown / sk-doc.

Permission review

Static risk signals and limitations

Network access

medium · line 79

The documentation includes network, browsing, or remote request actions.

return "REMOTE_MCP" # https://mcp.notion.com/mcp (Streamable HTTP + OAuth)

Network access

medium · line 101

The documentation includes network, browsing, or remote request actions.

| **Views** (create/list/query) | **direct API** | data-source view endpoints | Not in MCP |

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score93/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars34SourceRepository attention, not individual Skill quality
Compatibility0 platformsSourceDeclared in the catalog source record
Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory
Skill path
.opencode/skills/mcp-tooling/mcp-notion/SKILL.md
Commit
3d386ee21366523774d89c0aff3ebbbc8fa7ff10
License
MIT
Collected
2026-08-28
Default branch
main
View the original SKILL.md

mcp-notion Skill

Notion workspace operations via the official Notion MCP (@notionhq/notion-mcp-server, 24 tools) over Code Mode, plus direct Notion API calls for the five capabilities the MCP does not expose. It knows Notion's data model at the schema layer — data sources, 22 property types, relations, rollups, Formulas 2.0 — so an agent can create, query, and extend a workspace without guessing.


MARKDOWN + DATA-SOURCE CONTRACT — READ BEFORE ANY NOTION WRITE

Two shape rules cause most Notion write failures:

  1. Page bodies vs page properties are different surfaces. A page's content is a tree of blocks (append/update via block tools, or the markdown round-trip tools). A page's metadata is properties typed by its parent data source's schema. Writing prose into a property, or a property value into a block, fails or silently truncates.
  2. API 2.0 replaced "databases" with "data sources" (API version 2025-09-03). A database is now a container of one or more data sources; queries, schema, relations, and rollups all target a data source id, not a database id. Using a database id where a data-source id is required is the most common 400.

Markdown round-trip tools (retrieve-page-markdown / update-page-markdown) require API version 2026-03-11 and are the token-efficient path for AI. Full detail: references/database-model.md and references/mcp-tools.md.

Failure symptom: a validation_error naming data_source_id, or property writes that vanish, means a database id was used where a data-source id was required, or content was routed to the wrong surface.


1. WHEN TO USE

Activation Triggers (explicit user phrases)

  • "notion", "notion mcp", "notion api", "mcp-notion"
  • "notion page", "notion database", "notion data source", "query notion"
  • "create a notion page", "add a row", "notion property", "notion relation", "notion rollup", "notion formula"
  • "notion token", "notion integration", "ntn_", "notion search"
  • "upload a file to notion", "notion view", "notion async task"

Automatic Triggers (keyword patterns)

  • notion + any action verb (create, read, update, query, search, append, archive)
  • "data source" / "property" / "rollup" / "relation" in a Notion context
  • MCP tool names: create-a-page, query-data-source, retrieve-a-page (namespaced notion.notion_<name>)

When NOT to Use

  • Community Notion MCP servers (suekou/mcp-notion-server, awkoy/notion-mcp-server) — this mode uses the official @notionhq/notion-mcp-server only.
  • Notion→Obsidian migration mechanics (running the importer itself) — the importer runs inside the Obsidian desktop app, not here; this mode is the read-side inventory enabler (references/migration-inventory.md), not the importer.
  • Generic markdown authoring with no Notion workspace — use @markdown / sk-doc.
  • Non-Notion knowledge apps (Obsidian, ClickUp docs) — wrong surface (mcp-obsidian, mcp-click-up).

2. SMART ROUTING

Resource Loading Levels

ALWAYS:    SKILL.md (this file)
ON_DEMAND: references/mcp-tools.md        (24-tool catalog + Code Mode invocation)
           references/api-gap-tools.md    (direct API for the 5 uncovered capabilities)
           references/property-types.md   (22 property types: schema, value, filter/sort)
           references/database-model.md    (data-source hierarchy, relations, rollups, Formulas 2.0)
           references/troubleshooting.md   (auth, rate-limit, version, deprecation-migration)
           references/migration-inventory.md (Notion→Obsidian migration read-side inventory method)

Two Decisions This Router Makes

  1. MCP vs direct API — anything in the 24-tool surface (page/block/data-source/comment/user/search CRUD) goes through the MCP over Code Mode; the five gaps (file uploads, views, page property items, async tasks, daily-notes convention) go to direct Notion API calls.
  2. Which backend — headless local stdio (npx @notionhq/notion-mcp-server, NOTION_TOKEN) for Code Mode / automated sessions; remote OAuth (mcp.notion.com) only when an interactive browser session is available. Code Mode is headless, so it uses the local stdio backend.

Backend Selection

def resolve_notion_backend(runtime):
    """Pick the Notion backend. Probe, never assume.
      runtime.interactive   -> a browser/OAuth session is available
      runtime.oauth_token   -> remote Notion MCP OAuth completed
      runtime.notion_token  -> NOTION_TOKEN (ntn_...) present for Code Mode
    """
    # Remote MCP is OAuth-only and CANNOT run headless. Prefer it only when a
    # human/browser session is present; it adds async-task tools the local lacks.
    if runtime.interactive and runtime.oauth_token:
        return "REMOTE_MCP"      # https://mcp.notion.com/mcp (Streamable HTTP + OAuth)

    # Default for Code Mode and any automated session: the local stdio server.
    # Deprecated by Notion but the only headless-capable backend.
    if runtime.notion_token:
        return "LOCAL_STDIO"     # notion manual in .utcp_config.json, via Code Mode

    return "ESCALATE"            # no auth — direct the user to INSTALL-GUIDE.md

Operation-to-Tool Routing Table

OperationSurfaceTool / callNotes
Create / retrieve / update / archive a pageMCPcreate-a-page / retrieve-a-page / update-page-properties / archive-a-pageArchive, not hard delete
Page body as markdown (read/write)MCPretrieve-page-markdown / update-page-markdownNeeds API 2026-03-11; token-efficient
Append / update / delete blocksMCPblock tools (append-block-children, update-a-block, delete-a-block, …)Page content surface
Query / retrieve / update a data sourceMCPquery-data-source + data-source toolsTarget the data-source id
Comments (create, list)MCPcomment tools
Users (list, retrieve, bot)MCPuser tools
Search (by title)MCPsearchTitle-only; no full-text content search
File uploadsdirect APIPOST /v1/file_uploads (+ send/complete)Not in MCP — see api-gap-tools.md
Views (create/list/query)direct APIdata-source view endpointsNot in MCP
Page property items (non-truncated)direct APIGET /v1/pages/{id}/properties/{prop}Not in MCP
Async tasks (poll)direct API / remote MCPtask-status endpointNative on remote MCP only
Daily notesconventionknowledge-layer patternNo API — see database-model.md

Smart Router Pseudocode

from pathlib import Path

SKILL_ROOT = Path(__file__).resolve().parent
RESOURCE_BASES = (SKILL_ROOT / "references",)
DEFAULT_RESOURCE = "references/mcp-tools.md"
# Fallback-only: DEFAULT_RESOURCE is a defer-time suggestion, never unioned into a
# route's loaded set. Scored routes load exactly RESOURCE_MAP[intent]; zero-score
# routes load nothing and ask for disambiguation instead.
DEFAULT_RESOURCE_SEMANTICS = "fallback-only"

UNKNOWN_FALLBACK_CHECKLIST = [
    "Confirm whether the request is Notion page/block ops, data-source/schema ops, an API-gap capability, install/auth, or troubleshooting",
    "Provide the page id, data-source id, property name, or error text",
    "Confirm whether NOTION_TOKEN (headless/Code Mode) or a remote OAuth session is available",
    "Confirm the verification command before completing any write action",
]

INTENT_SIGNALS = {
    "NOTION_PAGES": {
        "weight": 5,
        "keywords": ["page", "pages", "block", "blocks", "append", "markdown", "content",
                     "create page", "retrieve page", "update page", "archive", "comment",
                     "user", "search", "title search", "sub-page", "child page"],
    },
    "NOTION_DATA": {
        "weight": 5,
        "keywords": ["database", "data source", "datasource", "query", "row", "rows",
                     "relation", "rollup", "formula", "schema", "property", "filter",
                     "sort", "data_source_id", "two-way relation", "aggregate"],
    },
    "NOTION_API_GAP": {
        "weight": 6,
        "keywords": ["file upload", "upload a file", "view", "views", "property item",
                     "non-truncated", "async task", "poll task", "daily note"],
    },
    "NOTION_KNOWLEDGE": {
        "weight": 5,
        "keywords": ["property type", "property types", "select", "multi-select", "status",
                     "formula function", "rollup function", "data model", "hierarchy"],
    },
    "NOTION_MIGRATION": {
        "weight": 5,
        "keywords": ["migration", "migrate", "migration inventory", "notion import",
                     "obsidian import", "workspace inventory", "pre-migration inventory",
                     "relation recovery", "rollup recovery", "comment reconstruction",
                     "parity verification"],
    },
    "INSTALL": {
        "weight": 6,
        "keywords": ["install", "setup", "not found", "not installed", "notion token",
                     "ntn_", "integration token", "api token", "mcp config", "register",
                     "configure", "configuration", "getting started", "onboarding",
                     "oauth", "connect notion", "how do i install"],
    },
    "TROUBLESHOOT": {
        "weight": 6,
        "keywords": ["error", "failed", "not working", "401", "403", "429", "400",
                     "rate limit", "unauthorized", "forbidden", "slow", "timeout",
                     "validation_error", "data_source_id", "deprecated", "won't connect",
                     "can't connect", "version mismatch", "object_not_found"],
    },
}

# NOTE: no "DEFAULT" entry — route_notion_resources() never indexes RESOURCE_MAP by
# that key; the selected `intent` is always one of the seven INTENT_SIGNALS keys. The
# no-match case is owned by DEFAULT_RESOURCE, whose fallback-only semantics mean it is
# SUGGESTED beside the disambiguation checklist, never loaded — so mcp-tools.md cannot
# leak into the DATA / API_GAP / KNOWLEDGE / MIGRATION / INSTALL / TROUBLESHOOT routes.
RESOURCE_MAP = {
    "NOTION_PAGES":     ["references/mcp-tools.md"],
    "NOTION_DATA":      ["references/database-model.md", "references/property-types.md",
                         "references/mcp-tools.md"],
    "NOTION_API_GAP":   ["references/api-gap-tools.md"],
    "NOTION_KNOWLEDGE": ["references/property-types.md", "references/database-model.md"],
    "NOTION_MIGRATION": ["references/migration-inventory.md"],
    "INSTALL":          ["references/troubleshooting.md"],
    "TROUBLESHOOT":     ["references/troubleshooting.md"],
}

def discover_markdown_resources() -> set[str]:
    docs = []
    for base in RESOURCE_BASES:
        if base.exists():
            docs.extend(path for path in base.rglob("*.md") if path.is_file())
    return {doc.relative_to(SKILL_ROOT).as_posix() for doc in docs}

def _guard_in_skill(relative_path: str) -> str:
    resolved = (SKILL_ROOT / relative_path).resolve()
    resolved.relative_to(SKILL_ROOT)
    if resolved.suffix.lower() != ".md":
        raise ValueError(f"Only markdown skill resources are routable: {relative_path}")
    return resolved.relative_to(SKILL_ROOT).as_posix()

def load_if_available(relative_path, loaded, seen, inventory) -> None:
    guarded = _guard_in_skill(relative_path)
    if guarded in inventory and guarded not in seen:
        load(guarded)
        loaded.append(guarded)
        seen.add(guarded)

def route_notion_resources(request: str) -> dict:
    """Score intent labels and load available Notion reference docs."""
    inventory = discover_markdown_resources()
    loaded, seen = [], set()
    request_lower = request.lower()

    scores = {}
    for intent, config in INTENT_SIGNALS.items():
        score = sum(config["weight"] for kw in config["keywords"] if kw in request_lower)
        if score > 0:
            scores[intent] = score

    if not scores:
        return {
            "load_level": "UNKNOWN_FALLBACK",
            "needs_disambiguation": True,
            "disambiguation_checklist": UNKNOWN_FALLBACK_CHECKLIST,
            "suggested_fallback": DEFAULT_RESOURCE,
            "resources": loaded,
        }

    # Error/install keywords win regardless of other signals.
    if scores.get("TROUBLESHOOT", 0) > 3:
        intent = "TROUBLESHOOT"
    elif scores.get("INSTALL", 0) > 4:
        intent = "INSTALL"
    else:
        intent = max(scores, key=scores.get)

    for resource in RESOURCE_MAP[intent]:
        load_if_available(resource, loaded, seen, inventory)

    if not loaded:
        return {
            "load_level": "UNKNOWN_FALLBACK",
            "notice": f"No Notion reference docs available for intent '{intent}'",
            "disambiguation_checklist": UNKNOWN_FALLBACK_CHECKLIST,
            "suggested_fallback": DEFAULT_RESOURCE,
            "resources": loaded,
        }

    return {"intent": intent, "resources": loaded}

3. HOW IT WORKS

Backend Comparison

DimensionLocal stdio (default, headless)Remote MCP (interactive)
Transportstdio via npx -y @notionhq/notion-mcp-serverStreamable HTTP at https://mcp.notion.com/mcp
AuthNOTION_TOKEN (ntn_… internal-integration token)OAuth (browser)
Headless?Yes — the only Code-Mode-capable backendNo — interactive only
Tool namescreate-a-page, retrieve-a-page, …notion-create-pages, … + async tasks
StatusDeprecated by Notion, still functionalRecommended by Notion
Used byCode Mode / automationHuman-in-the-loop clients

Deprecation note. Notion is deprecating the open-source local server in favor of the remote OAuth server. Code Mode is headless, so the local stdio server is the correct (and only) choice here today; references/troubleshooting.md carries the local→remote migration path for when the operator moves to an interactive workflow.

Official Notion MCP — via Code Mode (default path)

The registered notion manual launches @notionhq/notion-mcp-server over stdio with npx -y. It talks to Notion's REST API with the integration's NOTION_TOKEN.

Prerequisites:

  • Code Mode MCP configured, with the notion manual in .utcp_config.json (already registered — see INSTALL-GUIDE).
  • notion_NOTION_TOKEN (an ntn_… internal-integration token) available to Code Mode, and the integration granted content access to the target pages/data sources.

Configuration (.utcp_config.json, manual_call_templates) — already applied:

{
  "name": "notion",
  "call_template_type": "mcp",
  "config": {
    "mcpServers": {
      "notion": {
        "transport": "stdio",
        "command": "npx",
        "args": ["-y", "@notionhq/notion-mcp-server"],
        "env": { "NOTION_TOKEN": "${notion_NOTION_TOKEN}" }
      }
    }
  }
}

The notion_ env prefix matches the manual name notion, so ${notion_NOTION_TOKEN} resolves. This mode documents that registration; it does not rewrite config files.

Tools: the server exposes 24 notion_* tools across 6 domains — pages (7), blocks (5), data sources (6), comments (2), users (3), search (1). Confirm every name with tool_info() / list_tools() before calling; the full catalog with per-tool inputs is in references/mcp-tools.md.

Invocation via Code Mode (call_tool_chain takes a single code string):

// Code Mode namespaces each tool as notion.notion_<tool_name>. Notion tool names are
// HYPHENATED (create-a-page, retrieve-a-page), so notion.notion_retrieve-a-page is invalid
// JS (it parses as subtraction) — use hyphen-safe BRACKET access. VERIFY once the manual is
// registered: run list_tools() to read the exact callable; Code Mode MAY instead sanitize
// hyphens to underscores (notion.notion_retrieve_a_page). Bracket form is the safe default.
const result = await call_tool_chain({
  code: `
    const hit  = await notion["notion_search"]({ query: "Roadmap" });
    const page = await notion["notion_retrieve-a-page"]({ page_id: hit.results[0].id });
    return page;
  `,
});

The Five API Gaps (direct API)

File uploads, views, non-truncated page property items, and async-task polling exist in the Notion REST API but not in the MCP tool surface; daily notes are a convention with no endpoint. Fill them with direct calls (Authorization: Bearer $notion_NOTION_TOKEN, Notion-Version: 2025-09-03, or 2026-03-11 for markdown/async). Recipes: references/api-gap-tools.md.

When to prefer the remote MCP: interactive sessions where OAuth is available and async-task tools are needed. Otherwise stay on the local stdio backend.

Limitations: search is title-only (no full-text content search); pages archive rather than hard-delete; the workspace is cloud-only (no headless filesystem); rate limit ≈ 3 req/s per integration with Retry-After.


4. RULES

✅ ALWAYS

  1. Resolve the backend before acting — Code Mode uses the local stdio backend with NOTION_TOKEN; only route to the remote OAuth backend when an interactive session is genuinely available. Probe, do not assume.
  2. Target a data-source id, not a database id — API 2.0 made data sources the primary abstraction; queries, schema, relations, and rollups all take a data_source_id.
  3. Route content to the right surface — page prose → blocks (or markdown round-trip tools); metadata → typed properties. Never cross them.
  4. Confirm MCP tool names with list_tools() / tool_info() before calling — Notion tool names are hyphenated (create-a-page), so the hyphen-safe callable is bracket-access notion["notion_create-a-page"] unless list_tools() shows Code Mode sanitized them to underscores.
  5. Read a data source's schema before writing rows — property types and select options are schema-defined; writing an undefined option or wrong-typed value fails.
  6. Handle the rate limit — ≈3 req/s per integration; on 429 back off with jitter and honor Retry-After. Batch reads where possible.
  7. Pin the API version per operation2025-09-03 for most tools, 2026-03-11 for markdown round-trip and async tasks.
  8. Preview destructive ops — confirm the exact page/row before archive; Notion archives (recoverable) rather than hard-deletes, but bulk archives are still disruptive.

⛔ NEVER

  1. Never hardcode the token — read it from notion_NOTION_TOKEN in the Code Mode environment; never inline ntn_… in a command, note, or example.
  2. Never use a community Notion MCP server as the default — this mode is the official @notionhq/notion-mcp-server.
  3. Never assume the remote OAuth backend works headless — it cannot; Code Mode must use the local stdio backend.
  4. Never auto-modify .utcp_config.json, .env.example, opencode.json, or hub files — the notion manual is already registered there; if it needs changing, print the config for the user and never write these files programmatically.
  5. Never fabricate pages, rows, or property values — if a query returns empty, the data source is genuinely empty or the integration lacks access. Report it.
  6. Never treat search as full-textsearch matches titles only; to find by content, retrieve candidate pages and inspect client-side.
  7. Never write markdown into a property field — prose belongs in blocks or the markdown round-trip; properties are typed values.

⚠️ ESCALATE IF

  • No NOTION_TOKEN and no OAuth session → direct the user to INSTALL-GUIDE.md (create an internal integration, copy the ntn_… token to .env, grant content access).
  • A 401/403 → the token is missing/wrong, or the integration was not granted access to the target page/data source.
  • A validation_error naming data_source_id → a database id was used where a data-source id is required (2.0 migration); resolve the data source first.
  • Persistent 429 → the integration is over ≈3 req/s; reduce concurrency, add backoff, or batch.
  • The operator wants an interactive/OAuth workflow → follow the local→remote migration path in references/troubleshooting.md.

5. SUCCESS CRITERIA

  • Code Mode notion["notion_search"]({query}) returns results (empty is valid) — confirms the manual + token work
  • list_tools() shows notion.notion_* entries; tool_info("notion.notion_retrieve-a-page") resolves a live schema
  • query-data-source returns rows for a data-source id the integration can access
  • A page create + markdown round-trip (update-page-markdownretrieve-page-markdown) preserves content
  • An API-gap call (e.g. a page-property-item GET) returns data with the Bearer token from the environment
  • bash scripts/doctor.sh reports Node/npx, the notion manual, and notion_NOTION_TOKEN state without mutating

6. INTEGRATION POINTS

Gate 2 (Skill Routing): activates at ≥0.8 confidence for Notion workspace requests. The advisor matches on notion, notion mcp, notion database, notion data source, notion page, notion token.

Code Mode MCP: the official Notion MCP tools are invoked via mcp__code_mode__call_tool_chain; Code Mode namespaces each as notion.notion_<tool_name> — use hyphen-safe bracket access since Notion names are hyphenated. See references/mcp-tools.md.

Migration (packet 015): this mode is the read-side inventory enabler for Notion→Obsidian migration (references/migration-inventory.md) — the same knowledge layer that operates a live workspace reads its structure to drive an Obsidian import; the write-side reconstruction method lives in mcp-obsidian's references/notion-migration.md.

Memory: save Notion workflow context (target data-source ids, integration name, backend) with /memory:save when switching sessions.

Tool Usage: Bash for direct API calls and scripts/; mcp__code_mode__call_tool_chain for MCP operations; Read to load references on demand.


7. QUICK REFERENCE

Notion MCP tool surface (24 tools, 6 domains — confirm names with tool_info())

DomainCountRepresentative tools
Pages7create, retrieve, update, archive; markdown retrieve/update
Blocks5retrieve, children, append, update, delete
Data sources6query, retrieve, update, create, templates
Comments2create, list
Users3list, retrieve, bot
Search1title search

The 5 gaps → direct API (references/api-gap-tools.md)

GapEndpoint family
File uploadsPOST /v1/file_uploads (+ send / complete)
Viewsdata-source view endpoints
Page property itemsGET /v1/pages/{id}/properties/{prop}
Async taskstask-status endpoint (native on remote MCP)
Daily notesconvention (no endpoint)

Code Mode call pattern

// 24 tools, namespaced notion.notion_<tool_name>; hyphenated names → bracket access.
// Confirm the exact callable with list_tools() before relying on either form.
await call_tool_chain({
  code: `
    const ds = await notion["notion_query-data-source"]({
      data_source_id: "DATA_SOURCE_ID",
      filter: { property: "Status", status: { equals: "In progress" } },
    });
    return ds.results.map(p => p.id);
  `,
});

8. REFERENCES AND RELATED RESOURCES

Reference Files (load on demand via router):

  • references/mcp-tools.md — the 24-tool catalog by domain + Code Mode invocation
  • references/api-gap-tools.md — direct Notion API for the 5 uncovered capabilities
  • references/property-types.md — 22 property types: schema, value, filter/sort
  • references/database-model.md — data-source hierarchy, relations, rollups, Formulas 2.0
  • references/troubleshooting.md — auth, rate-limit, API-version, deprecation-migration
  • references/migration-inventory.md — Notion→Obsidian migration read-side inventory method: the 7-step inventory procedure, the 5 API-gap reads it uses, and the read-limit constraints that shape it

Install guide (front door): INSTALL-GUIDE.md — token setup, Code Mode registration, dual-backend config.

Scripts:

  • scripts/install.sh — prints the Code Mode manual + notion_NOTION_TOKEN env key (read-only)
  • scripts/doctor.sh — diagnoses Node/npx, the manual, and the token

Embedded Servers:

  • mcp-servers/notion-mcp/README.md — official @notionhq/notion-mcp-server config notes (stdio, NOTION_TOKEN, dual-backend)

Examples:

  • examples/README.md — Code Mode Notion workflow examples

Related Skills:

  • mcp-click-up — structural sibling (light workflow mode)
  • mcp-obsidian — sibling knowledge app; the 015 migration counterpart
  • mcp-code-mode — Code Mode MCP orchestration (used for Notion MCP invocation)

External:

Frequently asked questions

What to verify before installation and use

What does the mcp-notion source document cover?

Notion workspace operations via the official Notion MCP (@notionhq/notion-mcp-server, 24 tools) over Code Mode, plus direct Notion API calls for the five capabilities the MCP does not expose. It knows Notion's data model at the schema layer — data sources, 22 property types, rel…

How do I install mcp-notion?

The source record exposes this install command: npx skills add https://github.com/MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory --skill ".opencode/skills/mcp-tooling/mcp-notion". Inspect the command and pinned source before running it.

Which permission-related actions were detected?

Static rules flagged network in the source; the page lists the matching lines and excerpts.

Alternatives

Compare before choosing

Computed 10045,960

coreyhaines31/marketingskills

ab-testing

When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program

Computed 10029,236

garrytan/gbrain

bulk-ingestion

End-to-end discipline for turning any large data source (audio libraries, email takeouts, document corpora, chat exports, API dumps) into brain pages at scale. The lifecycle spine: SCHEMA → ACCESS → TRIAL → EVALUATE → IMPROVE → CODIFY → TEST → SKILLIFY → BULK → MONITOR. State is tracked in a durable JSON manifest (see MANIFEST-PATTERN.md) so any crash, session boundary, or subagent fan-out resumes from ground truth instead of memory.

Computed 10025,136

alirezarezvani/claude-skills

app-store-optimization

App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist

Computed 1005,277

dotnet/skills

migrate-vstest-to-mtp

Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions EnableMSTestRunner, EnableNUnitRunner, or UseMicrosoftTestingPlatformRunner. USE FOR: MTP behavioral differences vs VSTest (exit code 8, zero tests discovered, --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE); centralizing