MCP / Skill
MCP server setup, the TrayPage agent skill, authentication (OAuth / API tokens), and the tool reference.
Page creation, publishing, and fetching from TrayPage can happen via MCP (Model Context Protocol). Connect the MCP server first; then add the TrayPage agent skill when you want AI agents to run the create, review, comment, and revision loop consistently. If MCP is unavailable or you need scriptable local commands, use the CLI.
MCP server
TrayPage MCP is exposed as a Streamable HTTP endpoint. Register this URL in supported clients:
https://tray.page/api/mcpClaude Code
claude mcp add --transport http --scope user traypage https://tray.page/api/mcpAfter adding, run /mcp inside Claude Code and select traypage to authenticate. A browser opens for sign-in and consent (choose the organization, the projects this client may access, and the default project).
This user-level setup is recommended for day-to-day use. If each repository should use a different TrayPage organization / project, or if you intentionally want the configuration to stay inside one repository, use --scope project instead.
claude mcp add --transport http --scope project traypage https://tray.page/api/mcpCodex
codex mcp add traypage --url https://tray.page/api/mcp
codex mcp login traypageComplete browser authentication with codex mcp login traypage. The CLI and IDE extension share ~/.codex/config.toml, so one setup works in both clients. If each repository should use a different TrayPage organization / project, or you want project-scoped setup, put the same configuration in .codex/config.toml inside the repository.
To edit the configuration directly:
[mcp_servers.traypage]
url = "https://tray.page/api/mcp"Cursor
Add the server from Cursor Settings → MCP, or add this to ~/.cursor/mcp.json (all workspaces) or .cursor/mcp.json (current project):
{
"mcpServers": {
"traypage": {
"url": "https://tray.page/api/mcp"
}
}
}Save, reload Cursor, and complete the OAuth flow the first time the server is used.
VS Code (GitHub Copilot Agent mode)
Run MCP: Add Server from the Command Palette and add TrayPage as an HTTP server, or add this to .vscode/mcp.json:
{
"servers": {
"traypage": {
"type": "http",
"url": "https://tray.page/api/mcp"
}
}
}For user-level setup instead of workspace setup, run MCP: Open User Configuration from the Command Palette and add the same server configuration there.
claude.ai / Claude Desktop
Go to Settings → Connectors → Add custom connector and enter https://tray.page/api/mcp as the URL. The same authorization flow runs in the browser when connecting.
ChatGPT
Open Settings → Connectors, add a custom connector, and use https://tray.page/api/mcp as the MCP server URL. Availability, workspace publication, and admin approval requirements can vary by plan and organization settings.
Windsurf / Antigravity
Clients such as Windsurf and Antigravity often use serverUrl in mcp_config.json:
{
"mcpServers": {
"traypage": {
"serverUrl": "https://tray.page/api/mcp"
}
}
}Save the file, refresh the MCP settings, and run authenticate to complete browser sign-in.
Other MCP clients
Any client that supports Streamable HTTP and OAuth 2.1 can connect by registering the URL https://tray.page/api/mcp. For clients without OAuth support, or for automation, pass an API token as a header instead:
claude mcp add --transport http --scope user traypage https://tray.page/api/mcp \
--header "Authorization: Bearer tp_xxx"Agent skill
The TrayPage MCP server is enough to create and publish pages, but the public skill helps AI coding agents run the full create, review, publish, comment, and revision loop consistently. The public repository is 8d-inc/traypage-skills.
npx skills add 8d-inc/traypage-skills -gThe -g flag installs the skill at user/global scope. Use this for normal day-to-day work across Claude Code, Codex, Cursor, and other repositories. If you only want the skill in one repository, omit -g and choose project scope in the interactive prompt.
The skill is not an MCP setup guide. It tells the agent how to use create_page, create_page_version, publish_version, get_page_comments, reply_page_comment, resolve_page_comment, and get_page_revision_prompt for real TrayPage work. It also tells the agent to prefer MCP tools, return review_url and share_url instead of /viewer URLs, keep draft creation separate from publishing, start a review session after publishing when the CLI is available, explain the CLI and review-session benefits when the CLI is missing, and create a revised version after receiving review feedback.
When using a review session, have the user open the URL printed when that session starts. If a normal review page is already open and the CLI review session starts later, that existing tab does not automatically connect to the session.
Authentication
| Method | Best for | Steps |
|---|---|---|
| OAuth 2.1 (recommended) | Day-to-day AI tools | Authorize in the browser when connecting. No token management |
API token (tp_ prefix) | CI, scripts, clients without OAuth | Create on the project page, pass as Authorization: Bearer tp_xxx |
During OAuth authorization, a consent screen shows the organization, the project access mode (selected projects or all projects in the organization), and the default project you are granting. API tokens are issued per project and only work within that project. Calling create_page without a project creates the page in the token's project (or the OAuth default project).
The scopes are listed below. When OAuth scopes are omitted, TrayPage grants the default scopes needed for normal page creation, publishing, and reading. Project and organization management operations require the matching write scope explicitly.
| Scope | Allowed operations |
|---|---|
page:read | Fetch pages and versions |
page:write | Create draft pages, add new versions, publish versions, archive / restore pages, change visibility, reply to comments, and resolve comments |
comment:read | Fetch review comments |
revision_prompt:read | Fetch revision prompts |
project:read | List projects |
project:write | Manage project settings, project members, and API tokens |
organization:read | View organization settings, organization members, and audit logs |
organization:write | Manage organization settings, organization members, and allowed domains |
folder:read | List folders |
Regardless of method and scopes, final authorization is decided per page by the permission model (How it works § Permissions).
Tool reference
This section intentionally shows the exact tool names, argument names, and literal values that AI agents and MCP clients must send. The surrounding text explains the product meaning in user-facing terms.
create_page
Creates a new page from HTML or Markdown. The first version starts as a draft, and the tool returns a review URL and a share URL. To show the page body from the share URL, review the draft and call publish_version.
| Argument | Required | Description |
|---|---|---|
organization_id | ID of the target organization (defaults to the token's organization) | |
project_id | ID of the target project (defaults to the token's / OAuth default project) | |
page_title | ✓ | Page title |
content | ✓ | Full HTML or Markdown |
content_type | text/html (default) or text/markdown | |
folder_path | Folder path within the project | |
changelog | What changed in this version |
When you create a page or version from Markdown, TrayPage converts it to styled HTML at view time. The conversion uses marked and supports GitHub Flavored Markdown (GFM) — tables, strikethrough, task lists, code blocks, and so on.
create_page_version
Adds a new draft version to an existing page. The share URL keeps showing the current live version until you call publish_version.
| Argument | Required | Description |
|---|---|---|
page_id | ✓ | Target page ID |
content | ✓ | Full HTML or Markdown |
content_type | text/html (default) or text/markdown | |
changelog | What changed in this version |
publish_version
Makes a specific version live on the stable share URL. Requires page.publish on the target page. Only one version can be live at a time; publishing a new version returns the previous live version to draft. This does not change visibility.
| Argument | Required | Description |
|---|---|---|
page_id | ✓ | Target page ID |
version_number | ✓ | Version number to make live |
list_pages
Lists pages in a project.
| Argument | Required | Description |
|---|---|---|
organization_id | Organization ID (defaults to the token's organization) | |
project_id | Project ID (defaults to the token's / OAuth default project) | |
folder_path | Filter by folder | |
archived | When true, list archived pages. Omitted means list only normal active pages |
archive_page
Archives a page. Archived pages are hidden from normal lists and free an active page slot. Page content and versions are not deleted. Requires page.manage_access on the target page.
| Argument | Required | Description |
|---|---|---|
page_id | ✓ | Target page ID |
unarchive_page
Restores an archived page. Restoring consumes an active page slot, so it can fail when the organization is already at its plan limit. Requires page.manage_access on the target page.
| Argument | Required | Description |
|---|---|---|
page_id | ✓ | Target page ID |
set_page_visibility
Changes a page's visibility. Requires page.manage_access on the target page. Visibility controls who can open the share URL; publish_version controls which version appears from that URL.
| Argument | Required | Description |
|---|---|---|
page_id | ✓ | Target page ID |
visibility | ✓ | private (Private) / project_members (Project Members) / organization_domain_users (Company Domain Users) / public_link (Anyone with the link) |
share_expires_at | Optional link expiration for public/domain sharing. Use an ISO 8601 string, null, or omit it. Omitted means keep the existing setting; normal links do not expire by default |
get_page_comments
Fetches review comments for a page.
| Argument | Required | Description |
|---|---|---|
page_id | ✓ | Target page ID |
version_number | Filter to a specific version | |
status | open (default) or resolved |
reply_page_comment
Replies to a review comment thread. Use this after applying a requested change, or when the right response is an answer instead of a page change. Requires comment.write on the target page.
| Argument | Required | Description |
|---|---|---|
thread_id | ✓ | Comment thread ID from get_page_comments |
body | ✓ | Reply body |
resolve_page_comment
Marks a review comment thread as resolved. Resolve only after the requested change is complete or the question has been answered. Requires comment.resolve on the target page.
| Argument | Required | Description |
|---|---|---|
thread_id | ✓ | Comment thread ID from get_page_comments |
get_page_revision_prompt
Builds revision instructions from open comments, ready to hand to an AI.
| Argument | Required | Description |
|---|---|---|
page_id | ✓ | Target page ID |
version_number | Base the prompt on a specific version | |
language | ja or en. Omitted means use the caller's language setting |
Revision prompts do not treat every comment as a mechanical change request. If a comment is a question or clarification and the right response is an answer rather than a file change, the prompt tells the AI to answer it without changing the page for that item.
Troubleshooting
- The auth screen doesn't open / persistent 401 — Re-authenticate via
/mcpin Claude Code. If that doesn't fix it, runclaude mcp remove traypageand add it again. Organization not found— Check the organization ID, and confirm you granted access to that organization during OAuth consent. You can find the ID in the app URL (/app/organizations/{organization-id}).Project not found/project_restricted— Tokens are scoped to the project they were issued for. To create pages in a different project, issue a token for that project or grant access to it during OAuth consent.- Page creation or publishing works but reading comments fails — Check that your API token's scopes include
comment:read. - Comment replies or resolve fail — Check that your API token's scopes include
page:writeand that your page role allows commenting or resolving threads.