Skip to content

feat: page move/duplicate, user commands, and page create --json fix - #39

Open
mariotsi wants to merge 1 commit into
lox:mainfrom
mariotsi:feat/page-move-duplicate-user-commands
Open

mariotsi wants to merge 1 commit into
lox:mainfrom
mariotsi:feat/page-move-duplicate-user-commands

Conversation

@mariotsi

Copy link
Copy Markdown

Why

The MCP layer already reaches notion-move-pages, notion-duplicate-page, and
notion-get-users, but none of them have a CLI surface.

Separately, page create --json returns an empty id and url: it reads a
flat object, but the server wraps the created page in a {"pages":[...]}
envelope and returns an app.notion.com URL that the extractor, which only
matches www.notion.so, misses. A script cannot pick up the new page.

What

New commands:

Command Tool
page move <page> --parent <page> / --parent-db <db> notion-move-pages
page duplicate <page> [--json] notion-duplicate-page
user list [--query] [--limit] [--json] notion-get-users
user me [--json] notion-get-users with user_id=self

Client.MovePage, Client.DuplicatePage, and Client.ListUsers land in
internal/mcp/pages.go, with argument building and response parsing as pure
functions under unit test. Commands resolve pages and databases by URL, name, or
ID like the rest of the CLI. user list follows the server cursor to the end so
large workspaces return every member instead of only the first page; --query
pushes the filter server-side and --limit bounds the result. page duplicate --json reads page_id / page_url from the response and recovers the id from
the URL when the server replies in prose.

page create --json now reads the pages envelope and accepts a page URL on
either www.notion.so or app.notion.com, so id and url are populated.

README.md and skills/notion/SKILL.md document the new commands. SKILL.md
also notes that page edit -P key=value already handles property edits, and
that the official API fallback needs an internal integration secret from
notion.so/profile/integrations/internal (the MCP OAuth token is rejected by
api.notion.com with 401), reaching only pages explicitly connected to it.

Testing

go build ./..., go vet ./..., and go test ./... pass. New unit tests cover
move-argument building, create/duplicate response parsing, the multi-host URL
match, and user-list cursor handling.

New CLI surfaces for MCP tools that had none:

  page move <page> --parent <page> | --parent-db <db>   notion-move-pages
  page duplicate <page> [--json]                        notion-duplicate-page
  user list [--query] [--limit] [--json]                notion-get-users
  user me [--json]                                      notion-get-users user_id=self

Client.MovePage, Client.DuplicatePage and Client.ListUsers live in
internal/mcp/pages.go, with the tool-argument building and response parsing
split into pure functions covered by unit tests. Commands resolve pages and
databases by URL, name, or ID like the rest of the CLI. user list follows the
server cursor to the end so large workspaces return every member rather than
only the first page; --query pushes the filter to the server and --limit bounds
the result.

Two response shapes differ from what the client assumed, so --json returned an
empty id and url where a script needs them to chain calls:

  * notion-create-pages answers with a {"pages":[...]} wrapper, not a flat
    object
  * notion-duplicate-page answers with page_id and page_url, not id and url
  * the server returns app.notion.com URLs, while URL extraction matched only
    www.notion.so; it now matches either host
  * when the server answers in prose, the duplicated page id is recovered from
    the URL

README.md and skills/notion/SKILL.md document the new commands. SKILL.md also
records that page edit -P key=value already handles property edits, and that
the official API fallback needs an internal integration secret from
notion.so/profile/integrations/internal (the MCP OAuth token is rejected by
api.notion.com with 401), which only reaches pages explicitly connected to it.
@mariotsi
mariotsi marked this pull request as ready for review September 8, 2026 07:51
@mariotsi

mariotsi commented Oct 2, 2026

Copy link
Copy Markdown
Author

@lox any chance this can be reviewed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant