Skip to content

Latest commit

 

History

History
131 lines (98 loc) · 5.19 KB

File metadata and controls

131 lines (98 loc) · 5.19 KB

Notion Agent Instruction Updater

A Python CLI for programmatically updating and publishing Notion AI Agent instructions, bypassing the public API's inability to access workflow-parented blocks.

Background

Notion AI Agents store their instruction pages under parent_table: workflow — an internal type not exposed by the public Notion API. This means tools like Gemini, Claude, and external MCP integrations cannot read or write these pages through normal means.

This tool uses two internal endpoints discovered via browser network interception:

  • POST /api/v3/saveTransactionsFanout — edit block content
  • POST /api/v3/publishCustomAgentVersion — deploy the updated agent

Auth is handled by reading your existing Firefox session cookie (token_v2) — no separate credentials needed.

Requirements

  • Python 3.11+
  • Firefox with an active Notion session (logged in)
  • pyyaml: pip install pyyaml

Setup

  1. Add your agents to cli/agents.yaml (the Librarian is pre-populated).

    To find IDs for a new agent, run this in the Notion browser console while on the agent's instruction page:

    fetch('/api/v3/getRecordValues', {
      method: 'POST', headers: {'Content-Type':'application/json'},
      body: JSON.stringify({requests:[{id:'<page-id-from-url>',table:'block'}]})
    }).then(r=>r.json()).then(d=>{
      const v = d.results[0].value;
      console.log('parent_id (workflow_id):', v.parent_id);
      console.log('block_id:', v.id);
      console.log('space_id:', v.space_id);
    });
  2. Run from the project root.

Usage

# Update instructions and publish
python cli/update_agent.py librarian path/to/instructions.md

# Dry-run — print payloads, no API calls
python cli/update_agent.py librarian path/to/instructions.md --dry-run

# Update content without publishing
python cli/update_agent.py librarian path/to/instructions.md --no-publish

# Re-publish without changing content
python cli/update_agent.py librarian --publish-only

# Dump current instructions as Markdown
python cli/update_agent.py librarian --dump

For External Agents (Gemini, Claude)

This CLI is designed to be callable as a tool from AI agent frameworks:

# Example tool definition for an external agent
def update_notion_agent(agent_name: str, instructions_markdown: str) -> str:
    import tempfile, subprocess
    with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
        f.write(instructions_markdown)
        tmp = f.name
    result = subprocess.run(
        ['python', 'cli/update_agent.py', agent_name, tmp],
        capture_output=True, text=True,
        cwd='/home/sam/projects/notion-forge'
    )
    return result.stdout + result.stderr

If the agent is calling the notion-agents MCP server directly, prefer the file-based update_agent_from_file tool for long instruction documents. The Notion write path is the same, but the MCP request stays small instead of embedding the full Markdown body inline.

MCP Operational Notes

Use lab_query for broad read-only Lab questions where a direct database query would return a large payload. It runs on MiniMax M2.5 (fireworks-minimax-m2.5) and acts as a compressed, Exa-like query surface over Notion. Its answers must preserve the canonical answer set: exact counts should state exact totals, matched counts, scanned counts, or limits, and it must not call a view/search subset a full database total.

For direct MCP database work, call describe_database before query_database when property names or property types are uncertain. Use count_database with exact=True for precise counts instead of inferring totals from a single query_database page.

Lab dispatch returns are exposed as two MCP paths:

  • handle_final_return — normal execution-plane return ingestion when a dispatch packet and run_id exist.
  • direct_closeout_return — fallback closeout when no GitHub issue, dispatch packet, or trusted run_id is available. It generates an idempotency key if needed, appends result blocks, and stamps Return Received At / Return Consumed At so the Intake Clerk can continue the pipeline.

Supported Markdown

The instruction file should be standard Markdown:

Syntax Block type
# Heading H1
## Heading H2
### Heading H3
- item Bulleted list
1. item Numbered list
```code``` Code block
> text Callout
--- Divider
Plain text Paragraph
**bold** *italic* `code` Inline formatting

Security Note

token_v2 is a long-lived browser session token that grants full access to your Notion workspace. This tool reads it directly from Firefox's local SQLite store and uses it only for the API calls you trigger. It is never logged, stored, or transmitted elsewhere. If you are concerned, revoke the session in Notion's settings after use.

FOSS Credits