atris/skills/notion/SKILL.md
Notion integration via AtrisOS API. Search pages, read/create/update pages, query databases, manage blocks and comments. Use when user asks about Notion, pages, databases, wikis, or docs.
npx skillsauth add atrislabs/atris notionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Drop this in
~/.claude/skills/notion/SKILL.mdand Claude Code becomes your Notion assistant.
Before any Notion operation, run this bootstrap to ensure everything is set up:
#!/bin/bash
set -e
# 1. Check if atris CLI is installed
if ! command -v atris &> /dev/null; then
echo "Installing atris CLI..."
npm install -g atris
fi
# 2. Check if logged in to AtrisOS
if [ ! -f ~/.atris/credentials.json ]; then
echo "Not logged in to AtrisOS."
echo ""
echo "Option 1 (interactive): Run 'atris login' and follow prompts"
echo "Option 2 (non-interactive): Get token from https://atris.ai/auth/cli"
echo " Then run: atris login --token YOUR_TOKEN"
echo ""
exit 1
fi
# 3. Extract token
if command -v node &> /dev/null; then
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
elif command -v python3 &> /dev/null; then
TOKEN=$(python3 -c "import json,os; print(json.load(open(os.path.expanduser('~/.atris/credentials.json')))['token'])")
elif command -v jq &> /dev/null; then
TOKEN=$(jq -r '.token' ~/.atris/credentials.json)
else
echo "Error: Need node, python3, or jq to read credentials"
exit 1
fi
# 4. Check Notion connection status
STATUS=$(curl -s "https://api.atris.ai/api/integrations/notion/status" \
-H "Authorization: Bearer $TOKEN")
if echo "$STATUS" | grep -q "Token expired\|Not authenticated"; then
echo "Token expired. Please re-authenticate:"
echo " Run: atris login --force"
exit 1
fi
if command -v node &> /dev/null; then
CONNECTED=$(node -e "try{console.log(JSON.parse('$STATUS').connected||false)}catch(e){console.log(false)}")
elif command -v python3 &> /dev/null; then
CONNECTED=$(echo "$STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin).get('connected', False))")
else
CONNECTED=$(echo "$STATUS" | jq -r '.connected // false')
fi
if [ "$CONNECTED" != "true" ] && [ "$CONNECTED" != "True" ]; then
echo "Notion not connected. Getting authorization URL..."
AUTH=$(curl -s -X POST "https://api.atris.ai/api/integrations/notion/start" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"return_url":"https://atris.ai/dashboard/settings"}')
if command -v node &> /dev/null; then
URL=$(node -e "try{console.log(JSON.parse('$AUTH').auth_url||'')}catch(e){console.log('')}")
elif command -v python3 &> /dev/null; then
URL=$(echo "$AUTH" | python3 -c "import sys,json; print(json.load(sys.stdin).get('auth_url', ''))")
else
URL=$(echo "$AUTH" | jq -r '.auth_url // empty')
fi
echo ""
echo "Open this URL to connect your Notion:"
echo "$URL"
echo ""
echo "After authorizing, run your command again."
exit 0
fi
echo "Ready. Notion is connected."
export ATRIS_TOKEN="$TOKEN"
Base: https://api.atris.ai/api/integrations
All requests require: -H "Authorization: Bearer $TOKEN"
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
curl -s "https://api.atris.ai/api/integrations/notion/search?q=meeting+notes&page_size=20" \
-H "Authorization: Bearer $TOKEN"
Filter by type:
# Only pages
curl -s "https://api.atris.ai/api/integrations/notion/search?q=roadmap&filter_type=page" \
-H "Authorization: Bearer $TOKEN"
# Only databases
curl -s "https://api.atris.ai/api/integrations/notion/search?q=tasks&filter_type=database" \
-H "Authorization: Bearer $TOKEN"
curl -s "https://api.atris.ai/api/integrations/notion/pages/{page_id}" \
-H "Authorization: Bearer $TOKEN"
curl -s -X POST "https://api.atris.ai/api/integrations/notion/pages" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"parent_id": "PARENT_PAGE_ID",
"parent_type": "page_id",
"title": "Meeting Notes - Feb 14"
}'
curl -s -X POST "https://api.atris.ai/api/integrations/notion/pages" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"parent_id": "DATABASE_ID",
"parent_type": "database_id",
"title": "New Task",
"properties": {
"Status": {"select": {"name": "In Progress"}},
"Priority": {"select": {"name": "High"}}
}
}'
curl -s -X POST "https://api.atris.ai/api/integrations/notion/pages" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"parent_id": "PARENT_PAGE_ID",
"parent_type": "page_id",
"title": "Project Brief",
"children": [
{
"object": "block",
"type": "heading_2",
"heading_2": {"rich_text": [{"type": "text", "text": {"content": "Overview"}}]}
},
{
"object": "block",
"type": "paragraph",
"paragraph": {"rich_text": [{"type": "text", "text": {"content": "This project aims to..."}}]}
},
{
"object": "block",
"type": "bulleted_list_item",
"bulleted_list_item": {"rich_text": [{"type": "text", "text": {"content": "Goal 1: Ship MVP"}}]}
}
]
}'
curl -s -X PATCH "https://api.atris.ai/api/integrations/notion/pages/{page_id}" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"Status": {"select": {"name": "Done"}}
}
}'
curl -s -X PATCH "https://api.atris.ai/api/integrations/notion/pages/{page_id}" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"archived": true}'
curl -s "https://api.atris.ai/api/integrations/notion/databases/{database_id}" \
-H "Authorization: Bearer $TOKEN"
curl -s -X POST "https://api.atris.ai/api/integrations/notion/databases/{database_id}/query" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"page_size": 20}'
With filters:
curl -s -X POST "https://api.atris.ai/api/integrations/notion/databases/{database_id}/query" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filter": {
"property": "Status",
"select": {"equals": "In Progress"}
},
"sorts": [
{"property": "Created", "direction": "descending"}
],
"page_size": 50
}'
curl -s -X POST "https://api.atris.ai/api/integrations/notion/databases" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"parent_page_id": "PAGE_ID",
"title": "Task Tracker",
"properties": {
"Name": {"title": {}},
"Status": {"select": {"options": [{"name": "To Do"}, {"name": "In Progress"}, {"name": "Done"}]}},
"Priority": {"select": {"options": [{"name": "High"}, {"name": "Medium"}, {"name": "Low"}]}},
"Due Date": {"date": {}}
}
}'
curl -s "https://api.atris.ai/api/integrations/notion/blocks/{page_id}/children?page_size=50" \
-H "Authorization: Bearer $TOKEN"
curl -s -X PATCH "https://api.atris.ai/api/integrations/notion/blocks/{page_id}/children" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"children": [
{
"object": "block",
"type": "paragraph",
"paragraph": {"rich_text": [{"type": "text", "text": {"content": "Added via Atris!"}}]}
}
]
}'
curl -s -X DELETE "https://api.atris.ai/api/integrations/notion/blocks/{block_id}" \
-H "Authorization: Bearer $TOKEN"
curl -s "https://api.atris.ai/api/integrations/notion/users" \
-H "Authorization: Bearer $TOKEN"
curl -s "https://api.atris.ai/api/integrations/notion/me" \
-H "Authorization: Bearer $TOKEN"
curl -s "https://api.atris.ai/api/integrations/notion/comments/{page_id}" \
-H "Authorization: Bearer $TOKEN"
curl -s -X POST "https://api.atris.ai/api/integrations/notion/comments" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"parent_id": "PAGE_ID",
"text": "This looks great! Approved."
}'
curl -s -X POST "https://api.atris.ai/api/integrations/notion/comments" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"parent_id": "PAGE_ID",
"text": "Thanks for the feedback!",
"discussion_id": "DISCUSSION_ID"
}'
GET /notion/search?q=XGET /notion/search?q=tasks&filter_type=databasePOST /notion/databases/{id}/query with filtersGET /notion/search?q=parent+name&filter_type=pagePOST /notion/pages with title + children blocksGET /notion/databases/{id} (to see property names/types)POST /notion/pages with parent_type=database_id and matching propertiesGET /notion/pages/{id}GET /notion/blocks/{id}/childrenPATCH /notion/pages/{id} with new property valuesCommon block types for creating content:
| Type | Key | Rich text field |
|------|-----|----------------|
| Paragraph | paragraph | rich_text |
| Heading 1 | heading_1 | rich_text |
| Heading 2 | heading_2 | rich_text |
| Heading 3 | heading_3 | rich_text |
| Bullet list | bulleted_list_item | rich_text |
| Numbered list | numbered_list_item | rich_text |
| To-do | to_do | rich_text + checked |
| Code | code | rich_text + language |
| Quote | quote | rich_text |
| Divider | divider | (none) |
| Callout | callout | rich_text + icon |
12345678-abcd-1234-abcd-123456789abc. You can get them from URLs or search results| Error | Meaning | Solution |
|-------|---------|----------|
| Token expired | AtrisOS session expired | Run atris login |
| Notion not connected | OAuth not completed | Re-run bootstrap |
| 401 Unauthorized | Invalid/expired token | Run atris login |
| object_not_found | Page/database not shared with integration | Share the page with the Atris integration in Notion |
| validation_error | Bad request format | Check property names match database schema |
| restricted_resource | No access to resource | Share with Atris integration in Notion settings |
~/.atris/credentials.json): Your AtrisOS auth token, stored locally.# Setup (one time)
npm install -g atris && atris login
# Get token
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
# Check connection
curl -s "https://api.atris.ai/api/integrations/notion/status" -H "Authorization: Bearer $TOKEN"
# Search
curl -s "https://api.atris.ai/api/integrations/notion/search?q=meeting" -H "Authorization: Bearer $TOKEN"
# Read a page
curl -s "https://api.atris.ai/api/integrations/notion/pages/PAGE_ID" -H "Authorization: Bearer $TOKEN"
# Read page content
curl -s "https://api.atris.ai/api/integrations/notion/blocks/PAGE_ID/children" -H "Authorization: Bearer $TOKEN"
# Create a page
curl -s -X POST "https://api.atris.ai/api/integrations/notion/pages" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"parent_id":"PAGE_ID","parent_type":"page_id","title":"New Page"}'
# Query a database
curl -s -X POST "https://api.atris.ai/api/integrations/notion/databases/DB_ID/query" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"page_size":20}'
# List users
curl -s "https://api.atris.ai/api/integrations/notion/users" -H "Authorization: Bearer $TOKEN"
development
Wake a team member by name — 'gm <member>' or 'wake up <member>' — and run ONE closed-loop tick: boot, inbox, claim, one bounded slice, verify, commit+push, proof, receipt. Optionally dispatch the build to an engine (codex/cursor/devin). Triggers on: gm, good morning, wake up <member>, wake the team, run a tick as <member>.
development
Dispatch coding work to an installed terminal agent — Codex, Cursor, or Devin — as an interchangeable worker engine. Claude orchestrates: writes the bounded prompt, the engine builds, Claude verifies and lands. Triggers on: use codex, use cursor, use devin, engine, dispatch to, worker agent, second opinion build.
development
Live RL tuner for skills. Watches skill invocations, reads user reaction, proposes targeted SKILL.md overlay edits, requires explicit approval, writes scorecards. The in-session half of the skill-RL loop (Path B). Triggers on: tune, sharpen, skill feedback, that was shit, that was great, make X better.
development
Run one RL improvement tick on the workspace via POST /api/improve. Ships one verifiable change, scores it, writes the scorecard. The thing you pay for. Triggers on: improve, make this better, ship one thing, run a tick, get smarter.