Skip to content

SCR-395: plugin distribution metadata, Cursor/Codex manifests and install-path fixes - #36

Merged
sahilsunny merged 6 commits into
mainfrom
sahil/scr-395-plugin-distribution
Oct 7, 2026
Merged

sahilsunny merged 6 commits into
mainfrom
sahil/scr-395-plugin-distribution

Conversation

@sahilsunny

Copy link
Copy Markdown
Collaborator

What

  • plugins/scrapingbee-cli/ now carries its own README.md, LICENSE and license / homepage / repository fields in the Claude manifest.
  • The same folder gains .cursor-plugin/plugin.json (with a SCRAPINGBEE_API_KEY variable and a root mcp.json that connects the ScrapingBee MCP server) and .codex-plugin/plugin.json, plus assets/logo.svg and assets/icon.png.
  • The skill's Getting-started step and rules/install.md now say that uv tool install puts scrapingbee in ~/.local/bin and how to run it when that directory is not on PATH, and document what a "Temporary failure in name resolution" means in a sandbox with a network allowlist.
  • CONTRIBUTING.md lists all three plugin manifests in the version-bump checklist; CHANGELOG.md gets an Unreleased section.

Why

  • Plugin directories require a README and a license inside the plugin folder, not just at the repo root.
  • One folder can serve Claude Code, Cursor and Codex because each reads its own manifest directory and all share skills/. Vendor directories were chosen over the portable root plugin.json because Cursor's support for that format has no variables or logo, and a root .mcp.json for Codex would also be picked up by Claude Code.
  • The MCP server is bundled for Cursor only: Codex/ChatGPT plugins accept OAuth or no-auth servers, not API-key headers, so the Codex manifest ships the skills and the README shows the one-line codex mcp add setup instead.
  • Fresh environments often lack ~/.local/bin on PATH; without the note an agent hit "command not found" after a successful install and fell back to another tool.

Verification

  • claude plugin validate --strict passes; Claude Code loads the plugin with no MCP server picked up from mcp.json.
  • cursor agent --plugin-dir loads both skills and the bundled MCP server and completes a scrape task.
  • codex plugin add installs the plugin from a local marketplace; codex exec reads the skill and runs scrapingbee scrape … --render-js false; codex mcp add … --bearer-token-env-var connects the MCP server authenticated.
  • Fresh-install smoke test (temp HOME, no ~/.local/bin on PATH): the updated skill installs and runs the CLI without a failed command.
  • scripts/check_examples.py passes and the host skill copies are in sync.

…ires

Anthropic's plugin directory moved to the developer portal at
claude.ai/directory/manage, whose validator blocks a submission on two things
this plugin lacked: a README of at least 40 words in the plugin folder, and a
license declared there (a LICENSE file in the folder or `license` in
plugin.json). The repository-root LICENSE does not count; people who install
the plugin receive only the plugin folder.

- plugins/scrapingbee-cli/README.md: the directory shows it as the listing's
  description. It says what the plugin is for, what is inside, what it needs,
  and — for the security scan, which checks for undisclosed behaviour — exactly
  what it runs, sends and fetches: skill text only, no hooks or scripts; the
  agent runs the scrapingbee CLI or calls the MCP server, which talk to
  app.scrapingbee.com over HTTPS with the user's own key, and nothing else.
- plugins/scrapingbee-cli/LICENSE: copy of the repository's MIT license.
- plugin.json: `license`, `homepage` and `repository`, the metadata fields the
  publishing guide asks for. `claude plugin validate --strict` still passes.
A live Cowork test installed scrapingbee-cli successfully, then reported
`scrapingbee: command not found` — pip had put the entrypoint in ~/.local/bin,
which that shell does not search. The agent recovered by calling the full path,
but nothing in the skill told it to, and an agent that does not work it out
will conclude the install failed and reach for another tool.

Getting-started now says where the executable is, gives the one-line PATH fix,
and names the full-path fallback, with an explicit instruction not to switch
tools over it. It also notes that a .env in the working directory is read for
the key, which is the cleanest way to hand a sandboxed shell a credential
without pasting it anywhere.

Applies to any minimal shell, not only Cowork; the eval harness never saw it
because it places the shim on PATH itself.
…ATH note

Live Cowork test, continued. With the CLI installed and runnable, every API
call failed with "Cannot connect to host app.scrapingbee.com:443 ... Temporary
failure in name resolution": the sandbox shell reaches PyPI but not the
ScrapingBee API, because the org restricts outbound traffic to an allowlist.
The MCP connector worked throughout, since connectors bypass the shell's
allowlist.

SKILL.md's MCP rule now names that case alongside "no shell" and "installation
blocked", with the error string an agent will actually see. rules/install.md
gains a section on allowlists — an org Owner can add the host (Cowork: Admin
settings → Capabilities), or use the MCP connector for single-page work while
crawls, batches and file output still need the CLI — and an explicit note not
to substitute the host's built-in fetch, which sits behind the same allowlist
and cannot render JavaScript or pass anti-bot protection.

Also completes the previous commit: install.md's "Command not found" section
only covered virtualenvs, not the ~/.local/bin user-install case the Cowork
shell hit.
@sahilsunny
sahilsunny requested a review from a team October 7, 2026 10:46
Comment thread CHANGELOG.md
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

placeholder or left like this on purpose? (I mean version number)

@sahilsunny
sahilsunny merged commit 9091c57 into main Oct 7, 2026
27 of 28 checks passed
@sahilsunny
sahilsunny deleted the sahil/scr-395-plugin-distribution branch October 7, 2026 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants