From e15c90d8885c806771b0c575e803077bc8029aca Mon Sep 17 00:00:00 2001 From: kenny yong Date: Mon, 2 Nov 2026 18:17:56 +0800 Subject: [PATCH 1/3] Package the skills as a Claude Code and Codex plugin Add Claude Code and Codex plugin manifests and marketplaces at the repo root, so the four skills install with one command and update with the repo. The plugin ships no MCP server: the skills stay CLI first. In the etherscan skill, prefer the CLI over MCP for agents that can run shell commands, list the keyless MCP endpoint, keep MCP calls minimal, and call render_etherscan_widget only where the host displays it. Co-Authored-By: Claude Opus 5.5 --- .agents/plugins/marketplace.json | 20 ++++++++++++++ .claude-plugin/marketplace.json | 14 ++++++++++ .claude-plugin/plugin.json | 18 +++++++++++++ .codex-plugin/plugin.json | 42 +++++++++++++++++++++++++++++ README.md | 18 +++++++++++++ assets/icon.png | Bin 0 -> 7754 bytes skills/etherscan/SKILL.md | 6 +++-- skills/etherscan/references/mcp.md | 19 ++++++++++--- 8 files changed, 132 insertions(+), 5 deletions(-) create mode 100644 .agents/plugins/marketplace.json create mode 100644 .claude-plugin/marketplace.json create mode 100644 .claude-plugin/plugin.json create mode 100644 .codex-plugin/plugin.json create mode 100644 assets/icon.png diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json new file mode 100644 index 0000000..2f01cfb --- /dev/null +++ b/.agents/plugins/marketplace.json @@ -0,0 +1,20 @@ +{ + "name": "etherscan", + "interface": { + "displayName": "Etherscan" + }, + "plugins": [ + { + "name": "etherscan", + "source": { + "source": "local", + "path": "./" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_USE" + }, + "category": "Developer Tools" + } + ] +} diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 0000000..6fb5034 --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,14 @@ +{ + "name": "etherscan", + "description": "Official Etherscan plugins", + "owner": { + "name": "Etherscan" + }, + "plugins": [ + { + "name": "etherscan", + "source": "./", + "description": "Debug EVM transactions, review verified contracts, and trace on-chain money flow with Etherscan." + } + ] +} diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..bdc5bc6 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,18 @@ +{ + "name": "etherscan", + "displayName": "Etherscan", + "description": "Debug EVM transactions, review verified contracts, trace on-chain money flow, and pick the right Etherscan page, API endpoint, CLI command, or MCP tool. Uses the Etherscan CLI first.", + "author": { + "name": "Etherscan", + "url": "https://etherscan.io" + }, + "homepage": "https://github.com/etherscan/skills", + "repository": "https://github.com/etherscan/skills", + "license": "MIT", + "keywords": ["etherscan", "ethereum", "evm", "blockchain", "transactions", "smart-contracts"], + "icon": "./assets/icon.png", + "documentationUrl": "https://docs.etherscan.io", + "supportUrl": "https://etherscan.io/contactus", + "privacyPolicyUrl": "https://etherscan.io/privacypolicy", + "termsOfServiceUrl": "https://etherscan.io/terms" +} diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json new file mode 100644 index 0000000..4c8fb09 --- /dev/null +++ b/.codex-plugin/plugin.json @@ -0,0 +1,42 @@ +{ + "name": "etherscan", + "version": "0.1.0", + "description": "Debug EVM transactions, review verified contracts, trace on-chain money flow, and pick the right Etherscan page, API endpoint, CLI command, or MCP tool.", + "author": { + "name": "Etherscan", + "url": "https://etherscan.io" + }, + "homepage": "https://github.com/etherscan/skills", + "repository": "https://github.com/etherscan/skills", + "license": "MIT", + "keywords": [ + "etherscan", + "ethereum", + "evm", + "blockchain", + "transactions", + "smart-contracts" + ], + "skills": "./skills/", + "interface": { + "displayName": "Etherscan", + "shortDescription": "Debug transactions and review contracts with Etherscan.", + "longDescription": "Etherscan skills that explain EVM transactions, review verified contracts, trace on-chain money flow, and route a task to the right Etherscan website page, API endpoint, CLI command, or MCP tool. They use the Etherscan CLI first.", + "developerName": "Etherscan", + "category": "Developer Tools", + "capabilities": [ + "Read" + ], + "websiteURL": "https://etherscan.io", + "privacyPolicyURL": "https://etherscan.io/privacypolicy", + "termsOfServiceURL": "https://etherscan.io/terms", + "defaultPrompt": [ + "Explain what happened in this transaction with Etherscan.", + "Review this verified contract on Etherscan.", + "Trace where the funds from this address went." + ], + "brandColor": "#0784C3", + "composerIcon": "./assets/icon.png", + "logo": "./assets/icon.png" + } +} diff --git a/README.md b/README.md index 21604cd..fd115a5 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,24 @@ ## Installation +### As a Claude Code or Codex plugin + +The plugin installs all four skills and updates them with this repo. It contains no MCP server: the skills use the [Etherscan CLI](https://docs.etherscan.io/ai/cli.md) first, and use an Etherscan MCP connection only if you have already added one. + +In Claude Code: + +```text +/plugin marketplace add etherscan/skills +/plugin install etherscan@etherscan +``` + +In Codex: + +```bash +codex plugin marketplace add etherscan/skills +codex plugin add etherscan@etherscan +``` + ### With the Skills CLI Install every skill in this repo: diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a7bcbb70f8d5e733d9c54c3b02ef974dc2b04d21 GIT binary patch literal 7754 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 Date: Tue, 3 Nov 2026 14:27:49 +0800 Subject: [PATCH 2/3] Document the plugin files in CONTRIBUTING Co-Authored-By: Claude Opus 5.5 --- CONTRIBUTING.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 73698c9..4ca1a13 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,6 +17,16 @@ skills/ examples/ # optional — example outputs ``` +## Plugin packaging + +The repo root is also a Claude Code and Codex plugin that installs every skill under `skills/`, so a new skill ships in the plugin with no extra step. The plugin files are: + +- `.claude-plugin/plugin.json` and `.claude-plugin/marketplace.json` (Claude Code) +- `.codex-plugin/plugin.json` and `.agents/plugins/marketplace.json` (Codex) +- `assets/icon.png` + +The Claude manifest has no `version`, so every merge to `main` becomes the new plugin version for Claude Code users the next time their marketplace updates. The Codex manifest has one; bump it to release a change to Codex users. Check the plugin with `claude plugin validate .`. + ## Adding a skill 1. Create `skills//SKILL.md`. From ba405d59ad86f2b1897c54fac32c9f25f67c7b6f Mon Sep 17 00:00:00 2001 From: kenny yong Date: Wed, 4 Nov 2026 12:22:32 +0800 Subject: [PATCH 3/3] Gate CLI-first routing on a usable CLI and add a final fallback Keep the CLI as the preferred interface across products, but only when it has a resolved API key and supports the requested chain, matching etherscan-flow's fallthrough rule. Fall back to MCP when connected, and otherwise to the API or website so agents without a shell or MCP connection always have a route. Merge the two overlapping CLI bullets. Co-Authored-By: Claude Opus 5.5 --- skills/etherscan/SKILL.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/skills/etherscan/SKILL.md b/skills/etherscan/SKILL.md index 767981d..6a35a29 100644 --- a/skills/etherscan/SKILL.md +++ b/skills/etherscan/SKILL.md @@ -63,9 +63,9 @@ When the user does not specify an interface, apply these defaults. - Prefer the website for an interactive human workflow. - Prefer the API for an application integration or when the broadest endpoint coverage is required. -- Prefer the CLI for terminal automation, pipelines, or exports. -- Prefer the CLI for agent-driven, read-only lookups when the agent can run shell commands and the CLI is installed, even when an MCP connection is also available. -- Prefer MCP when the agent cannot run shell commands, or the CLI is unavailable and an MCP connection is. +- Prefer the CLI for terminal automation, pipelines, exports, and agent-driven read-only lookups when the agent can run shell commands and the CLI is installed, has a resolved API key, and supports the requested chain, even when an MCP connection is also available. +- Otherwise, prefer MCP when an MCP connection is available. +- Otherwise, use the API (or the website for an interactive human workflow) and tell the user that the CLI or MCP would need setup. ## Respect capability boundaries @@ -93,7 +93,9 @@ Use these representative cases to verify routing and guardrail behavior after ch | Show an address in the block explorer. | Use the website reference and an interactive address page. | | Export a wallet's ERC-20 transfers to CSV from a terminal. | Use the CLI reference and its pagination and CSV support. | | An agent with shell access retrieves a balance, and both the CLI and an MCP connection are available. | Use the CLI; inspect its live help before running the command. | +| An agent with shell access retrieves a balance; the CLI is installed but has no resolved API key or does not support the chain, and an MCP connection is available. | Use MCP; tell the user the CLI needs an API key or chain support to be preferred. | | An agent without shell access retrieves a balance. | Use MCP when live discovery advertises a matching tool; inspect its current schema before calling it. | +| An agent retrieves a balance, and neither a usable CLI nor an MCP connection is available. | Use the API reference and tell the user that the CLI or MCP would need setup; do not claim an unavailable interface. | | Integrate token-holder counts into a backend. | Use the API and discover the current endpoint from official documentation; do not invent an MCP tool. | | The Etherscan CLI is installed locally. | Mention the installed version, inspect its live help, and use it when it matches the requested environment and output. | | An MCP server is documented but live discovery is unavailable. | Report its availability as unknown; do not describe it as connected or infer its tool inventory. |