@andrzejchm/notion-cli 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,7 @@
18
18
  | Page create | Under pages only | Under pages, databases, data sources; batch; templates; icon/cover | Partial |
19
19
  | Page edit | Multi-op `--find`/`--replace`, `--range` | Search-and-replace (multi-op), full replace, template apply, verification | Partial |
20
20
  | Page properties | Read + write via `update --prop` | Full read + write (update any property) | ✅ Parity |
21
- | Move pages | - | Batch move to any parent | Gap |
21
+ | Move pages | `move --to` / `--to-db` | Batch move to any parent | Parity |
22
22
  | Duplicate pages | - | Duplicate with async content copy | Gap |
23
23
  | Archive/delete | `archive` | Trash pages | ✅ Parity |
24
24
  | Database create | `db create --prop` syntax | SQL DDL `CREATE TABLE` syntax | Partial |
@@ -74,11 +74,10 @@ These gaps directly limit what an AI agent can accomplish through the CLI compar
74
74
  **CLI:** `notion db create --parent <id> --title "Tasks" --prop "Status:select:To Do,Done"` — supports title, rich_text, number, select, multi_select, status, date, checkbox, url, email, phone_number, people, files, created_time, last_edited_time. Relation, rollup, formula, and unique_id are not supported (too complex for CLI flags).
75
75
  **Status:** Shipped in v0.10.0.
76
76
 
77
- #### 7. Move pages
77
+ #### 7. Move pages (shipped v0.11.0)
78
78
  **MCP:** Batch move up to 100 pages/databases to a new parent (page, database, data source, or workspace).
79
- **CLI:** No equivalent.
80
- **Why:** Reorganizing content (moving completed items to archive, restructuring projects) is a common agent task.
81
- **Suggested command:** `notion move <id...> --to <parent-id>`
79
+ **CLI:** `notion move <ids...> --to <page-id>` or `notion move <ids...> --to-db <database-id>`. Supports multiple page IDs as variadic arguments.
80
+ **Status:** Shipped in v0.11.0.
82
81
 
83
82
  #### 8. Update database schema
84
83
  **MCP:** `ADD COLUMN`, `DROP COLUMN`, `RENAME COLUMN`, `ALTER COLUMN SET` via DDL.
@@ -30,7 +30,7 @@ The skill file teaches your AI agent how to use notion-cli. It follows the open
30
30
 
31
31
  **Skill URL:**
32
32
  ```
33
- https://raw.githubusercontent.com/andrzejchm/notion-cli/main/docs/skills/using-notion-cli/SKILL.md
33
+ https://raw.githubusercontent.com/andrzejchm/notion-cli/main/.agents/skills/using-notion-cli/SKILL.md
34
34
  ```
35
35
 
36
36
  **Agent:** Ask the user whether they want the skill installed **globally** (all projects) or **per-project**, then consult your own documentation for the correct skill install path. The skill directory name must be `using-notion-cli` and the file must be named `SKILL.md`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andrzejchm/notion-cli",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "description": "Read Notion pages and databases from the terminal. Built for AI agents and developers.",
5
5
  "keywords": [
6
6
  "notion",
@@ -1,256 +0,0 @@
1
- ---
2
- name: using-notion-cli
3
- description: Reads and writes Notion pages using the `notion` CLI tool. Use when accessing Notion content, searching workspace pages, querying database entries, reading page markdown, appending content, creating pages, or adding comments from the terminal or within automated workflows.
4
- ---
5
-
6
- ## Setup
7
-
8
- Install once:
9
- ```bash
10
- npm install -g @andrzejchm/notion-cli
11
- notion auth login # interactive setup — choose OAuth or integration token
12
- ```
13
-
14
- Or set env var (preferred for CI/agents):
15
- ```bash
16
- export NOTION_API_TOKEN=ntn_your_token_here
17
- ```
18
-
19
- Get token: https://www.notion.so/profile/integrations/internal
20
-
21
- Pages must be shared with your integration: open page → `⋯` → **Add connections**.
22
-
23
- **Integration capabilities** (set at notion.so/profile/integrations/internal → your integration → Capabilities):
24
- - Read-only commands: **Read content** only
25
- - `notion append`, `notion append --after`, `notion create-page` (page parent): also need **Insert content**
26
- - `notion create-page --parent <db>`: also need **Insert content** + database must be shared with integration
27
- - `notion edit-page`: also need **Update content** + **Insert content**
28
- - `notion comment`: also need **Read comments** + **Insert comments**
29
-
30
- ---
31
-
32
- ## Authentication
33
-
34
- Two auth methods are available. If both are configured, **OAuth takes precedence**.
35
-
36
- | Method | Command | Attribution | Notes |
37
- |--------|---------|-------------|-------|
38
- | Interactive setup | `notion auth login` | — | Guides you to choose; TTY required |
39
- | OAuth user login | select "OAuth user login" in `notion auth login` | Your Notion account | Browser required; `--manual` for headless |
40
- | Integration token | select "Integration token" in `notion auth login` | Integration bot | Works in CI/headless; must connect integration to pages |
41
-
42
- ```bash
43
- notion auth login # interactive selector — OAuth or integration token
44
- notion auth login --manual # headless OAuth (prints URL, paste redirect back)
45
- notion auth status # show current auth state
46
- notion auth logout # remove a profile (interactive selector)
47
- notion auth logout --profile <name> # remove specific profile directly
48
- notion auth list # list all saved profiles
49
- notion auth use <name> # switch active profile
50
- ```
51
-
52
- **Headless/CI agents:** Use `NOTION_API_TOKEN=<token>` env var — overrides all config, no TTY needed.
53
-
54
- ---
55
-
56
- ## Output Modes
57
-
58
- | Context | Default | Override |
59
- |---------|---------|----------|
60
- | Terminal (TTY) | Formatted tables | `--json` |
61
- | Piped / agent | Plain text tables | `--json` |
62
-
63
- `notion read` always outputs **markdown** — in terminal and when piped.
64
-
65
- Pipe any command to get JSON:
66
- ```bash
67
- notion search "query" | jq '.[0].id'
68
- notion ls | jq '.[] | select(.type == "database")'
69
- ```
70
-
71
- ---
72
-
73
- ## Commands
74
-
75
- ### Search & Discovery
76
-
77
- ```bash
78
- notion search "query" # search all pages/databases by title
79
- notion search "query" --type page # pages only
80
- notion search "query" --type database # databases only
81
- notion ls # list everything accessible to integration
82
- notion users # list workspace members
83
- notion comments <id|url> # list page comments
84
- notion open <id|url> # open in browser
85
- ```
86
-
87
- ### Reading Pages
88
-
89
- ```bash
90
- notion read <id|url> # markdown (always, even when piped)
91
- notion read <id|url> --json # raw Notion JSON block tree
92
- ```
93
-
94
- ### Database Operations
95
-
96
- ```bash
97
- notion db schema <id|url> # inspect properties + valid values
98
- notion db query <id|url> # all rows
99
- notion db query <id|url> --filter "Status=Done" # filter (repeatable)
100
- notion db query <id|url> --sort "Created:desc" # sort (repeatable)
101
- notion db query <id|url> --columns "Title,Status" # limit columns
102
- notion db query <id|url> --json | jq '.[] | .properties'
103
- ```
104
-
105
- ### Write Operations
106
-
107
- ```bash
108
- notion append <id|url> -m "## Heading\nParagraph text" # append markdown blocks to a page
109
- notion append <id|url> -m "$(cat notes.md)" # append file contents
110
-
111
- notion create-page --parent <page-id|url> --title "Title" # child page under a page
112
- notion create-page --parent <page-id|url> --title "Title" -m "# Hello" # with markdown body
113
- echo "# Content" | notion create-page --parent <page-id|url> --title "Title" # from stdin
114
-
115
- # Create entry in a database (auto-detected from parent ID)
116
- notion create-page --parent <db-id|url> --title "New Task"
117
- notion create-page --parent <db-id|url> --title "Task" --prop "Status=To Do" --prop "Priority=High"
118
- notion create-page --parent <db-id|url> --title "Task" --prop "Due=2026-04-01" -m "# Details"
119
-
120
- # Icon and cover
121
- notion create-page --parent <id|url> --title "Page" --icon "🚀"
122
- notion create-page --parent <id|url> --title "Page" --cover "https://example.com/img.jpg"
123
-
124
- URL=$(notion create-page --parent <id|url> --title "Summary" -m "...") # capture URL
125
-
126
- notion comment <id|url> -m "Reviewed and approved." # add comment to a page
127
- ```
128
-
129
- #### Updating Page Properties
130
-
131
- ```bash
132
- notion update <id|url> --prop "Status=Done" # set a single property
133
- notion update <id|url> --prop "Status=Done" --prop "Priority=1" # multiple properties
134
- notion update <id|url> --title "New Title" # set the title
135
- notion update <id|url> --prop "Due=2026-04-01" # set a date
136
- notion update <id|url> --prop "Tags=bug,urgent" # multi-select (comma-separated)
137
- notion update <id|url> --prop "Done=true" # checkbox (true/yes/false/no)
138
- notion update <id|url> --prop "Status=" # clear a property (empty value)
139
- ```
140
-
141
- Supported types: title, rich_text, select, status, multi_select, number, checkbox, url, email, phone_number, date.
142
-
143
- #### Surgical Editing
144
-
145
- Search-and-replace specific text, replace the full page, or insert content at a specific location.
146
-
147
- ```bash
148
- # Search-and-replace: find text and replace it
149
- notion edit-page <id|url> --find "old text" --replace "new text"
150
-
151
- # Multiple search-and-replace operations in one call
152
- notion edit-page <id|url> --find "old1" --replace "new1" --find "old2" --replace "new2"
153
-
154
- # Replace all occurrences (not just the first match)
155
- notion edit-page <id|url> --find "TODO" --replace "DONE" --all
156
-
157
- # Replace an entire page's content
158
- notion edit-page <id|url> -m "# Replacement\nNew full-page content"
159
-
160
- # Pipe replacement content from a file
161
- cat updated-section.md | notion edit-page <id|url>
162
-
163
- # Allow deletion of child pages/databases during replace
164
- notion edit-page <id|url> -m "## Clean Slate" --allow-deleting-content
165
-
166
- # Append after a matched section (inserts new blocks right after the match)
167
- notion append <id|url> -m "New content" --after "## Status...end of status"
168
- ```
169
-
170
- > **`--range` (deprecated):** The `--range` flag still works for backward compatibility but uses the older `replace_content_range` API. Prefer `--find`/`--replace` for targeted edits.
171
-
172
- ---
173
-
174
- ## ID Formats
175
-
176
- All commands accept any of:
177
- - `abc123def456789012345678901234ab` (32-char hex)
178
- - `abc123de-f456-7890-1234-5678901234ab` (UUID)
179
- - `https://www.notion.so/workspace/Page-Title-abc123` (full URL)
180
-
181
- ---
182
-
183
- ## Agent Patterns
184
-
185
- ```bash
186
- # Find page by title, read it
187
- PAGE_ID=$(notion search "Meeting Notes" --type page | jq -r '.[0].id')
188
- notion read "$PAGE_ID"
189
-
190
- # Get database ID, then query with filter
191
- DB_ID=$(notion search "Project Tracker" --type database | jq -r '.[0].id')
192
- notion db query "$DB_ID" --filter "Status=In Progress" | jq '.[] | .properties'
193
-
194
- # Always check schema before filtering (see valid property names/values)
195
- notion db schema "$DB_ID"
196
- notion db query "$DB_ID" --filter "Status=Done"
197
-
198
- # Extract page section
199
- notion read "$PAGE_ID" | grep -A 10 "## Action Items"
200
-
201
- # Summarize a page and append the summary back
202
- SUMMARY=$(notion read "$PAGE_ID" | your-summarize-command)
203
- notion append "$PAGE_ID" -m "## AI Summary\n$SUMMARY"
204
-
205
- # Create a page and capture its URL for further use
206
- URL=$(notion create-page --parent "$PAGE_ID" --title "Report $(date +%Y-%m-%d)" -m "# Report\n...")
207
- echo "Created: $URL"
208
-
209
- # Pipe command output into a new page
210
- my-report-command | notion create-page --parent "$PAGE_ID" --title "Auto Report"
211
-
212
- # Surgically update specific text on a page
213
- # 1. Read the page to find the text you want to change
214
- notion read "$PAGE_ID"
215
- # 2. Use --find/--replace to swap specific text
216
- notion edit-page "$PAGE_ID" --find "Status: In Progress" --replace "Status: Done"
217
-
218
- # Multiple replacements in one call
219
- notion edit-page "$PAGE_ID" \
220
- --find "Status: In Progress" --replace "Status: Done" \
221
- --find "Blocked: yes" --replace "Blocked: none"
222
-
223
- # Create a database entry with properties
224
- DB_ID=$(notion search "Tasks" --type database | jq -r '.[0].id')
225
- notion db schema "$DB_ID" # check property names and valid values first
226
- notion create-page --parent "$DB_ID" --title "Fix login bug" \
227
- --prop "Status=To Do" --prop "Priority=High" --prop "Due=2026-04-15"
228
-
229
- # Insert a new sub-section after an existing section
230
- notion append "$PAGE_ID" -m "## New Sub-section\nContent here" \
231
- --after "## Existing Section...last line of section"
232
- ```
233
-
234
- ---
235
-
236
- ## Troubleshooting
237
-
238
- **404 / page not found** — Share the page with your integration: page → `⋯` → **Add connections**.
239
-
240
- **401 / unauthorized** — Run `notion auth login` or set `NOTION_API_TOKEN`.
241
-
242
- **Search returns nothing** — Search is title-only. Page must be shared with integration.
243
-
244
- **Empty db query** — Run `notion db schema <id>` to see valid property names and values.
245
-
246
- **`notion auth login` requires TTY** — Use `NOTION_API_TOKEN` env var in agents, or use `notion auth login --manual` for headless OAuth.
247
-
248
- **`notion comment` returns "Insufficient permissions"** — Enable **Read comments** + **Insert comments** in integration capabilities: notion.so/profile/integrations/internal → your integration → Capabilities.
249
-
250
- **`notion append` / `notion create-page` returns "Insufficient permissions"** — Enable **Insert content** in integration capabilities.
251
-
252
- **`notion edit-page` returns "Insufficient permissions"** — Enable **Update content** in integration capabilities.
253
-
254
- **`--find` text not found** — Run `notion read <id>` to see the exact page content. The `--find` value must match text on the page exactly.
255
-
256
- **`--after` selector not found** — Run `notion read <id>` to see the exact page content. The selector must match real text: `"start...end"` with ~10 chars from the beginning and end of the target range.