diff --git a/README.md b/README.md index 4c17b3e..b32fa9a 100644 --- a/README.md +++ b/README.md @@ -72,16 +72,15 @@ ships its own directory because each marketplace submission reads only that dire ## Authentication -All three plugins talk to the same endpoint, `https://docs.readme.com/mcp`, and all three ship -anonymous. Without a key you get read-only access to public docs, which is enough for searching and -reading, and none of the plugins prompt for anything on install. - -Write tools such as `update-docs` need a ReadMe API key. That step is the user's, not the package's, -because each client wires credentials differently and the Agent Plugins spec forbids putting them in -a plugin at all: it requires headers to be literal package data with no secrets in them, and Codex -strips `Authorization` from plugin MCP configs regardless. In every client the shape is the same, -register the server yourself with the key and your entry replaces the plugin's anonymous one. Each -plugin README has the exact snippet. +All three plugins talk to the same endpoint, `https://docs.readme.com/mcp`. Without a key you get +read-only access to public docs. Writes through `execute-request` need a ReadMe API key, and each +client wires that credential differently. + +Cursor declares `README_API_KEY` as a plugin variable and prompts for it on install (or under +**Plugins → Configure**). Claude and Codex cannot put secrets in a plugin MCP config — the Agent +Plugins spec requires headers to be literal package data, and Codex strips `Authorization` anyway +— so those clients still ship anonymous and the user registers the server themselves. Each plugin +README has the exact steps. ## License diff --git a/claude/skills/mcp-auth/SKILL.md b/claude/skills/mcp-auth/SKILL.md index f26cc61..0a3d9b7 100644 --- a/claude/skills/mcp-auth/SKILL.md +++ b/claude/skills/mcp-auth/SKILL.md @@ -5,21 +5,24 @@ description: Establish or repair the ReadMe API key behind execute-request. Use # The key behind execute-request -The plugin ships anonymous. Public reads of ReadMe's documentation need no key; anything touching -the user's own project does, and it travels on the MCP server registration rather than in the tool -call. See the `mcp-server` skill for which calls land where. +Public reads of ReadMe's documentation need no key; anything touching the user's own project does, +and it travels on the MCP server registration rather than in the tool call. See the `mcp-server` +skill for which calls land where. + +Cursor prompts for `README_API_KEY` on install. Claude and Codex ship anonymous, so those users +still have to register the server themselves. ## Tools - `execute-request` -## Assume anonymous +## Assume the registration may be empty -Most users have not registered a key, so do not spend a call proving it. Go straight to the work: +Do not spend a call proving auth unless you need the user's project. Go straight to the work: - ReadMe documentation questions — `search` and `fetch`, no key involved. - The user's project, and they have not mentioned a key — go to **No key yet** below. -- The user says they registered one, or an `execute-request` call fails — verify with the probe. +- The user says they set a key, or an `execute-request` call fails — verify with the probe. ## Verify @@ -53,7 +56,7 @@ register the key with the server or paste it in chat. Offer the better option first: -- **Preferred:** they register the server with the key themselves, so it stays out of the chat. They +- **Preferred:** they put the key on the server registration, so it stays out of the chat. They create the key under **Configuration → API Keys** in ReadMe, then follow **Registering the key** below. - **Otherwise:** they paste it and you send it as a header on each call: @@ -97,8 +100,9 @@ thing to change. ## Registering the key -Registering a `readme` server of their own replaces the plugin's anonymous one. The server name stays -the same, so the skills and tools keep working. +On Cursor, set the plugin variable. On Claude and Codex, registering a `readme` server of their own +replaces the plugin's anonymous one. The server name stays the same, so the skills and tools keep +working. Find the row for the client you are running in. If you cannot tell which one that is, ask the user — the wrong row sends them to a config file their client never reads. @@ -107,5 +111,5 @@ the wrong row sends them to a config file their client never reads. | --- | --- | | Claude Code | `export README_API_KEY=rdme_…`, then `claude mcp add --scope user --transport http readme https://docs.readme.com/mcp --header 'Authorization: Bearer ${README_API_KEY}'`. Keep the single quotes: the variable is expanded when Claude Code starts, so the key never lands in a config file. Restart afterwards | | Codex, and the ChatGPT desktop app that shares its config | `export README_API_KEY=rdme_…`, then `codex mcp add readme --url https://docs.readme.com/mcp --bearer-token-env-var README_API_KEY`. Codex reads the variable at startup, so the key never lands in a config file. Start a new session afterwards | -| Cursor | Add a `readme` entry to `~/.cursor/mcp.json` for every project, or `.cursor/mcp.json` for one: `"type": "http"`, `"url": "https://docs.readme.com/mcp"`, and a `headers` block setting `Authorization` to `Bearer ${env:README_API_KEY}`. Export the variable in the shell the editor launches from, then restart the editor, since the header resolves when the server connects | +| Cursor | Open **Customize**, find **ReadMe**, and set **ReadMe API key** under **Plugins → Configure** (also the install prompt). Create the key under **Configuration → API Keys**. Restart if the server was already connected. Do not also add a `readme` entry in `~/.cursor/mcp.json`: a user-level server with the same name overrides the plugin, including a blank or `${env:README_API_KEY}` header that never resolved | | Claude Desktop, Cowork, claude.ai, ChatGPT web | Not possible. The connector is read-only on these surfaces and cannot take a key. Say so, and offer to carry on in a CLI or editor | diff --git a/codex/skills/mcp-auth/SKILL.md b/codex/skills/mcp-auth/SKILL.md index f26cc61..0a3d9b7 100644 --- a/codex/skills/mcp-auth/SKILL.md +++ b/codex/skills/mcp-auth/SKILL.md @@ -5,21 +5,24 @@ description: Establish or repair the ReadMe API key behind execute-request. Use # The key behind execute-request -The plugin ships anonymous. Public reads of ReadMe's documentation need no key; anything touching -the user's own project does, and it travels on the MCP server registration rather than in the tool -call. See the `mcp-server` skill for which calls land where. +Public reads of ReadMe's documentation need no key; anything touching the user's own project does, +and it travels on the MCP server registration rather than in the tool call. See the `mcp-server` +skill for which calls land where. + +Cursor prompts for `README_API_KEY` on install. Claude and Codex ship anonymous, so those users +still have to register the server themselves. ## Tools - `execute-request` -## Assume anonymous +## Assume the registration may be empty -Most users have not registered a key, so do not spend a call proving it. Go straight to the work: +Do not spend a call proving auth unless you need the user's project. Go straight to the work: - ReadMe documentation questions — `search` and `fetch`, no key involved. - The user's project, and they have not mentioned a key — go to **No key yet** below. -- The user says they registered one, or an `execute-request` call fails — verify with the probe. +- The user says they set a key, or an `execute-request` call fails — verify with the probe. ## Verify @@ -53,7 +56,7 @@ register the key with the server or paste it in chat. Offer the better option first: -- **Preferred:** they register the server with the key themselves, so it stays out of the chat. They +- **Preferred:** they put the key on the server registration, so it stays out of the chat. They create the key under **Configuration → API Keys** in ReadMe, then follow **Registering the key** below. - **Otherwise:** they paste it and you send it as a header on each call: @@ -97,8 +100,9 @@ thing to change. ## Registering the key -Registering a `readme` server of their own replaces the plugin's anonymous one. The server name stays -the same, so the skills and tools keep working. +On Cursor, set the plugin variable. On Claude and Codex, registering a `readme` server of their own +replaces the plugin's anonymous one. The server name stays the same, so the skills and tools keep +working. Find the row for the client you are running in. If you cannot tell which one that is, ask the user — the wrong row sends them to a config file their client never reads. @@ -107,5 +111,5 @@ the wrong row sends them to a config file their client never reads. | --- | --- | | Claude Code | `export README_API_KEY=rdme_…`, then `claude mcp add --scope user --transport http readme https://docs.readme.com/mcp --header 'Authorization: Bearer ${README_API_KEY}'`. Keep the single quotes: the variable is expanded when Claude Code starts, so the key never lands in a config file. Restart afterwards | | Codex, and the ChatGPT desktop app that shares its config | `export README_API_KEY=rdme_…`, then `codex mcp add readme --url https://docs.readme.com/mcp --bearer-token-env-var README_API_KEY`. Codex reads the variable at startup, so the key never lands in a config file. Start a new session afterwards | -| Cursor | Add a `readme` entry to `~/.cursor/mcp.json` for every project, or `.cursor/mcp.json` for one: `"type": "http"`, `"url": "https://docs.readme.com/mcp"`, and a `headers` block setting `Authorization` to `Bearer ${env:README_API_KEY}`. Export the variable in the shell the editor launches from, then restart the editor, since the header resolves when the server connects | +| Cursor | Open **Customize**, find **ReadMe**, and set **ReadMe API key** under **Plugins → Configure** (also the install prompt). Create the key under **Configuration → API Keys**. Restart if the server was already connected. Do not also add a `readme` entry in `~/.cursor/mcp.json`: a user-level server with the same name overrides the plugin, including a blank or `${env:README_API_KEY}` header that never resolved | | Claude Desktop, Cowork, claude.ai, ChatGPT web | Not possible. The connector is read-only on these surfaces and cannot take a key. Say so, and offer to carry on in a CLI or editor | diff --git a/cursor/.cursor-plugin/plugin.json b/cursor/.cursor-plugin/plugin.json index 32074cf..185877f 100644 --- a/cursor/.cursor-plugin/plugin.json +++ b/cursor/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "readme", "displayName": "ReadMe", - "version": "1.0.0", + "version": "1.0.1", "minClientVersions": { "cursor": "3.13.0" }, @@ -31,5 +31,18 @@ "mcp" ], "skills": "./skills/", + "variables": { + "type": "object", + "properties": { + "README_API_KEY": { + "description": "API key from ReadMe Configuration → API Keys (starts with rdme_). Grants read and write access to the project the key belongs to.", + "title": "ReadMe API key", + "type": "string" + } + }, + "required": [ + "README_API_KEY" + ] + }, "mcpServers": "./mcp.json" } diff --git a/cursor/CHANGELOG.md b/cursor/CHANGELOG.md index a9ef7ac..c975e22 100644 --- a/cursor/CHANGELOG.md +++ b/cursor/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this plugin will be documented here. +## 1.0.1 — plugin-managed API key + +- Declare `README_API_KEY` as a plugin variable so Cursor prompts for it on install and exposes it under **Plugins → Configure**. +- Send `Authorization: Bearer ${README_API_KEY}` on the plugin MCP server, so writes through `execute-request` no longer require a hand-written `mcp.json`. + ## 1.0.0 — initial release - Added the `readme` MCP server pointing at ReadMe's hosted Streamable HTTP endpoint (`https://docs.readme.com/mcp`). diff --git a/cursor/README.md b/cursor/README.md index ff04304..f6a0a34 100644 --- a/cursor/README.md +++ b/cursor/README.md @@ -12,12 +12,12 @@ The server is bound to one project by its hostname, and this one is ReadMe's own ## Install -1. Open **Cursor Settings → Plugins**. -2. Search for **ReadMe**. -3. Click **Install** and choose project or user scope. +1. Open **Customize** in Cursor's sidebar. +2. Find **ReadMe** and select **Install**, choosing project or user scope. +3. Set your **ReadMe API key** when prompted (see below). -Or run `/add-plugin readme` in chat. Nothing to configure afterwards: the plugin reads public docs -straight away, and a key is only needed for writes (see below). +Or run `/add-plugin readme` in chat. Public reads of ReadMe's own docs work without a key; anything +that touches your project needs the key from step 3. ### From this repository @@ -36,6 +36,9 @@ there. Teams and Enterprise plans only. { "mcpServers": { "readme": { + "headers": { + "Authorization": "Bearer ${README_API_KEY}" + }, "type": "http", "url": "https://docs.readme.com/mcp" } @@ -43,33 +46,19 @@ there. Teams and Enterprise plans only. } ``` -## Authentication - -Public read access works without any setup, so the plugin ships no credential and asks for nothing -on install. +`${README_API_KEY}` is a plugin variable. Cursor substitutes the value you set at install (or later +under **Plugins → Configure**). It is not a shell environment variable. -Anything that changes your project goes through `execute-request` against `api.readme.com`, and that -needs your ReadMe API key. Register the server yourself once with the key, and your `readme` entry -replaces the plugin's anonymous one: +## Authentication -```json -{ - "mcpServers": { - "readme": { - "type": "http", - "url": "https://docs.readme.com/mcp", - "headers": { - "Authorization": "Bearer ${env:README_API_KEY}" - } - } - } -} -``` +Create a key under **Configuration → API Keys** in ReadMe. Paste it into the install prompt, or +open **Plugins → Configure** on the installed plugin and set **ReadMe API key**. Rotate it from +Configuration if it is ever exposed. -Put that in `~/.cursor/mcp.json` for every project, or `.cursor/mcp.json` for one. Create the key -under **Account Settings → API Keys** in ReadMe and export it as `README_API_KEY` rather than -committing it. The key decides which project the agent reaches, and grants read and write access to -it. Rotate it from Account Settings if it is ever exposed. +`search` and `fetch` still answer from ReadMe's own documentation. The key is what `execute-request` +sends to `api.readme.com`, so that tool lands in **your** project. A user-level `readme` entry in +`~/.cursor/mcp.json` overrides the plugin's headers if both exist; prefer Configure unless you are +deliberately replacing the server. ## What agents can do diff --git a/cursor/mcp.json b/cursor/mcp.json index 59156bc..ebf0d8f 100644 --- a/cursor/mcp.json +++ b/cursor/mcp.json @@ -1,6 +1,9 @@ { "mcpServers": { "readme": { + "headers": { + "Authorization": "Bearer ${README_API_KEY}" + }, "type": "http", "url": "https://docs.readme.com/mcp" } diff --git a/cursor/skills/mcp-auth/SKILL.md b/cursor/skills/mcp-auth/SKILL.md index f26cc61..0a3d9b7 100644 --- a/cursor/skills/mcp-auth/SKILL.md +++ b/cursor/skills/mcp-auth/SKILL.md @@ -5,21 +5,24 @@ description: Establish or repair the ReadMe API key behind execute-request. Use # The key behind execute-request -The plugin ships anonymous. Public reads of ReadMe's documentation need no key; anything touching -the user's own project does, and it travels on the MCP server registration rather than in the tool -call. See the `mcp-server` skill for which calls land where. +Public reads of ReadMe's documentation need no key; anything touching the user's own project does, +and it travels on the MCP server registration rather than in the tool call. See the `mcp-server` +skill for which calls land where. + +Cursor prompts for `README_API_KEY` on install. Claude and Codex ship anonymous, so those users +still have to register the server themselves. ## Tools - `execute-request` -## Assume anonymous +## Assume the registration may be empty -Most users have not registered a key, so do not spend a call proving it. Go straight to the work: +Do not spend a call proving auth unless you need the user's project. Go straight to the work: - ReadMe documentation questions — `search` and `fetch`, no key involved. - The user's project, and they have not mentioned a key — go to **No key yet** below. -- The user says they registered one, or an `execute-request` call fails — verify with the probe. +- The user says they set a key, or an `execute-request` call fails — verify with the probe. ## Verify @@ -53,7 +56,7 @@ register the key with the server or paste it in chat. Offer the better option first: -- **Preferred:** they register the server with the key themselves, so it stays out of the chat. They +- **Preferred:** they put the key on the server registration, so it stays out of the chat. They create the key under **Configuration → API Keys** in ReadMe, then follow **Registering the key** below. - **Otherwise:** they paste it and you send it as a header on each call: @@ -97,8 +100,9 @@ thing to change. ## Registering the key -Registering a `readme` server of their own replaces the plugin's anonymous one. The server name stays -the same, so the skills and tools keep working. +On Cursor, set the plugin variable. On Claude and Codex, registering a `readme` server of their own +replaces the plugin's anonymous one. The server name stays the same, so the skills and tools keep +working. Find the row for the client you are running in. If you cannot tell which one that is, ask the user — the wrong row sends them to a config file their client never reads. @@ -107,5 +111,5 @@ the wrong row sends them to a config file their client never reads. | --- | --- | | Claude Code | `export README_API_KEY=rdme_…`, then `claude mcp add --scope user --transport http readme https://docs.readme.com/mcp --header 'Authorization: Bearer ${README_API_KEY}'`. Keep the single quotes: the variable is expanded when Claude Code starts, so the key never lands in a config file. Restart afterwards | | Codex, and the ChatGPT desktop app that shares its config | `export README_API_KEY=rdme_…`, then `codex mcp add readme --url https://docs.readme.com/mcp --bearer-token-env-var README_API_KEY`. Codex reads the variable at startup, so the key never lands in a config file. Start a new session afterwards | -| Cursor | Add a `readme` entry to `~/.cursor/mcp.json` for every project, or `.cursor/mcp.json` for one: `"type": "http"`, `"url": "https://docs.readme.com/mcp"`, and a `headers` block setting `Authorization` to `Bearer ${env:README_API_KEY}`. Export the variable in the shell the editor launches from, then restart the editor, since the header resolves when the server connects | +| Cursor | Open **Customize**, find **ReadMe**, and set **ReadMe API key** under **Plugins → Configure** (also the install prompt). Create the key under **Configuration → API Keys**. Restart if the server was already connected. Do not also add a `readme` entry in `~/.cursor/mcp.json`: a user-level server with the same name overrides the plugin, including a blank or `${env:README_API_KEY}` header that never resolved | | Claude Desktop, Cowork, claude.ai, ChatGPT web | Not possible. The connector is read-only on these surfaces and cannot take a key. Say so, and offer to carry on in a CLI or editor | diff --git a/skills/mcp-auth/SKILL.md b/skills/mcp-auth/SKILL.md index f26cc61..0a3d9b7 100644 --- a/skills/mcp-auth/SKILL.md +++ b/skills/mcp-auth/SKILL.md @@ -5,21 +5,24 @@ description: Establish or repair the ReadMe API key behind execute-request. Use # The key behind execute-request -The plugin ships anonymous. Public reads of ReadMe's documentation need no key; anything touching -the user's own project does, and it travels on the MCP server registration rather than in the tool -call. See the `mcp-server` skill for which calls land where. +Public reads of ReadMe's documentation need no key; anything touching the user's own project does, +and it travels on the MCP server registration rather than in the tool call. See the `mcp-server` +skill for which calls land where. + +Cursor prompts for `README_API_KEY` on install. Claude and Codex ship anonymous, so those users +still have to register the server themselves. ## Tools - `execute-request` -## Assume anonymous +## Assume the registration may be empty -Most users have not registered a key, so do not spend a call proving it. Go straight to the work: +Do not spend a call proving auth unless you need the user's project. Go straight to the work: - ReadMe documentation questions — `search` and `fetch`, no key involved. - The user's project, and they have not mentioned a key — go to **No key yet** below. -- The user says they registered one, or an `execute-request` call fails — verify with the probe. +- The user says they set a key, or an `execute-request` call fails — verify with the probe. ## Verify @@ -53,7 +56,7 @@ register the key with the server or paste it in chat. Offer the better option first: -- **Preferred:** they register the server with the key themselves, so it stays out of the chat. They +- **Preferred:** they put the key on the server registration, so it stays out of the chat. They create the key under **Configuration → API Keys** in ReadMe, then follow **Registering the key** below. - **Otherwise:** they paste it and you send it as a header on each call: @@ -97,8 +100,9 @@ thing to change. ## Registering the key -Registering a `readme` server of their own replaces the plugin's anonymous one. The server name stays -the same, so the skills and tools keep working. +On Cursor, set the plugin variable. On Claude and Codex, registering a `readme` server of their own +replaces the plugin's anonymous one. The server name stays the same, so the skills and tools keep +working. Find the row for the client you are running in. If you cannot tell which one that is, ask the user — the wrong row sends them to a config file their client never reads. @@ -107,5 +111,5 @@ the wrong row sends them to a config file their client never reads. | --- | --- | | Claude Code | `export README_API_KEY=rdme_…`, then `claude mcp add --scope user --transport http readme https://docs.readme.com/mcp --header 'Authorization: Bearer ${README_API_KEY}'`. Keep the single quotes: the variable is expanded when Claude Code starts, so the key never lands in a config file. Restart afterwards | | Codex, and the ChatGPT desktop app that shares its config | `export README_API_KEY=rdme_…`, then `codex mcp add readme --url https://docs.readme.com/mcp --bearer-token-env-var README_API_KEY`. Codex reads the variable at startup, so the key never lands in a config file. Start a new session afterwards | -| Cursor | Add a `readme` entry to `~/.cursor/mcp.json` for every project, or `.cursor/mcp.json` for one: `"type": "http"`, `"url": "https://docs.readme.com/mcp"`, and a `headers` block setting `Authorization` to `Bearer ${env:README_API_KEY}`. Export the variable in the shell the editor launches from, then restart the editor, since the header resolves when the server connects | +| Cursor | Open **Customize**, find **ReadMe**, and set **ReadMe API key** under **Plugins → Configure** (also the install prompt). Create the key under **Configuration → API Keys**. Restart if the server was already connected. Do not also add a `readme` entry in `~/.cursor/mcp.json`: a user-level server with the same name overrides the plugin, including a blank or `${env:README_API_KEY}` header that never resolved | | Claude Desktop, Cowork, claude.ai, ChatGPT web | Not possible. The connector is read-only on these surfaces and cannot take a key. Say so, and offer to carry on in a CLI or editor |