@andrzejchm/notion-cli 0.1.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.
@@ -0,0 +1,475 @@
1
+ # Notion CLI — Agent Skill Reference
2
+
3
+ > **Audience:** AI coding agents (Claude Code, OpenCode, Codex) and developers.
4
+ > Use this reference to query Notion pages and databases directly from the terminal or within automated workflows.
5
+
6
+ The `notion` CLI provides read access to Notion workspaces via the official API. Agents can fetch page content as markdown, query structured databases as JSON, and discover workspace resources — all without leaving the shell.
7
+
8
+ ---
9
+
10
+ ## Table of Contents
11
+
12
+ 1. [Installation & Setup](#installation--setup)
13
+ 2. [Agent Setup by Platform](#agent-setup-by-platform)
14
+ 3. [Output Modes](#output-modes)
15
+ 4. [Command Reference](#command-reference)
16
+ - [Authentication](#authentication)
17
+ - [Search & Discovery](#search--discovery)
18
+ - [Page Reading](#page-reading)
19
+ - [Database Operations](#database-operations)
20
+ 5. [Common Agent Patterns](#common-agent-patterns)
21
+ 6. [ID and URL Formats](#id-and-url-formats)
22
+ 7. [Troubleshooting](#troubleshooting)
23
+
24
+ ---
25
+
26
+ ## Installation & Setup
27
+
28
+ ```bash
29
+ npm install -g @andrzejchm/notion-cli
30
+ notion init # interactive setup — enter your Notion integration token
31
+ ```
32
+
33
+ **Alternative: environment variable (preferred for CI and agent environments)**
34
+
35
+ ```bash
36
+ export NOTION_API_TOKEN=ntn_your_token_here
37
+ ```
38
+
39
+ Get your token at: https://www.notion.so/profile/integrations/internal
40
+
41
+ > **Integration access:** Each page or database your agent needs must be explicitly shared with your integration.
42
+ > In Notion: open the page → `⋯` menu → **Add connections** → select your integration.
43
+
44
+ ---
45
+
46
+ ## Agent Setup by Platform
47
+
48
+ ### Claude Code
49
+
50
+ Add to `CLAUDE.md`:
51
+
52
+ ```markdown
53
+ ## Notion Access
54
+
55
+ Use `notion` CLI to access Notion pages and databases.
56
+
57
+ - Auth: ensure `NOTION_API_TOKEN` is set, or run `notion init` once.
58
+ - Page content: `notion read <id>` outputs markdown; pipe for JSON.
59
+ - Structured data: `notion db query <id> --json | jq '.[] | .properties'`
60
+ - See `docs/agent-skill.md` for full command reference and patterns.
61
+ ```
62
+
63
+ ### OpenCode
64
+
65
+ Add to `.opencode/config.json`:
66
+
67
+ ```json
68
+ {
69
+ "tools": ["bash"],
70
+ "instructions": "notion CLI is available for Notion access. See docs/agent-skill.md for full usage."
71
+ }
72
+ ```
73
+
74
+ Ensure `NOTION_API_TOKEN` is set in your shell environment before starting OpenCode.
75
+
76
+ ### Codex / Generic Agents
77
+
78
+ Add to system prompt or `AGENTS.md`:
79
+
80
+ ```markdown
81
+ Available tool: `notion` CLI (npm install -g @andrzejchm/notion-cli)
82
+ Auth: set NOTION_API_TOKEN env var, or run `notion init` interactively.
83
+ See docs/agent-skill.md for commands, flags, and agent patterns.
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Output Modes
89
+
90
+ The CLI auto-detects context and adjusts output format:
91
+
92
+ | Context | Default Output | Override flag |
93
+ |-------------------|-----------------------------|--------------------|
94
+ | Terminal (TTY) | Formatted tables, colored | `--json` for JSON |
95
+ | Piped / agent | JSON | `--md` for markdown|
96
+
97
+ **For agents: pipe the command to get JSON automatically:**
98
+
99
+ ```bash
100
+ notion search "my query" | jq '.[]'
101
+ notion ls | jq '.[] | {id, title}'
102
+ notion db query "$DB_ID" | jq '.[] | .properties.Status'
103
+ ```
104
+
105
+ **For page content: markdown is always the default in both modes:**
106
+
107
+ ```bash
108
+ notion read "$PAGE_ID" # markdown output (works in terminal AND piped)
109
+ notion read "$PAGE_ID" --json # raw JSON block tree
110
+ ```
111
+
112
+ **Global flags** (apply to all commands):
113
+
114
+ | Flag | Effect |
115
+ |----------|----------------------------------------|
116
+ | `--json` | Force JSON output (overrides TTY mode) |
117
+ | `--md` | Force markdown output |
118
+
119
+ ---
120
+
121
+ ## Command Reference
122
+
123
+ ### Authentication
124
+
125
+ #### `notion init`
126
+
127
+ Interactive setup wizard. Prompts for a profile name and integration token, validates the token against the Notion API, and saves the profile.
128
+
129
+ ```bash
130
+ notion init
131
+ ```
132
+
133
+ - Must be run in a TTY (terminal). Use `NOTION_API_TOKEN` env var in non-interactive environments.
134
+ - On success: saves profile to `~/.notion.yaml` and sets it as active.
135
+
136
+ ---
137
+
138
+ #### `notion profile list`
139
+
140
+ Lists all saved auth profiles with the active profile marked.
141
+
142
+ ```bash
143
+ notion profile list
144
+ ```
145
+
146
+ ```bash
147
+ notion profile list --json
148
+ # [{"name":"default","workspace":"My Workspace","active":true}, ...]
149
+ ```
150
+
151
+ ---
152
+
153
+ #### `notion profile use <name>`
154
+
155
+ Switches the active profile.
156
+
157
+ ```bash
158
+ notion profile use work
159
+ ```
160
+
161
+ ---
162
+
163
+ #### `notion profile remove <name>`
164
+
165
+ Removes a saved profile. If the removed profile was active, no profile is set as active.
166
+
167
+ ```bash
168
+ notion profile remove old-profile
169
+ ```
170
+
171
+ ---
172
+
173
+ ### Search & Discovery
174
+
175
+ #### `notion search <query>`
176
+
177
+ Searches workspace titles (not full-text content). Returns pages and databases accessible to your integration.
178
+
179
+ ```bash
180
+ notion search "Meeting Notes"
181
+ notion search "project docs" --type page
182
+ notion search "tracker" --type database
183
+ ```
184
+
185
+ **Flags:**
186
+
187
+ | Flag | Description |
188
+ |-------------------|------------------------------------------|
189
+ | `--type page` | Return only pages |
190
+ | `--type database` | Return only databases |
191
+ | `--json` | Force JSON output |
192
+
193
+ **Agent usage:**
194
+
195
+ ```bash
196
+ notion search "Weekly Review" --type page | jq '.[0].id'
197
+ notion search "Tasks" --type database --json | jq '.[0].id'
198
+ ```
199
+
200
+ **JSON output shape:**
201
+
202
+ ```json
203
+ [
204
+ {
205
+ "id": "abc123def456789012345678901234ab",
206
+ "title": "Weekly Review",
207
+ "type": "page",
208
+ "url": "https://www.notion.so/myworkspace/Weekly-Review-abc123"
209
+ }
210
+ ]
211
+ ```
212
+
213
+ ---
214
+
215
+ #### `notion ls`
216
+
217
+ Lists all top-level pages and databases shared with your integration.
218
+
219
+ ```bash
220
+ notion ls
221
+ notion ls --json
222
+ ```
223
+
224
+ **Agent usage:**
225
+
226
+ ```bash
227
+ notion ls | jq '.[] | select(.type == "database") | {id, title}'
228
+ ```
229
+
230
+ ---
231
+
232
+ #### `notion open <id/url>`
233
+
234
+ Opens a Notion page or database in the default browser. Prints the URL to stdout for scriptable use.
235
+
236
+ ```bash
237
+ notion open abc123def456789012345678901234ab
238
+ notion open "https://www.notion.so/myworkspace/My-Page-abc123"
239
+ ```
240
+
241
+ ---
242
+
243
+ #### `notion users`
244
+
245
+ Lists all members of the workspace.
246
+
247
+ ```bash
248
+ notion users
249
+ notion users --json
250
+ ```
251
+
252
+ **JSON output shape:**
253
+
254
+ ```json
255
+ [
256
+ {
257
+ "id": "user-uuid",
258
+ "name": "Alice Smith",
259
+ "email": "alice@example.com",
260
+ "type": "person"
261
+ }
262
+ ]
263
+ ```
264
+
265
+ ---
266
+
267
+ #### `notion comments <id/url>`
268
+
269
+ Lists all comments on a page.
270
+
271
+ ```bash
272
+ notion comments abc123def456789012345678901234ab
273
+ notion comments "https://www.notion.so/myworkspace/My-Page-abc123" --json
274
+ ```
275
+
276
+ **JSON output shape:**
277
+
278
+ ```json
279
+ [
280
+ {
281
+ "id": "comment-uuid",
282
+ "author": "Alice Smith",
283
+ "text": "This looks good!",
284
+ "created": "2026-01-15T10:00:00Z"
285
+ }
286
+ ]
287
+ ```
288
+
289
+ ---
290
+
291
+ ### Page Reading
292
+
293
+ #### `notion read <id/url>`
294
+
295
+ Fetches a Notion page and outputs its content as markdown. This is the primary command for reading page content.
296
+
297
+ ```bash
298
+ notion read abc123def456789012345678901234ab
299
+ notion read "https://www.notion.so/myworkspace/My-Page-abc123def456"
300
+ notion read abc123def456789012345678901234ab --json # raw JSON block tree
301
+ ```
302
+
303
+ **Flags:**
304
+
305
+ | Flag | Description |
306
+ |----------|----------------------------------|
307
+ | `--json` | Output raw Notion JSON block tree |
308
+
309
+ **Notes:**
310
+ - Default output is always markdown (even when piped).
311
+ - Accepts 32-char hex IDs, UUID format, or full Notion URLs.
312
+ - The page must be shared with your integration.
313
+
314
+ **Agent usage:**
315
+
316
+ ```bash
317
+ # Read and search for a section
318
+ notion read "$PAGE_ID" | grep -A 10 "## Action Items"
319
+
320
+ # Extract all headings
321
+ notion read "$PAGE_ID" | grep "^#"
322
+
323
+ # Pass to LLM for summarization
324
+ notion read "$PAGE_ID" | your-summarize-command
325
+ ```
326
+
327
+ ---
328
+
329
+ ### Database Operations
330
+
331
+ #### `notion db schema <id/url>`
332
+
333
+ Retrieves the schema (property names and types) of a Notion database. **Always run this before building filters** to see available properties and valid select/status values.
334
+
335
+ ```bash
336
+ notion db schema abc123def456789012345678901234ab
337
+ notion db schema "$DB_ID" --json
338
+ ```
339
+
340
+ **JSON output shape:**
341
+
342
+ ```json
343
+ {
344
+ "id": "abc123def456789012345678901234ab",
345
+ "title": "Project Tracker",
346
+ "properties": {
347
+ "Name": { "type": "title" },
348
+ "Status": {
349
+ "type": "select",
350
+ "options": ["Not started", "In Progress", "Done"]
351
+ },
352
+ "Assignee": { "type": "people" },
353
+ "Due Date": { "type": "date" }
354
+ }
355
+ }
356
+ ```
357
+
358
+ ---
359
+
360
+ #### `notion db query <id/url>`
361
+
362
+ Queries a Notion database with optional filters, sorting, and column selection.
363
+
364
+ ```bash
365
+ notion db query abc123def456789012345678901234ab
366
+ notion db query "$DB_ID" --filter "Status=Done"
367
+ notion db query "$DB_ID" --filter "Priority=High" --filter "Status=In Progress"
368
+ notion db query "$DB_ID" --sort "Name:asc"
369
+ notion db query "$DB_ID" --sort "Created:desc"
370
+ notion db query "$DB_ID" --columns "Title,Status,Assignee"
371
+ notion db query "$DB_ID" --json
372
+ ```
373
+
374
+ **Flags:**
375
+
376
+ | Flag | Description |
377
+ |------------------------|----------------------------------------------------------------|
378
+ | `--filter "Prop=Val"` | Filter rows where property equals value. Repeatable. |
379
+ | `--sort "Prop:dir"` | Sort by property. Direction: `asc` or `desc`. Repeatable. |
380
+ | `--columns "A,B,C"` | Limit output to specific columns (comma-separated). |
381
+ | `--json` | Force JSON output. |
382
+
383
+ **Agent usage:**
384
+
385
+ ```bash
386
+ # Get all done items as JSON
387
+ notion db query "$DB_ID" --filter "Status=Done" --json | jq '.[] | .properties'
388
+
389
+ # Extract title and status for each row
390
+ notion db query "$DB_ID" --json | jq '.[] | {id, title: .properties.Name, status: .properties.Status}'
391
+
392
+ # Get most recently modified items
393
+ notion db query "$DB_ID" --sort "Last edited:desc" --columns "Title,Status" | head -20
394
+ ```
395
+
396
+ **JSON output shape:**
397
+
398
+ ```json
399
+ [
400
+ {
401
+ "id": "row-uuid",
402
+ "properties": {
403
+ "Name": "Project Alpha",
404
+ "Status": "In Progress",
405
+ "Assignee": "Alice Smith",
406
+ "Due Date": "2026-03-01"
407
+ }
408
+ }
409
+ ]
410
+ ```
411
+
412
+ ---
413
+
414
+ ## Common Agent Patterns
415
+
416
+ ```bash
417
+ # Pattern 1: Find a page by title, then read it
418
+ PAGE_ID=$(notion search "Meeting Notes" --type page | jq -r '.[0].id')
419
+ notion read "$PAGE_ID"
420
+
421
+ # Pattern 2: Get all items with a specific status from a database
422
+ DB_ID=$(notion search "Project Tracker" --type database | jq -r '.[0].id')
423
+ notion db query "$DB_ID" --filter "Status=Done" | jq '.[] | .properties'
424
+
425
+ # Pattern 3: List recent entries sorted by date
426
+ notion db query "$DB_ID" --sort "Last edited:desc" --columns "Title,Status" | head -20
427
+
428
+ # Pattern 4: Read a page and extract specific content
429
+ notion read "$PAGE_ID" | grep -A 5 "## Action Items"
430
+
431
+ # Pattern 5: Check database schema before building a filter
432
+ notion db schema "$DB_ID" # see what properties exist and their valid values
433
+ notion db query "$DB_ID" --filter "Status=In Progress"
434
+
435
+ # Pattern 6: Using URLs instead of IDs
436
+ notion read "https://www.notion.so/myworkspace/My-Page-abc123def456"
437
+ notion db query "https://www.notion.so/myworkspace/My-DB-abc123def456"
438
+
439
+ # Pattern 7: Combine search + query in one pipeline
440
+ notion search "Tasks" --type database | jq -r '.[0].id' | xargs -I{} notion db query {} --filter "Assignee=Alice" --json
441
+ ```
442
+
443
+ ---
444
+
445
+ ## ID and URL Formats
446
+
447
+ The CLI accepts any of these formats for the `<id>` argument in all commands:
448
+
449
+ | Format | Example |
450
+ |--------------|------------------------------------------------------|
451
+ | 32-char hex | `abc123def456789012345678901234ab` |
452
+ | UUID | `abc123de-f456-7890-1234-5678901234ab` |
453
+ | Full URL | `https://www.notion.so/workspace/Page-Title-abc123` |
454
+
455
+ All commands (`read`, `db query`, `db schema`, `open`, `comments`) accept any of these formats.
456
+
457
+ ---
458
+
459
+ ## Troubleshooting
460
+
461
+ **Page not found (404):** The page must be shared with your integration.
462
+ In Notion: open the page → `⋯` menu → **Add connections** → select your integration.
463
+
464
+ **Unauthorized (401):** Your token is invalid or expired.
465
+ Run `notion init` to reconfigure, or set a new `NOTION_API_TOKEN`.
466
+ Get a new token at: https://www.notion.so/profile/integrations/internal
467
+
468
+ **Search returns no results:** Search is title-only (not full-text content search).
469
+ The page or database must also be explicitly shared with your integration.
470
+
471
+ **Empty database query:** No entries match your filters, or the database has no entries.
472
+ Run `notion db schema <id>` first to see available properties and their valid values.
473
+
474
+ **`notion init` fails in agent/CI environment:** `notion init` requires an interactive terminal (TTY).
475
+ Use the `NOTION_API_TOKEN` environment variable instead.
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@andrzejchm/notion-cli",
3
+ "version": "0.1.0",
4
+ "description": "Read Notion pages and databases from the terminal. Built for AI agents and developers.",
5
+ "keywords": ["notion", "cli", "notion-api", "ai-agent", "markdown", "database"],
6
+ "author": "Andrzej Chm",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/andrzejchm/notion-cli#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/andrzejchm/notion-cli.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/andrzejchm/notion-cli/issues"
15
+ },
16
+ "engines": {
17
+ "node": ">=22.0.0"
18
+ },
19
+ "files": [
20
+ "dist/",
21
+ "docs/agent-skill.md",
22
+ "README.md"
23
+ ],
24
+ "type": "module",
25
+ "bin": {
26
+ "notion": "./dist/cli.js"
27
+ },
28
+ "scripts": {
29
+ "build": "tsup",
30
+ "dev": "tsup --watch",
31
+ "test": "vitest run",
32
+ "test:watch": "vitest"
33
+ },
34
+ "dependencies": {
35
+ "@inquirer/prompts": "^8.3.0",
36
+ "@notionhq/client": "^5.10.0",
37
+ "chalk": "^5.6.0",
38
+ "commander": "^14.0.0",
39
+ "yaml": "^2.8.0"
40
+ },
41
+ "devDependencies": {
42
+ "@commander-js/extra-typings": "^14.0.0",
43
+ "@types/node": "^22",
44
+ "tsup": "^8.5.0",
45
+ "typescript": "~5.9.0",
46
+ "vitest": "^4.0.0"
47
+ }
48
+ }