From 15c17ac20f4518102d4f1786264bf3a1a3c51d50 Mon Sep 17 00:00:00 2001 From: chrisjleal <184772742+chrisjleal@users.noreply.github.com> Date: Sat, 26 Sep 2026 20:12:00 -0500 Subject: [PATCH 1/3] fix: host-accurate install copy across skills and README Aligns the setup and trust-workflow skills, the plugin README, the guarded-agent example and smithery.config.json with the mcpInstallPaths SSOT: describe the step each host actually performs instead of naming a Connect control most hosts do not render. Keeps the plugin bundle, server.json discovery metadata and .cursor-plugin/.claude-plugin/.codex-plugin manifests unchanged. Co-authored-by: Cursor --- CHANGELOG.md | 4 ++-- README.md | 10 +++++----- examples/guarded-agent-action/README.md | 2 +- plugins/proofable-mcp/README.md | 2 +- .../proofable-mcp/skills/proofable-setup/SKILL.md | 8 +++++--- .../proofable-trust-workflow/references/setup.md | 12 +++++++----- skills/proofable-setup/SKILL.md | 8 +++++--- skills/proofable-trust-workflow/references/setup.md | 12 +++++++----- smithery.config.json | 4 ++-- 9 files changed, 35 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d4c1c3..4291d79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ npx -y @proofable/sdk setup ### Changed -- **Twelve public tools, documented.** Every `proofable_*` tool carries safety annotations, and `tools/list` returns one stable order. +- **Thirteen public tools, documented.** Every `proofable_*` tool carries safety annotations, and `tools/list` returns one stable order. - **One endpoint serves two MCP protocol dates.** Hosted MCP runs the MCP TypeScript SDK v2 packages and answers both `2026-07-28` and `2025-11-25` clients. - **Proofable no longer holds agent private keys.** Dedicated agent accounts are created in your wallet or runtime; only the public address reaches Proofable. - **Registry publishing is reproducible.** The publisher workflow pins `mcp-publisher` 1.8.1 with a pinned Linux AMD64 checksum. @@ -53,7 +53,7 @@ First Proofable MCP discovery package and public plugin release. The predecessor ### Added - **Hosted connection.** One OAuth endpoint at `https://mcp.proofable.me/mcp`. -- **Public tools.** The twelve `proofable_*` MCP tools documented on [docs.proofable.me/mcp](https://docs.proofable.me/mcp/overview). +- **Public tools.** The thirteen `proofable_*` MCP tools documented on [docs.proofable.me/mcp](https://docs.proofable.me/mcp/overview). - **Plugins and skills.** Plugin manifests and skills for Claude Code, Codex, and Cursor, including the trust workflow skill. ### Changed diff --git a/README.md b/README.md index a785459..716e83a 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ Add Proofable to any app, chat, or agent that speaks MCP. ## Install -**[One-click install](https://proofable.me/install)** detects your client and writes the config: Cursor, VS Code, Claude Code, or Codex. +**[One-click install](https://proofable.me/install)** detects the MCP clients on your machine and writes the config for Cursor, VS Code, Claude Code, and Codex; `npx -y @proofable/sdk setup` covers anything else. -Then click **Connect**, sign in, and ask: +Then finish sign-in in your client, and ask: ```text Show my Proofable profile and current proofs. @@ -29,13 +29,13 @@ In Claude Code, the repository is also a plugin marketplace: /plugin install proofable-mcp@proofable ``` -Use either the plugin or a manual entry, not both. The plugin registers the same endpoint and ships the skills in [`plugins/proofable-mcp`](./plugins/proofable-mcp). +Use either the plugin or a manual entry, not both. The Cursor plugin registers the endpoint; the Claude and Codex plugins ship the skills only, so register the server yourself there and sign in. The skills live in [`plugins/proofable-mcp`](./plugins/proofable-mcp). ## Connect Two paths, one endpoint, one profile: -- **Connect (OAuth):** add the hosted server, click **Connect**, sign in in the browser. Best for interactive clients. +- **Interactive sign-in (OAuth):** add the hosted server, then let your client run its own browser sign-in. Best for interactive clients. Only Claude connectors and Devin show a control called Connect; elsewhere the client starts the sign-in itself. - **Server key:** best for servers, CI, and headless agents. Send it as a Bearer token. Any MCP client: @@ -85,7 +85,7 @@ Full reference: [docs.proofable.me/mcp/tools](https://docs.proofable.me/mcp/tool ## Authentication -Two paths, one session model: interactive clients Connect with OAuth (PKCE, silent refresh); servers and CI send a server key (`npk_...`) as a Bearer token from `PROOFABLE_ACCESS_KEY`. Same endpoint, same Proofable profile, same tools and policy. Never put a key in client config or chat when Connect works. See [Auth](https://docs.proofable.me/mcp/auth). +Two paths, one session model: interactive clients let their client run browser sign-in (OAuth, PKCE, silent refresh); servers and CI send a server key (`npk_...`) as a Bearer token from `PROOFABLE_ACCESS_KEY`. Same endpoint, same Proofable profile, same tools and policy. Never put a key in client config or chat when the client can sign in for you. See [Auth](https://docs.proofable.me/mcp/auth). ## This package diff --git a/examples/guarded-agent-action/README.md b/examples/guarded-agent-action/README.md index 2404130..9cb009d 100644 --- a/examples/guarded-agent-action/README.md +++ b/examples/guarded-agent-action/README.md @@ -10,7 +10,7 @@ npx -y @proofable/sdk setup npx -y @proofable/sdk mount --apply ``` -Click **Connect** after setup. `` is `cursor`, `claude`, `codex`, `hermes`, `openclaw`, or `opencode`. VS Code uses `cursor`. +Finish the sign-in in your client after setup. `` is `cursor`, `claude`, `codex`, `hermes`, `openclaw`, or `opencode`. VS Code uses `cursor`. ## Check an action diff --git a/plugins/proofable-mcp/README.md b/plugins/proofable-mcp/README.md index 277e278..31e6c4c 100644 --- a/plugins/proofable-mcp/README.md +++ b/plugins/proofable-mcp/README.md @@ -1,6 +1,6 @@ # Proofable MCP plugin -Add `https://mcp.proofable.me/mcp`, click **Connect**, and reuse your profile, agents, and proofs. +Add `https://mcp.proofable.me/mcp`, finish the sign-in your client opens, and reuse your profile, agents, and proofs. This plugin registers that URL. If the host already installed the plugin from a marketplace or registry, do not also add a second `proofable` entry in the host MCP config. diff --git a/plugins/proofable-mcp/skills/proofable-setup/SKILL.md b/plugins/proofable-mcp/skills/proofable-setup/SKILL.md index a6892f8..476b403 100644 --- a/plugins/proofable-mcp/skills/proofable-setup/SKILL.md +++ b/plugins/proofable-mcp/skills/proofable-setup/SKILL.md @@ -11,11 +11,13 @@ Give AI agents verified identity, scoped permissions, and reusable proof through Add Proofable to any app, chat, or agent that speaks MCP. Cursor, Claude, Codex, and VS Code are shortcuts. -Install Proofable, then click **Connect**: +Add Proofable, then finish sign-in in your client: `https://mcp.proofable.me/mcp` -If the host offers the Proofable plugin, install it and click **Connect** instead of adding the URL by hand. Do not add a second `proofable` entry. +There is no universal Connect button. Cursor, VS Code, Claude Code, and Codex each run their own sign-in after the server is registered; only Claude connectors and Devin show a control called Connect. + +If the client offers the Proofable plugin, install that instead of adding the URL by hand. It ships these skills, and in Cursor it registers the server too. Do not add a second `proofable` entry. Have the CLI? @@ -23,7 +25,7 @@ Have the CLI? proofable setup ``` -After Connect, ask: +After sign-in, ask: ```text Show my Proofable profile and current proofs. diff --git a/plugins/proofable-mcp/skills/proofable-trust-workflow/references/setup.md b/plugins/proofable-mcp/skills/proofable-trust-workflow/references/setup.md index 81a84e5..497bd47 100644 --- a/plugins/proofable-mcp/skills/proofable-trust-workflow/references/setup.md +++ b/plugins/proofable-mcp/skills/proofable-trust-workflow/references/setup.md @@ -4,13 +4,15 @@ Load this file only when the user needs install, sign-in, access keys, or projec ## Install -Install Proofable on this host, then click **Connect**: +Install Proofable on this host, then finish sign-in in the client itself: `https://mcp.proofable.me/mcp` -If the host already has a Proofable plugin, use that Connect path. Do not also write a second `proofable` entry. +There is no universal Connect button. Cursor, VS Code, Claude Code, and Codex each run their own sign-in once the server is registered; only Claude connectors and Devin render a control named Connect. -If Connect is missing, use the host’s own MCP login after the URL is registered. +If the host already has a Proofable plugin, use the plugin path. Do not also write a second `proofable` entry. + +If the client shows no sign-in, use its own MCP login command after the URL is registered. Have the CLI? @@ -28,7 +30,7 @@ Create access keys under **Account → Access keys** on [proofable.me](https://p Hosted MCP: **`https://mcp.proofable.me/mcp`** -After Connect, call `proofable_context`. To sell: set payouts at https://proofable.me/profile?tab=credits, then create a listing at https://proofable.me/profile/portals/new. Full page: https://docs.proofable.me/mcp/setup +After sign-in, call `proofable_context`. To sell: set payouts at https://proofable.me/profile?tab=credits, then create a listing at https://proofable.me/profile/portals/new. Full page: https://docs.proofable.me/mcp/setup ## Connect an agent to a project @@ -44,4 +46,4 @@ proofable mount --apply | **Project** | `proofable mount --apply ` | | **Session** | `proofable_context` → `proofable_agent_mount` when acting as the agent | -Use `proofable mount` only when acting as a registered profile agent. For proofs and secrets, Connect plus `proofable_context` is enough. +Use `proofable mount` only when acting as a registered profile agent. For proofs and secrets, a completed sign-in plus `proofable_context` is enough. diff --git a/skills/proofable-setup/SKILL.md b/skills/proofable-setup/SKILL.md index a6892f8..476b403 100644 --- a/skills/proofable-setup/SKILL.md +++ b/skills/proofable-setup/SKILL.md @@ -11,11 +11,13 @@ Give AI agents verified identity, scoped permissions, and reusable proof through Add Proofable to any app, chat, or agent that speaks MCP. Cursor, Claude, Codex, and VS Code are shortcuts. -Install Proofable, then click **Connect**: +Add Proofable, then finish sign-in in your client: `https://mcp.proofable.me/mcp` -If the host offers the Proofable plugin, install it and click **Connect** instead of adding the URL by hand. Do not add a second `proofable` entry. +There is no universal Connect button. Cursor, VS Code, Claude Code, and Codex each run their own sign-in after the server is registered; only Claude connectors and Devin show a control called Connect. + +If the client offers the Proofable plugin, install that instead of adding the URL by hand. It ships these skills, and in Cursor it registers the server too. Do not add a second `proofable` entry. Have the CLI? @@ -23,7 +25,7 @@ Have the CLI? proofable setup ``` -After Connect, ask: +After sign-in, ask: ```text Show my Proofable profile and current proofs. diff --git a/skills/proofable-trust-workflow/references/setup.md b/skills/proofable-trust-workflow/references/setup.md index 81a84e5..497bd47 100644 --- a/skills/proofable-trust-workflow/references/setup.md +++ b/skills/proofable-trust-workflow/references/setup.md @@ -4,13 +4,15 @@ Load this file only when the user needs install, sign-in, access keys, or projec ## Install -Install Proofable on this host, then click **Connect**: +Install Proofable on this host, then finish sign-in in the client itself: `https://mcp.proofable.me/mcp` -If the host already has a Proofable plugin, use that Connect path. Do not also write a second `proofable` entry. +There is no universal Connect button. Cursor, VS Code, Claude Code, and Codex each run their own sign-in once the server is registered; only Claude connectors and Devin render a control named Connect. -If Connect is missing, use the host’s own MCP login after the URL is registered. +If the host already has a Proofable plugin, use the plugin path. Do not also write a second `proofable` entry. + +If the client shows no sign-in, use its own MCP login command after the URL is registered. Have the CLI? @@ -28,7 +30,7 @@ Create access keys under **Account → Access keys** on [proofable.me](https://p Hosted MCP: **`https://mcp.proofable.me/mcp`** -After Connect, call `proofable_context`. To sell: set payouts at https://proofable.me/profile?tab=credits, then create a listing at https://proofable.me/profile/portals/new. Full page: https://docs.proofable.me/mcp/setup +After sign-in, call `proofable_context`. To sell: set payouts at https://proofable.me/profile?tab=credits, then create a listing at https://proofable.me/profile/portals/new. Full page: https://docs.proofable.me/mcp/setup ## Connect an agent to a project @@ -44,4 +46,4 @@ proofable mount --apply | **Project** | `proofable mount --apply ` | | **Session** | `proofable_context` → `proofable_agent_mount` when acting as the agent | -Use `proofable mount` only when acting as a registered profile agent. For proofs and secrets, Connect plus `proofable_context` is enough. +Use `proofable mount` only when acting as a registered profile agent. For proofs and secrets, a completed sign-in plus `proofable_context` is enough. diff --git a/smithery.config.json b/smithery.config.json index 2282ad3..110b894 100644 --- a/smithery.config.json +++ b/smithery.config.json @@ -1,12 +1,12 @@ { "title": "Proofable server key", - "description": "Optional. Connect (OAuth) needs no configuration. Use a server key for CI, containers, and headless agents when browser sign-in is unavailable.", + "description": "Optional. OAuth sign-in needs no configuration. Use a server key for CI, containers, and headless agents when browser sign-in is unavailable.", "type": "object", "properties": { "profileAccessKey": { "type": "string", "title": "Proofable server key", - "description": "Optional. Create one at https://proofable.me/profile?tab=account (Access keys). Used only when browser OAuth is unavailable; otherwise click Connect.", + "description": "Optional. Create one at https://proofable.me/profile?tab=account (Access keys). Used only when browser OAuth is unavailable; otherwise let your client run its own sign-in.", "x-from": { "header": "x-proofable-access-key" } From 27a8080b537986bc41fd033274e48c63aae0c690 Mon Sep 17 00:00:00 2001 From: chrisjleal <184772742+chrisjleal@users.noreply.github.com> Date: Sat, 26 Sep 2026 21:03:07 -0500 Subject: [PATCH 2/3] fix(copy): remove 'build an app against Proofable' Replaces an unapproved phrase with approved vocabulary: 'To put Proofable behind your own product, start from github.com/proofable/sdk'. The language owner's blacklist and its rule against describing architecture as customer value both reject the original wording; the SDK is the integration path, not something a reader 'builds against'. Co-authored-by: Cursor --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 716e83a..cd74106 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ Two paths, one session model: interactive clients let their client run browser s ## This package -`@proofable/mcp` publishes the registry manifest (`server.json`) and the public skills. It does not run a local server. To build an app against Proofable, start from [github.com/proofable/sdk](https://github.com/proofable/sdk). +`@proofable/mcp` publishes the registry manifest (`server.json`) and the public skills. It does not run a local server. To put Proofable behind your own product, start from [github.com/proofable/sdk](https://github.com/proofable/sdk). ```js import { serverManifest } from '@proofable/mcp'; From 3640ab02fd8cda98b6763ac61328a2a9d8938dcb Mon Sep 17 00:00:00 2001 From: chrisjleal <184772742+chrisjleal@users.noreply.github.com> Date: Sat, 26 Sep 2026 21:27:38 -0500 Subject: [PATCH 3/3] ci: make skill parity provable on the branch, not on the sibling's default branch Pull-request CI compared mcp/skills/ against proofable/sdk checked out at its default branch, so the paired SDK pull request could never be green here and neither could this one - a deadlock across the two repositories. PR CI now proves what this repository can prove alone: canonical skills/ versus the bundled plugin copy (--plugin-only). The cross-repository comparison stays a hard gate where both sides are settled - prepublishOnly and the Release workflow - and release still fails on a real mismatch. --- .github/workflows/ci.yml | 6 +++++- .github/workflows/release.yml | 2 ++ package.json | 5 +++-- scripts/sync-plugin-skills.mjs | 13 ++++++++++++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a25eae0..55a7b40 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,11 @@ jobs: with: node-version: '24' package-manager-cache: false - - name: Validate (incl. canonical skill parity with @proofable/sdk) + # Pull-request CI proves only what this repository can prove deterministically: + # canonical skills/ vs the bundled plugin copy. The cross-repository comparison + # against proofable/sdk is release-time (see the Release workflow) because the + # paired pull requests in both repositories land atomically. + - name: Validate (canonical vs bundled plugin copy) run: npm test env: PROOFABLE_SDK_SKILLS_ROOT: ${{ github.workspace }}/sdk/skills diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3f63cb1..a19bb68 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,6 +30,8 @@ jobs: run: npm test env: PROOFABLE_SDK_SKILLS_ROOT: ${{ github.workspace }}/sdk/skills + - name: Canonical skills match the published @proofable/sdk copy + run: node scripts/sync-plugin-skills.mjs --check - run: npm pack --dry-run - name: Publish @proofable/mcp shell: bash diff --git a/package.json b/package.json index 33b0c4d..d5f2826 100644 --- a/package.json +++ b/package.json @@ -51,9 +51,10 @@ "scripts": { "validate:package": "node -e \"const fs=require('fs');const p=JSON.parse(fs.readFileSync('package.json','utf8'));const s=JSON.parse(fs.readFileSync('server.json','utf8'));if(p.version!==s.version)throw new Error('package.json and server.json version mismatch: '+p.version+' vs '+s.version);if(p.description!==s.description)throw new Error('package.json and server.json descriptions must match');if(String(s.description||'').length>100)throw new Error('server.json description must be <=100 chars for MCP Registry');if(s.repository?.url!=='https://github.com/proofable/mcp'||s.repository?.subfolder)throw new Error('server.json must point at the repository root');if(!p.files.includes('LICENSE')||!fs.existsSync('LICENSE'))throw new Error('Apache-2.0 LICENSE must be published');\"", "validate:smithery": "node scripts/validate-smithery-config.mjs", - "validate": "node scripts/validate-template.mjs && node scripts/validate-cursor-schemas.mjs && node scripts/validate-cursor-mcp.mjs && node scripts/validate-universal-manifests.mjs && node scripts/validate-brand-assets.mjs && node scripts/sync-plugin-skills.mjs --check && npm run validate:package && npm run validate:smithery", + "validate:skills-cross-repo": "node scripts/sync-plugin-skills.mjs --check", + "validate": "node scripts/validate-template.mjs && node scripts/validate-cursor-schemas.mjs && node scripts/validate-cursor-mcp.mjs && node scripts/validate-universal-manifests.mjs && node scripts/validate-brand-assets.mjs && node scripts/sync-plugin-skills.mjs --check --plugin-only && npm run validate:package && npm run validate:smithery", "test": "npm run validate", - "prepublishOnly": "npm run validate" + "prepublishOnly": "npm run validate && npm run validate:skills-cross-repo" }, "publishConfig": { "access": "public", diff --git a/scripts/sync-plugin-skills.mjs b/scripts/sync-plugin-skills.mjs index c22a0d9..cf54605 100644 --- a/scripts/sync-plugin-skills.mjs +++ b/scripts/sync-plugin-skills.mjs @@ -11,6 +11,14 @@ * * Run after editing any skill: node scripts/sync-plugin-skills.mjs * CI check (no writes): node scripts/sync-plugin-skills.mjs --check + * + * The SDK copy lives in a different repository, so comparing against it can only + * be deterministic when both repositories already carry the same content — which + * is true after a coordinated merge, not while the paired pull requests are open. + * Pull-request CI therefore proves what this repository can prove alone + * (`--plugin-only`: canonical skills/ vs the bundled plugin copy), and the + * cross-repository comparison runs where both sides are settled: at publish time + * (the `validate:skills-cross-repo` script) and at release in each repository. */ import { createHash } from 'node:crypto'; import { readdirSync, readFileSync, mkdirSync, cpSync, existsSync, rmSync } from 'node:fs'; @@ -24,6 +32,9 @@ const sdkSkillsDir = process.env.PROOFABLE_SDK_SKILLS_ROOT ? path.resolve(process.env.PROOFABLE_SDK_SKILLS_ROOT) : path.resolve(repoRoot, '../sdk/skills'); const checkMode = process.argv.includes('--check'); +// Compare only the bundled plugin copy. The SDK copy is a different repository and +// is validated at publish/release, never from an open pull request's default branch. +const pluginOnly = process.argv.includes('--plugin-only'); function directoryDigest(dir) { const entries = []; @@ -64,7 +75,7 @@ let synced = 0; const targets = [ { label: 'plugin', root: pluginSkillsDir }, - { label: 'SDK', root: sdkSkillsDir, required: true }, + ...(pluginOnly ? [] : [{ label: 'SDK', root: sdkSkillsDir, required: true }]), ]; for (const target of targets) {