Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@
"displayName": "Paper"
},
"plugins": [
{
"name": "paper",
"source": {
"source": "local",
"path": "./plugins/paper"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Design"
},
{
"name": "paper-desktop",
"source": {
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ jobs:
- run: bun run build

- run: bun ./scripts/validate-mcpb-artifact.mjs

# The ZIP uploaded to the OpenAI plugin submission portal
- uses: actions/upload-artifact@v4
with:
name: paper-chatgpt-plugin
path: dist/paper-chatgpt-plugin.zip
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
Use Paper with your favorite agent harness.
Are we missing one, you have feedback for us, or just want to chat? Join us on our [Discord](https://discord.gg/xqBrwhuh2J) or [Slack](https://paper-community.slack.com/join/shared_invite/zt-430qekrpz-EzbDXbpIHulMPVBB02CwVA) communities.

## ChatGPT and Codex

The `paper` plugin connects to Paper's hosted MCP server (`https://mcp.paper.design`), so no desktop install is needed.

- Search for "Paper" in ChatGPT Plugins once it is listed in the directory.
- Before then, add it as a custom MCP server: Plugins > plus button > Add custom MCP server, URL `https://mcp.paper.design`, OAuth authentication.
- Maintainers: `bun run pack:chatgpt` writes `dist/paper-chatgpt-plugin.zip` for the OpenAI plugin submission portal.

## Cursor

```sh
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
"type": "module",
"private": true,
"scripts": {
"build": "bun ./scripts/validate-cursor-schema.mjs && bun ./scripts/validate-cursor-structure.mjs && bun ./scripts/validate-codex.mjs && bun ./scripts/validate-mcpb.mjs && bun run pack:mcpb",
"build": "bun ./scripts/validate-cursor-schema.mjs && bun ./scripts/validate-cursor-structure.mjs && bun ./scripts/validate-codex.mjs && bun ./scripts/validate-agent-plugins.mjs && bun ./scripts/validate-mcpb.mjs && bun run pack:mcpb && bun run pack:chatgpt",
"pack:mcpb": "bun ./claude-extensions/paper-desktop/scripts/pack.ts",
"pack:chatgpt": "bun ./scripts/pack-chatgpt.ts",
"test": "bun run build"
},
"devDependencies": {
Expand Down
27 changes: 27 additions & 0 deletions plugins/paper/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Paper for ChatGPT and Codex

Paper connects your designs, agents, code, and data on a single canvas built on web standards. This plugin connects ChatGPT (and Codex) to Paper's hosted MCP server at `https://mcp.paper.design`, so your agent can read and write your design files after you sign in with your Paper account.

No desktop install is required: everything runs through the remote server.

**Features**

- **Read designs**: Inspect artboard structure, screenshots, computed styles, JSX output, and text content.
- **Write to the canvas**: Create artboards, add or replace HTML nodes, update styles, set text, and duplicate elements from a prompt.
- **Export**: Export artboards as images or PDFs.
- **Design systems**: Read and write design tokens.

**Install**

- From the Plugin Directory: search for "Paper" in ChatGPT Plugins and install it, then sign in with your Paper account when prompted.
- Manually, before it is listed: in ChatGPT go to Plugins, select the plus button, then Add custom MCP server. Use `https://mcp.paper.design` as the server URL with OAuth authentication.

**Package layout**

This folder is a portable [Agent Plugins](https://agent-plugins.org) package:

- `plugin.json`: identity and listing metadata (OpenAI-specific fields under `extensions.com.openai`).
- `mcp.json`: the remote MCP server, strictly per the Agent Plugins schema. OAuth is not declared here: Codex's parser rejects servers with extra keys, and clients discover the authorization server from the MCP endpoint itself (401 + `resource_metadata`). Pick OAuth in the portal's Connect panel when submitting.
- `assets/`: listing icon.

Run `bun run pack:chatgpt` from the repository root to produce the ZIP uploaded to the OpenAI plugin submission portal. The ZIP contains only `plugin.json`, `mcp.json`, and the referenced icons; this README is for the repo, not the listing.
Binary file added plugins/paper/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions plugins/paper/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"paper": {
"type": "streamable-http",
"url": "https://mcp.paper.design"
}
}
}
107 changes: 107 additions & 0 deletions plugins/paper/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "paper",
"version": "1.0.0",
"description": "Design on a canvas that ChatGPT can read and write to — built on web standards.",
"author": {
"name": "Paper",
"email": "team@paper.design",
"url": "https://paper.design"
},
"homepage": "https://paper.design",
"repository": "https://github.com/paper-design/agent-plugins",
"license": "MIT",
"keywords": [
"paper",
"design",
"ui",
"canvas",
"html",
"css",
"design-to-code",
"code-to-design",
"prototyping",
"mcp",
"design-system"
],
"extensions": {
"com.openai": {
"interface": {
"displayName": "Paper",
"shortDescription": "Design UI on a live canvas",
"longDescription": "Paper is a professional design tool built on HTML and CSS. With this plugin, ChatGPT can read your Paper files — structure, styles, screenshots, and text — and write back to the canvas in real time. Use it to sketch new screens from a prompt, iterate on existing designs, generate UI from a brief or design system, export artboards, and keep design work moving without leaving the conversation.\n\nSign in with your Paper account to connect. ChatGPT can only access files that your account can access.",
"developerName": "Paper",
"category": "Design",
"capabilities": ["Read", "Write"],
"websiteURL": "https://paper.design",
"supportURL": "https://paper.design/support",
"privacyPolicyURL": "https://paper.design/legal/privacy",
"termsOfServiceURL": "https://paper.design/legal/tos",
"defaultPrompt": [
"Design a settings page for a mobile app in Paper",
"Take a screenshot of my selected artboard in Paper and suggest layout improvements",
"Create a design system sticker sheet in Paper with my brand colors and type scale"
],
"brandColor": "#81ADEC",
"composerIcon": "./assets/logo.png",
"logo": "./assets/logo.png"
},
"review": {
"test_cases": {
"positive": [
{
"description": "Read the structure of a Paper file from its URL",
"prompt": "Open this Paper file and tell me what artboards it has: https://app.paper.design/file/<test-file-id>",
"tools_triggered": "open_file, get_basic_info",
"expected_behavior": "Opens the file and lists its pages and artboards with their names and dimensions."
},
{
"description": "Screenshot an artboard for review",
"prompt": "Take a screenshot of the first artboard in my Paper file and describe what you see.",
"tools_triggered": "get_basic_info, get_screenshot",
"expected_behavior": "Returns a rendered screenshot of the artboard and describes its content."
},
{
"description": "Create a new design on the canvas",
"prompt": "In my Paper file, create a new 390 by 844 artboard with a simple login screen: logo, email and password fields, and a primary button.",
"tools_triggered": "get_font_family_info, create_artboard, write_html, get_screenshot, finish_working_on_nodes",
"expected_behavior": "A new artboard appears in the file containing the described login screen, and ChatGPT confirms with a screenshot."
},
{
"description": "Edit text in an existing design",
"prompt": "Change the heading on the login screen in my Paper file to say 'Welcome back'.",
"tools_triggered": "find_nodes, set_text_content, finish_working_on_nodes",
"expected_behavior": "The heading text node is updated to 'Welcome back' and no other content changes."
},
{
"description": "Inspect styles for handoff",
"prompt": "What are the exact colors, font sizes, and spacing used by the primary button on the login screen in my Paper file?",
"tools_triggered": "find_nodes, get_computed_styles",
"expected_behavior": "Reports the button's computed values (colors, font size, padding, radius) read from the design rather than guessed from a screenshot."
}
],
"negative": [
{
"description": "Access to a file the account cannot see",
"prompt": "Open the Paper file at https://app.paper.design/file/<file-from-another-team> and list its artboards."
},
{
"description": "Unsupported payment or plan change",
"prompt": "Use Paper to upgrade my team to a paid plan and charge my card."
},
{
"description": "Request unrelated to design",
"prompt": "Use Paper to book me a flight to Lisbon next Tuesday."
}
]
},
"demo_recording_url": "https://paper.design/TODO-demo-recording",
"commerce": false,
"commerce_description": "This plugin does not sell products or process payments."
},
"publication": {
"release_notes": "Initial release: read and write Paper files from ChatGPT through Paper's remote MCP server."
}
}
}
}
120 changes: 120 additions & 0 deletions schemas/agent-plugins/mcp.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"title": "Agent Plugins MCP Configuration",
"description": "Machine-readable schema for mcp.json in Agent Plugins 1.0.0. The Agent Plugins specification defines additional semantic and operational requirements.",
"type": "object",
"properties": {
"$schema": {
"const": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"description": "Canonical identifier of the MCP configuration schema for the Agent Plugins version targeted by this document."
},
"mcpServers": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/server"
}
}
},
"required": ["$schema", "mcpServers"],
"additionalProperties": false,
"$defs": {
"server": {
"title": "MCP server",
"oneOf": [
{
"$ref": "#/$defs/stdioServer"
},
{
"$ref": "#/$defs/streamableHttpServer"
},
{
"$ref": "#/$defs/sseServer"
}
]
},
"stdioServer": {
"title": "stdio MCP server",
"type": "object",
"properties": {
"type": {
"const": "stdio"
},
"command": {
"type": "string",
"minLength": 1,
"description": "Executable token. Resolution rules are defined by the Agent Plugins specification."
},
"args": {
"type": "array",
"items": {
"type": "string"
}
},
"env": {
"type": "object",
"propertyNames": {
"not": {
"enum": ["PLUGIN_ROOT", "PLUGIN_DATA"]
}
},
"additionalProperties": {
"type": "string"
}
},
"cwd": {
"type": "string",
"pattern": "^(?:\\./|\\$\\{PLUGIN_ROOT\\}(?:/|$)|\\$\\{PLUGIN_DATA\\}(?:/|$))",
"description": "Plugin-relative, PLUGIN_ROOT-rooted, or PLUGIN_DATA-rooted working directory. Filesystem containment is validated separately."
}
},
"required": ["type", "command"],
"additionalProperties": false
},
"streamableHttpServer": {
"title": "Streamable HTTP MCP server",
"type": "object",
"properties": {
"type": {
"const": "streamable-http"
},
"url": {
"type": "string",
"minLength": 1,
"description": "MCP endpoint URL. URL semantics are defined by the Agent Plugins specification."
},
"headers": {
"$ref": "#/$defs/headers"
}
},
"required": ["type", "url"],
"additionalProperties": false
},
"sseServer": {
"title": "Legacy HTTP+SSE MCP server",
"type": "object",
"properties": {
"type": {
"const": "sse"
},
"url": {
"type": "string",
"minLength": 1,
"description": "MCP endpoint URL. URL semantics are defined by the Agent Plugins specification."
},
"headers": {
"$ref": "#/$defs/headers"
}
},
"required": ["type", "url"],
"additionalProperties": false
},
"headers": {
"title": "HTTP headers",
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
}
65 changes: 65 additions & 0 deletions schemas/agent-plugins/plugin.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"title": "Agent Plugins Manifest",
"description": "Machine-readable schema for plugin.json in Agent Plugins 1.0.0. The Agent Plugins specification defines additional semantic and operational requirements.",
"type": "object",
"properties": {
"$schema": {
"const": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"description": "Canonical identifier of the plugin manifest schema for the Agent Plugins version targeted by this document."
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"pattern": "^(?!.*(?:--|\\.\\.))[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$",
"description": "Human-readable plugin name."
},
"version": {
"type": "string"
},
"description": {
"type": "string"
},
"author": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"url": {
"type": "string"
}
},
"additionalProperties": false
},
"homepage": {
"type": "string"
},
"repository": {
"type": "string"
},
"license": {
"type": "string"
},
"keywords": {
"type": "array",
"items": {
"type": "string"
}
},
"extensions": {
"type": "object",
"description": "Client-specific manifest data keyed by reverse-domain extension namespace. Agent Plugins assigns no semantics to namespace object contents.",
"additionalProperties": {
"type": "object"
}
}
},
"required": ["$schema", "name"],
"additionalProperties": false
}
Loading
Loading