agentsclimarketplace

Sync to notion doc

Skill talgacapri/pm-os/.claude/skills/sync-to-notion-doc

AI operating system for product managers. 65 Claude Code skills, 7 multi-perspective review agents, a memory system. Battle-tested in real PM work.

Install
npx -y skills add talgacapri/pm-os --skill sync-to-notion-doc

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Sync finalized Markdown documents from PM-OS to the Notion Documentation DB. Detects, classifies, converts, and pushes MD files as properly formatted Notion pages.

SKILL.md

11.6 KB, ~3.0k tokens by cl100k_base, as published. Nobody here has run it

Quick Start

/sync-to-notion                                        → Scan notion-docs/ for unsynced files
/sync-to-notion notion-docs/my-doc.md                  → Sync a specific file from the staging folder
/sync-to-notion outputs/launches/alpha-plan.md         → Sync a file directly from outputs

What you get: A Notion page in the Documentation DB with the correct Document Type, formatted content, and a sync record in the local file's YAML frontmatter.

Sync target: Notion Documentation DB at https://www.notion.so/Docs-2176409321d9814b8107ea8f9943e76f

  • Data source ID: 21764093-21d9-81a8-baca-000b9e5d9228

Time: 1-2 minutes per document.


/sync-to-notion - Notion Document Sync

Purpose

Push finalized Markdown documents from PM-OS to the Notion Documentation DB as properly formatted pages. Supports both new page creation and updates to previously synced pages.

Invocation Patterns

This skill supports three invocation styles:

  1. Explicit file path: /sync-to-notion path/to/file.md syncs a single specific file.
  2. Folder scan: /sync-to-notion-doc (no arguments) scans notion-docs/ for any MD files that have not been synced yet (no notion_page_id in their YAML frontmatter).
  3. Post-workflow prompt: After any PM-OS skill creates a file in outputs/, offer: "Want me to push this to Notion?"

Workflow

Step 1: Detect and Read the MD File

If a file path is provided:

  • Read the file at the given path.
  • If it does not exist, tell the user and stop.

If no file path is provided (folder scan):

  • List all .md files in notion-docs/ (excluding README.md).
  • For each file, check the YAML frontmatter for a notion_page_id field.
  • Files without notion_page_id are unsynced. Present the list and ask the user which ones to sync (or sync all).
  • If no unsynced files exist, tell the user and stop.

Check for existing sync record:

  • If the file already has notion_page_id in its YAML frontmatter, this is an update, not a create. Note the notion_page_id for Step 5.

Step 2: Classify the Document Type

Map the file to one of the Notion Documentation DB's Document Type values by analyzing the file's source path and content.

Classification rules (in priority order):

SignalDocument Type
Path contains prds/ or content has PRD structure (hypothesis, success metrics, rollout)PRD
Path contains launches/ or content has launch/testing/checklist structureSpecification
Path contains research-synthesis/ or research/ or content is user researchUser Research
Path contains decisions/ or content has decision log structureDiscovery
Path contains strategy/ or content is strategy, OKR, roadmapStrategy
Content describes a process, SOP, or operational procedureStandard Operating Procedure (SOP)
Content is a policy, privacy doc, compliance, or regulatoryPolicy
Content is a technical standard, API spec, or engineering standardStandard
None of the aboveAsk the user to choose

Always confirm the classification with the user before proceeding. Present it as:

I've classified this as [Document Type]. Does that look right, or would you prefer a different type?

Options: Specification, Discovery, PRD, Policy, Standard, Standard Operating Procedure (SOP), Strategy, User Research


Step 3: Set Document Status

Default to "Draft" unless the user specifies otherwise.

Ask: "Document status? Default is Draft."

Valid values: Draft, Dev Review, Approved for Dev, In Dev, In Production, Archived


Step 4: Convert MD to Notion-Flavored Markdown

Before converting, fetch the Enhanced Markdown Specification to get the exact syntax:

FetchMcpResource: server=user-Notion, uri=notion://docs/enhanced-markdown-spec

Conversion rules:

  1. Strip YAML frontmatter. Remove any existing --- delimited YAML block from the top of the file. The frontmatter is metadata for PM-OS, not Notion content.

  2. Extract the document title. Use the first # Heading in the document as the Name property. Remove it from the body content (Notion shows the title separately above the page content).

  3. Convert standard Markdown tables to Notion table format. Standard Markdown tables (| col1 | col2 |) must be converted to Notion's XML table format:

    <table header-row="true">
    	<tr>
    		<td>Header 1</td>
    		<td>Header 2</td>
    	</tr>
    	<tr>
    		<td>Cell 1</td>
    		<td>Cell 2</td>
    	</tr>
    </table>
    
  4. Preserve code blocks as-is. Notion supports standard fenced code blocks. Do NOT escape special characters inside code blocks.

  5. Convert horizontal rules. Standard --- becomes a Notion divider (same syntax, but make sure it is on its own line with blank lines around it).

  6. Preserve headings, lists, bold, italic, strikethrough, links, and inline code. These are compatible between standard Markdown and Notion-flavored Markdown.

  7. Convert checkboxes. - [ ] and - [x] are natively supported.

  8. Strip any HTML that Notion does not support. If the source MD contains raw HTML (e.g., <br>, <div>), convert <br> to Notion's <br> (same), and strip unsupported tags.

  9. Do NOT include the page title in the body content. The title goes into the Name property only.


Step 5: Create or Update the Page in Notion

For new pages (no existing notion_page_id):

Use CallMcpTool with notion-create-pages:

{
  "server": "user-Notion",
  "toolName": "notion-create-pages",
  "arguments": {
    "parent": {
      "data_source_id": "21764093-21d9-81a8-baca-000b9e5d9228"
    },
    "pages": [
      {
        "properties": {
          "Name": "<document title>",
          "Document Type": "<classified type>",
          "Document Status": "<status, default Draft>"
        },
        "content": "<converted Notion-flavored markdown body>"
      }
    ]
  }
}

For updates (existing notion_page_id in frontmatter):

Use CallMcpTool with notion-update-page:

{
  "server": "user-Notion",
  "toolName": "notion-update-page",
  "arguments": {
    "page_id": "<notion_page_id from frontmatter>",
    "command": "replace_content",
    "new_str": "<converted Notion-flavored markdown body>"
  }
}

Then update properties if they changed:

{
  "server": "user-Notion",
  "toolName": "notion-update-page",
  "arguments": {
    "page_id": "<notion_page_id from frontmatter>",
    "command": "update_properties",
    "properties": {
      "Name": "<document title>",
      "Document Type": "<classified type>",
      "Document Status": "<status>"
    }
  }
}

Step 6: Record the Sync

After a successful push, update the local MD file's YAML frontmatter.

If the file has no frontmatter yet, add one at the top:

---
notion_page_id: "<page ID returned by Notion>"
notion_url: "<Notion page URL>"
document_type: "<classified type>"
synced_at: "<ISO 8601 timestamp>"
---

If the file already has frontmatter, update these fields:

  • notion_page_id - keep the same (or set for first sync)
  • notion_url - keep the same (or set for first sync)
  • document_type - update if changed
  • synced_at - update to current timestamp

This frontmatter is what enables idempotent syncs. On the next /sync-to-notion-doc run, the skill detects the notion_page_id and updates instead of creating a duplicate.


Step 7: Confirm to User

After a successful sync, report:

Synced to Notion.

  • Page: Document Title
  • Type: Document Type
  • Status: Document Status
  • Action: Created new page / Updated existing page

If multiple files were synced (folder scan), provide a summary table.


Error Handling

ErrorAction
File not foundTell the user the path does not exist
Notion MCP not connectedTell the user to run /connect-mcps connect to notion
Notion API error on createShow the error, suggest checking the Notion workspace permissions
Notion API error on update (page not found)The page may have been deleted in Notion. Ask the user if they want to create a new page instead. Remove the stale notion_page_id from frontmatter.
File has no content (empty)Tell the user the file is empty and skip

Duplicate Prevention

The skill uses notion_page_id in the local file's YAML frontmatter as the single source of truth for sync state.

  • No notion_page_id = new page, use notion-create-pages
  • Has notion_page_id = existing page, use notion-update-page

Before creating a new page, optionally search Notion for a page with the same title to warn about potential duplicates:

{
  "server": "user-Notion",
  "toolName": "notion-search",
  "arguments": {
    "query": "<document title>",
    "data_source_url": "collection://21764093-21d9-81a8-baca-000b9e5d9228"
  }
}

If a match is found, ask: "A page with this title already exists in Notion. Do you want to update it or create a new one?"


Notion Documentation DB Schema Reference

The target database uses this schema:

PropertyTypeValues
NametitleDocument name (from first H1)
Document TypeselectSpecification, Discovery, PRD, Policy, Standard, Standard Operating Procedure (SOP), Strategy, User Research
Document StatusselectDraft, Dev Review, Approved for Dev, In Dev, In Production, Archived
Product Leadperson(optional, set manually in Notion)
Engineering Leadperson(optional, set manually in Notion)
UX Leadperson(optional, set manually in Notion)
GTM Leadperson(optional, set manually in Notion)
Ownerperson(optional, set manually in Notion)
Authorperson(optional, set manually in Notion)
Document Version (1)text(optional, can be set if version info is in frontmatter)

Person fields require Notion user IDs and cannot be set from Markdown content. They should be assigned manually in Notion after sync.


Integration with Other Skills

This skill works with every skill that creates files in outputs/:

  • /prd-draft creates files in outputs/prds/ -> classify as PRD
  • /launch-checklist creates files in outputs/launches/ -> classify as Specification
  • /user-research-synthesis creates files in outputs/research-synthesis/ -> classify as User Research
  • /decision-doc creates files in outputs/decisions/ -> classify as Discovery
  • /write-prod-strategy creates files in outputs/roadmaps/ or strategy docs -> classify as Strategy
  • /status-update creates files in outputs/status-updates/ -> classify as Specification

After any of these skills completes, the assistant can offer: "Want me to push this to Notion?"

The user can either:

  1. Say yes to sync immediately from outputs/.
  2. Move the file to notion-docs/ first and sync later.

Notion-Flavored Markdown Quick Reference

For the complete spec, always fetch: notion://docs/enhanced-markdown-spec

Key differences from standard Markdown:

  • Tables use XML (<table>, <tr>, <td>) not pipe syntax
  • Toggles use <details> / <summary>
  • Callouts use <callout icon="emoji">
  • Colors use {color="Color"} attribute on blocks or <span color="Color"> for inline
  • Empty lines need <empty-block/> (blank lines are stripped)
  • Indentation uses tabs, not spaces
  • Page title goes in properties, not in page content

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.