From 3cef55b3735d78b6237614e48e2ba1df3d64f9e2 Mon Sep 17 00:00:00 2001 From: Adam Ginzberg Date: Mon, 2 Feb 2026 14:25:54 -0800 Subject: [PATCH] MCP docs updates, Claude Code plugin, Skills --- .claude-plugin/marketplace.json | 27 +++ packages/docs/docs.json | 1 + packages/docs/guides/mcp-server.mdx | 11 +- packages/docs/guides/skills.mdx | 43 ++++ packages/docs/installation.mdx | 73 ++++--- packages/docs/learn/admin/auth-tokens.mdx | 4 +- .../subframe/.claude-plugin/plugin.json | 14 ++ plugins/claude/subframe/.mcp.json | 12 ++ .../claude/subframe/skills/design/SKILL.md | 61 ++++++ .../claude/subframe/skills/develop/SKILL.md | 94 +++++++++ plugins/claude/subframe/skills/setup/SKILL.md | 186 ++++++++++++++++++ 11 files changed, 481 insertions(+), 45 deletions(-) create mode 100644 .claude-plugin/marketplace.json create mode 100644 packages/docs/guides/skills.mdx create mode 100644 plugins/claude/subframe/.claude-plugin/plugin.json create mode 100644 plugins/claude/subframe/.mcp.json create mode 100644 plugins/claude/subframe/skills/design/SKILL.md create mode 100644 plugins/claude/subframe/skills/develop/SKILL.md create mode 100644 plugins/claude/subframe/skills/setup/SKILL.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 00000000..450d9708 --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,27 @@ +{ + "name": "subframe", + "owner": { + "name": "Subframe", + "email": "support@subframe.com" + }, + "metadata": { + "description": "Official Subframe marketplace - design and implement UIs with AI directly in Claude Code", + "version": "1.0.0" + }, + "plugins": [ + { + "name": "subframe", + "source": "./plugins/claude/subframe", + "description": "Design and implement UIs with Subframe - an AI design tool that outputs production-ready React code", + "version": "1.0.0", + "author": { + "name": "Subframe" + }, + "homepage": "https://subframe.com", + "repository": "https://github.com/SubframeApp/subframe", + "keywords": ["design", "ui", "react", "tailwind", "components"], + "category": "design", + "tags": ["design", "ui", "react", "frontend", "components"] + } + ] +} diff --git a/packages/docs/docs.json b/packages/docs/docs.json index 847a0b16..80f9f023 100644 --- a/packages/docs/docs.json +++ b/packages/docs/docs.json @@ -47,6 +47,7 @@ "group": "Guides", "pages": [ "guides/mcp-server", + "guides/skills", "guides/dark-mode", "guides/component-docs", "guides/accessibility", diff --git a/packages/docs/guides/mcp-server.mdx b/packages/docs/guides/mcp-server.mdx index 01d4dade..73e479f2 100644 --- a/packages/docs/guides/mcp-server.mdx +++ b/packages/docs/guides/mcp-server.mdx @@ -33,6 +33,7 @@ You can get the MCP link for any design by either: | `get_component_info` | Gets the code and metadata for a component | `id`, `name`, or `url`
`projectId` (optional) | `id`, `name`, `files` | | `get_page_info` | Gets the code for a page | `id`, `name`, or `url`
`projectId` (optional) | `id`, `name`, `files` | | `get_theme` | Generates the Tailwind theme for the project | `projectId` (optional)
`cssType` (optional) | `theme` config | +| `design_page` | Designs multiple page variations using AI | `description`, `variations` (1–4 strings), `flowName`
`projectId` (optional), `codeContext` (optional) | `pageId`, `reviewUrl` | If `projectId` is not specified, the tool will use the first project you have access to. @@ -125,13 +126,11 @@ Get my Subframe theme configuration -Check that: +The MCP server uses OAuth for authentication. If you're seeing authentication errors: -- Your API token is correct and hasn't expired -- You copied the entire token without extra spaces -- The token is in the `Authorization` header as `Bearer YOUR_AUTH_TOKEN` - -Generate a new token at [app.subframe.com/settings/tokens](https://app.subframe.com/settings/tokens). +- Try re-authenticating by reconnecting to the MCP server in your client +- Check that you have the correct permissions for the project you're trying to access +- Make sure your browser session is active when authenticating diff --git a/packages/docs/guides/skills.mdx b/packages/docs/guides/skills.mdx new file mode 100644 index 00000000..a9148d9d --- /dev/null +++ b/packages/docs/guides/skills.mdx @@ -0,0 +1,43 @@ +--- +title: Skills +description: Guided workflows that teach AI assistants how to design and implement UIs with Subframe. +--- + +[Agent Skills](https://agentskills.io) are structured instructions that teach AI assistants how to use tools correctly. The [MCP server](/guides/mcp-server) gives your AI assistant the _ability_ to access Subframe — skills give it the _knowledge_ of how to use Subframe well. + +Skills are an [open standard](https://agentskills.io) adopted by companies like Supabase, Vercel, and Cloudflare. + +## Available skills + +**`/subframe:setup`** — Initializes Subframe in a new or existing project. Detects the framework, runs the CLI, configures Tailwind and fonts, and syncs components. + +**`/subframe:design`** — Designs UI pages. Gathers context from your codebase, calls `design_page` to generate multiple variations, and returns a review URL where you can preview and select a variation. + +**`/subframe:develop`** — Implements designs with business logic. Fetches the design via `get_page_info`, syncs components, places the page in your codebase, and wires up data fetching, forms, event handlers, and loading/error states. + +## Typical workflow + +1. Run `/subframe:setup` to initialize Subframe in your project (one-time) +2. Run `/subframe:design` to create a page design with multiple variations +3. Review and select a variation in Subframe +4. Run `/subframe:develop` to implement the selected design with business logic + +## Installing skills + + + + Skills are bundled with the Subframe plugin and installed automatically. Run the following commands in Claude Code: + + ``` + /plugin marketplace add SubframeApp/subframe + /plugin install subframe@subframe + ``` + + + Install skills with: + + ```bash + npx skills add SubframeApp/subframe + ``` + + diff --git a/packages/docs/installation.mdx b/packages/docs/installation.mdx index 435f6740..639db1d5 100644 --- a/packages/docs/installation.mdx +++ b/packages/docs/installation.mdx @@ -85,11 +85,25 @@ Your Subframe theme may use a Google Font or an [uploaded custom font](/learn/th -## Set up Subframe MCP (recommended) +## Set up Subframe MCP and Skills (recommended) -Subframe's MCP server lets AI tools like Cursor and Claude Code fetch your designs directly. Instead of copying code manually, AI can access your components, pages, and theme automatically. +The MCP server lets AI tools like Cursor and Claude Code fetch your designs directly. Skills teach your AI assistant how to use Subframe well — setting up projects, designing pages, and implementing with business logic. + + The Subframe plugin for Claude Code sets up the MCP server and Skills in one install. + + + + Run the following commands in Claude Code: + + ``` + /plugin marketplace add SubframeApp/subframe + /plugin install subframe@subframe + ``` + + + @@ -99,21 +113,25 @@ Subframe's MCP server lets AI tools like Cursor and Claude Code fetch your desig Go to **Code** \> **Installation** \> **Cursor MCP server** - Click on **Add to Cursor**. Your auth token will be automatically applied. + Click on **Add to Cursor**. You'll be prompted to authenticate via OAuth. + + + Skills are guided workflows that teach Cursor how to best use Subframe. Install them with: + + ```bash + npx skills add SubframeApp/subframe + ``` **Manual installation** - Create a new auth token at [app.subframe.com/settings/tokens](https://app.subframe.com/settings/tokens) and add the following to `~/.cursor/mcp.json`: + Add the following to `~/.cursor/mcp.json`. Cursor will handle OAuth authentication automatically when you first connect. ```json ~/.cursor/mcp.json { "mcpServers": { "subframe": { - "url": "https://mcp.subframe.com/mcp", - "headers": { - "Authorization": "Bearer YOUR_AUTH_TOKEN" - } + "url": "https://mcp.subframe.com/mcp" }, "subframe-docs": { "url": "https://docs.subframe.com/mcp" @@ -122,40 +140,14 @@ Subframe's MCP server lets AI tools like Cursor and Claude Code fetch your desig } ``` - - - - You can create and manage your auth tokens at [app.subframe.com/settings/tokens](https://app.subframe.com/settings/tokens) - - - Run the following command with `YOUR_AUTH_TOKEN` replaced with your auth token: - - ```bash - claude mcp add --transport http subframe https://mcp.subframe.com/mcp \ - --header "Authorization: Bearer YOUR_AUTH_TOKEN" - ``` - - - You can install the Subframe Docs MCP server (recommended) to give AI access to this docs site: - - ```bash - claude mcp add --transport http subframe-docs https://docs.subframe.com/mcp - ``` - - - - - You can create and manage your auth tokens at [app.subframe.com/settings/tokens](https://app.subframe.com/settings/tokens) - Configure your MCP client to connect to the Subframe MCP server: - **URL:** `https://mcp.subframe.com/mcp` - **Transport:** HTTP - - **Authentication:** Bearer token in header - - **Header:** `Authorization: Bearer YOUR_AUTH_TOKEN` + - **Authentication:** OAuth (your client will handle the authentication flow) Optionally add the Subframe Docs MCP server for documentation access: @@ -164,14 +156,21 @@ Subframe's MCP server lets AI tools like Cursor and Claude Code fetch your desig - **Transport:** HTTP - **Authentication:** None required + + If your client supports the [Agent Skills](https://agentskills.io) standard, install the Subframe skills with: + + ```bash + npx skills add SubframeApp/subframe + ``` + - Restart your MCP client, then verify the MCP servers are available in your AI assistant. + Restart your MCP client, then verify the MCP servers and skills are available in your AI assistant. -See our [MCP server guide](/guides/mcp-server) for more information on how to use the MCP server. +See our [MCP server guide](/guides/mcp-server) and [Skills guide](/guides/skills) for more details. ## FAQ diff --git a/packages/docs/learn/admin/auth-tokens.mdx b/packages/docs/learn/admin/auth-tokens.mdx index 07547cc1..f9a82b77 100644 --- a/packages/docs/learn/admin/auth-tokens.mdx +++ b/packages/docs/learn/admin/auth-tokens.mdx @@ -1,9 +1,9 @@ --- title: Auth tokens -description: Create and manage auth tokens for CLI and MCP server. +description: Create and manage auth tokens for the Subframe CLI. --- -Auth tokens let team members authenticate the Subframe CLI and MCP server with their accounts. +Auth tokens let team members authenticate the Subframe CLI with their accounts. ## Create a token diff --git a/plugins/claude/subframe/.claude-plugin/plugin.json b/plugins/claude/subframe/.claude-plugin/plugin.json new file mode 100644 index 00000000..d632d47f --- /dev/null +++ b/plugins/claude/subframe/.claude-plugin/plugin.json @@ -0,0 +1,14 @@ +{ + "name": "subframe", + "description": "Design and implement UIs with Subframe - an AI design tool that outputs production-ready React code", + "version": "1.0.0", + "author": { + "name": "Subframe" + }, + "homepage": "https://subframe.com", + "repository": "https://github.com/SubframeApp/subframe", + "license": "MIT", + "keywords": ["design", "ui", "react", "tailwind", "components"], + "skills": "./skills/", + "mcpServers": "./.mcp.json" +} diff --git a/plugins/claude/subframe/.mcp.json b/plugins/claude/subframe/.mcp.json new file mode 100644 index 00000000..fa5f73a9 --- /dev/null +++ b/plugins/claude/subframe/.mcp.json @@ -0,0 +1,12 @@ +{ + "mcpServers": { + "subframe": { + "type": "http", + "url": "${SUBFRAME_MCP_URL:-https://mcp.subframe.com/mcp}" + }, + "subframe-docs": { + "type": "http", + "url": "https://docs.subframe.com/mcp" + } + } +} diff --git a/plugins/claude/subframe/skills/design/SKILL.md b/plugins/claude/subframe/skills/design/SKILL.md new file mode 100644 index 00000000..5cdb7b70 --- /dev/null +++ b/plugins/claude/subframe/skills/design/SKILL.md @@ -0,0 +1,61 @@ +--- +name: design +description: Design UI pages using Subframe. Use proactively whenever a task involves creating or updating UI - don't write UI code directly. +argument-hint: "[description of what to design]" +--- + +Design pages using the `design_page` MCP tool. + +**Don't write UI code directly.** Subframe generates production-ready React/Tailwind code that matches the design system. Design first, then implement with `/subframe:develop`. + +## Subframe Basics + +- **Components** (buttons, inputs, cards): Synced via CLI. Source of truth in Subframe. Don't modify locally. +- **Pages** (screens): Exported via MCP. Add business logic after export. + +Subframe knows about the design system and theme. Your job is to provide context from the user's codebase. + +## Workflow + +1. **Understand the request** - If vague, ask clarifying questions first. What data? What actions? Who uses it? +2. **Find the projectId** - Check `.subframe/sync.json` +3. **Gather context and decide variations** - Scale to the task (see below) +4. **Call `design_page`** +5. **Share results** - Present the review URL as a clickable link — this is the primary output for the user. Note the pageId for later. + +## Context and Variations + +How much context to gather and how many variations to generate depends on the task: + +| Task | Context | Variations | +| ------------------------------ | ----------------------------------------------------------------- | ------------------------------------ | +| **New page** | Similar pages, data types | 4 — explore the design space | +| **Adding or edit existing UI** | The existing page, relevant data types | 2 — match the pattern, offer options | +| **Redesigning existing UI** | The current page (note what to keep vs change in the description) | 2-4 — depending on how open-ended | + +**Always include when available:** + +- Similar existing pages (the single most valuable context) +- Components or patterns the user explicitly mentions +- Data types/interfaces for what the page will display + +### Variations + +Each variation is a prompt that drives a unique design direction. Make them meaningfully different: + +- "Compact data table with inline actions and bulk operations" +- "Card-based layout with visual hierarchy and quick filters" +- "Minimal single-column design focused on the primary action" + +More variations = more exploration. Fewer = more focused. Don't overthink it. + +## Multi-Page Requests + +When designing multiple related pages (flows, CRUD, etc.): + +1. Design the primary page first with more variations to establish the direction +2. After user approves, design remaining pages using the first as context + +## After Designing + +Always present the `reviewUrl` as a clickable markdown link — it's the most important thing for the user to see. They need it to preview and select a variation in Subframe. Also note the `pageId` — they'll need it for `/subframe:develop` to implement the page with business logic. diff --git a/plugins/claude/subframe/skills/develop/SKILL.md b/plugins/claude/subframe/skills/develop/SKILL.md new file mode 100644 index 00000000..cff9d562 --- /dev/null +++ b/plugins/claude/subframe/skills/develop/SKILL.md @@ -0,0 +1,94 @@ +--- +name: develop +description: Implement Subframe designs with business logic. Use after designing with /subframe:design or when given a Subframe URL/page ID. +argument-hint: "[page URL, page ID, or 'the design I just made']" +--- + +Implement Subframe designs in the codebase. Fetch the design via MCP, sync components, and add business logic. + +## Workflow + +1. **Fetch the design** - Use `get_page_info` with the URL, ID, or name +2. **Sync components** - Run `npx @subframe/cli@latest sync --all` +3. **Create the page** - Put it in the right place per codebase patterns +4. **Add business logic** - Data fetching, forms, events, loading/error states + +## Fetching Designs + +``` +// By URL +get_page_info({ url: "https://app.subframe.com/PROJECT/design/PAGE_ID/edit" }) + +// By ID (e.g., from /subframe:design) +get_page_info({ id: "PAGE_ID", projectId: "PROJECT_ID" }) + +// By name +get_page_info({ name: "Settings Page", projectId: "PROJECT_ID" }) + +// List all pages first if needed +list_pages({ projectId: "PROJECT_ID" }) +``` + +Get the `projectId` from `.subframe/sync.json`. + +## Syncing Components + +Always sync before implementing: + +```bash +npx @subframe/cli@latest sync --all +``` + +**Never modify synced component files** - they get overwritten. Create wrapper components if you need to add logic. + +## Adding Business Logic + +Subframe generates presentational code with placeholder data. You add: + +**Data fetching:** + +```tsx +const { data, isLoading, error } = useQuery(...) + +if (isLoading) return +if (error) return {error.message} + +return +``` + +**Form handling:** + +```tsx +const handleSubmit = async (e: FormEvent) => { + e.preventDefault() + await submitForm(formData) +} +``` + +**Event handlers:** + +```tsx + +} /> +``` + +## Updating Existing Pages + +When a design changes: + +1. Fetch the updated design +2. Update layout/structure from new design +3. Preserve existing hooks, handlers, and state management +4. Sync any new components + +When diffing the updated design against the existing code, if there are design changes beyond what the user asked you to design (e.g., layout tweaks, new elements, removed sections), call those out and ask whether to include them. + +## MCP Tools Reference + +| Tool | Purpose | Key Parameters | +| -------------------- | -------------------- | ----------------------------------- | +| `get_page_info` | Fetch page code | `url`, `id`, or `name`; `projectId` | +| `get_component_info` | Fetch component code | `url`, `id`, or `name`; `projectId` | +| `list_pages` | List all pages | `projectId` | +| `list_components` | List all components | `projectId` | +| `get_theme` | Get Tailwind config | `projectId`, `cssType` | diff --git a/plugins/claude/subframe/skills/setup/SKILL.md b/plugins/claude/subframe/skills/setup/SKILL.md new file mode 100644 index 00000000..59128d21 --- /dev/null +++ b/plugins/claude/subframe/skills/setup/SKILL.md @@ -0,0 +1,186 @@ +--- +name: setup +description: Initialize Subframe in a new or existing project. Sets up the CLI, syncs components, configures Tailwind and fonts. +argument-hint: "[your auth token and project ID]" +--- + +Set up Subframe in a project. Parse credentials from the user's input, detect the project framework, initialize the CLI, configure Tailwind and fonts, and start the dev server. + +## Workflow + +1. **Parse credentials** - Extract the auth token and project ID from the user's input +2. **Check initialization** - Look for `.subframe/sync.json` to see if Subframe is already set up +3. **Detect framework** - Determine if this is a new or existing project, and which framework it uses +4. **Check prerequisites** - Verify the project has the required dependencies +5. **Initialize** - Run the CLI init command with the right flags +6. **Verify configuration** - The CLI typically configures Tailwind, import aliases, and syncs components automatically. Check that everything was set up correctly, and fix anything the CLI missed. +7. **Configure fonts** - Use `get_theme` MCP tool to determine Google Fonts and add them (the CLI does not do this) +8. **Summarize** - Recap what was set up and mention `/subframe:design` and `/subframe:develop` as next steps + +## Parse Credentials + +The user will typically paste an installation prompt copied from **Code > Installation** in Subframe. Extract: + +- **Auth token** - a long string, usually prefixed or labeled +- **Project ID** - a shorter alphanumeric string (also found in Subframe URLs: `app.subframe.com//...`) + +If the user doesn't provide credentials: + +- **Auth token** — Ask them to go to `app.subframe.com/settings/tokens` to create a new auth token. +- **Project ID** — Found in the URL in the Subframe app: `app.subframe.com//...`. For example, if the URL is `app.subframe.com/abcdef123456/library`, the project ID is `abcdef123456`. + +## Detect Framework + +Check for framework indicators: + +| Framework | Indicators | +| --------------- | -------------------------------------------------------------- | +| **Next.js** | `next` in `package.json` dependencies, `next.config.*` file | +| **Vite** | `vite` in `package.json` devDependencies, `vite.config.*` file | +| **Astro** | `astro` in `package.json` dependencies, `astro.config.*` file | +| **New project** | No `package.json` in the current directory | + +## Check Prerequisites + +For existing projects, verify: + +- **React 16+** - `react` in `package.json` +- **Tailwind CSS 3.4+** - `tailwindcss` in `package.json` +- **TypeScript** - `typescript` in `package.json` + +If any are missing, let the user know before proceeding. + +## Initialization Commands + +For an **existing project**: + +```bash +npx @subframe/cli@latest init --auth-token {TOKEN} -p {PROJECT_ID} --install --sync +``` + +For a **new project** (Vite): + +```bash +npx @subframe/cli@latest init --auth-token {TOKEN} -p {PROJECT_ID} --dir ./src/ui --alias '@/ui/*' --install --tailwind --sync --template vite --name subframe-app +``` + +## Configure Tailwind + +The CLI typically handles Tailwind configuration automatically during `init`. After initialization, verify the Tailwind config is wired up correctly. If the CLI missed it (or the project has a non-standard setup), apply the appropriate fix based on the Tailwind version: + +**Tailwind v3** — Add the Subframe preset to `tailwind.config.js`: + +```javascript +// In tailwind.config.js, add to module.exports: +presets: [require("./src/ui/tailwind.config")], +``` + +The `content` array must include the Subframe output directory: + +```javascript +content: ["./index.html", "./src/**/*.{js,jsx,ts,tsx}"], +``` + +**Tailwind v4** — Import Subframe's generated `theme.css` in the global CSS file (e.g., `index.css`, `styles.css`, or `globals.css`): + +```css +@import "tailwindcss"; +@import "./ui/theme.css"; +``` + +## Configure Import Aliases + +The CLI typically sets up import aliases automatically during `init`. Verify that `@/*` aliases resolve correctly after initialization. If the CLI missed it (common with Vite and Astro), apply the fix manually: + +**Vite** — Two changes needed: + +1. Add `baseUrl` and `paths` to `tsconfig.app.json` (or `tsconfig.json`): + +```json +{ + "compilerOptions": { + "baseUrl": "./", + "paths": { + "@/*": ["./src/*"] + } + } +} +``` + +2. Install `@types/node` and add resolve aliases to `vite.config.ts`: + +```bash +npm install -D @types/node +``` + +```typescript +import { resolve } from "node:path" + +export default defineConfig({ + // ...existing config + resolve: { + alias: { + "@": resolve(__dirname, "./src"), + }, + }, +}) +``` + +**Astro** — Add `baseUrl` and `paths` to `tsconfig.json` (same as Vite step 1). + +**Next.js** — Usually already configured. Check `tsconfig.json` has `@/*` paths if using the `src/` directory. + +## Configure Fonts + +After initialization, use the `get_theme` MCP tool to get the Tailwind theme config: + +``` +get_theme({ projectId: "PROJECT_ID" }) +``` + +The theme config includes `fontFamily` entries that reference Google Fonts by name. Add the corresponding font imports based on the framework: + +**Vite / Astro** — Add `` tags to the `` of `index.html`: + +```html + + + +``` + +**Next.js (App Router)** — Add `` tags to the `` in `app/layout.tsx`: + +```tsx +export default function RootLayout({ children }) { + return ( + + + + + + + {children} + + ) +} +``` + +**Next.js (Pages Router)** — Add to `pages/_document.tsx` inside the `` component. + +Font link formatting: + +- Replace spaces with `+` in font names (e.g., `Inter+Tight`) +- Include weights from the theme in the `wght@` parameter (semicolon-separated) +- Add one `` per font family, but only one set of preconnect links + +## Summarize + +After all configuration, briefly recap what was set up and mention the `/subframe:design` and `/subframe:develop` skills for next steps. + +## Important + +- **Never modify files in the Subframe output directory** (e.g., `src/ui/`) — they get overwritten on sync. +- If you must edit a synced file, add `// @subframe/sync-disable` to the top to prevent overwrites.