expandai
v0.0.2
Published
Unified CLI and MCP server for ExpandAI
Readme
expandai
Unified CLI and MCP server for ExpandAI. Fetch any URL as clean markdown, and wire ExpandAI into Claude Code, Cursor, OpenCode, or Codex as an MCP server, a runtime webfetch hook, or a skill.
Install
bun install -g expandai
# or
npm install -g expandaiThe binary is published as expandai. One-off use without install:
bunx expandai fetch https://example.comStandalone binary
A self-contained expandai executable is published with each release — no
Node, Bun, or npm required at runtime. One command detects your platform,
downloads the right binary from GitHub Releases, and drops it on your
PATH:
curl -fsSL https://raw.githubusercontent.com/expandai/expandai-cli/main/install.sh | bashThen:
expandai whoamiThe binary bundles everything expandai mcp run, expandai hook claude-code,
and expandai hook opencode need at runtime, so the MCP server and webfetch
hooks work straight from PATH — no node/bun needed in your agent's
environment.
Quick start
expandai login # interactive auth
expandai fetch https://docs.example.com/api # full markdown
expandai fetch https://docs.example.com/api --search auth # semantic snippetsSupported harnesses
| Harness | MCP server | Webfetch hook | Skill | |-------------|:----------:|:-------------:|:-----:| | Claude Code | ✓ | ✓ | ✓ | | OpenCode | ✓ | ✓ | ✓ | | Cursor | ✓ | — | ✓ | | Codex | ✓ | — | ✓ |
Pick one — each integration works standalone. In rough preference order:
- Hook (Claude Code, OpenCode).
expandai hook install <host> <scope>— best invisible upgrade: every native web fetch the agent issues comes back as ExpandAI markdown, no prompt changes required. Also wires the MCP server in the same step. See Recommended:hook install. - Skill (all four harnesses).
expandai skill install <host> <scope>— lightest-weight: drops aSKILL.mdthat teaches the agent when to reach forexpandai fetch. - MCP server (all four harnesses).
expandai mcp install <host> <scope>— exposes the fullfetchAPI (snippets, screenshots, structured extraction) as an MCP-callable tool.
Combinations are fine — installing skill on top of hook, for example, nudges
the agent to use mcp__expandai__fetch for refinement on top of the
automatic substitution — but any single one is a complete setup.
Scopes
Every install / uninstall command takes a <scope> argument: global
or project.
global— written under your$HOME. Applies to every session of the harness, regardless of where the agent is launched. Pick this if you want ExpandAI on by default everywhere.project— written under the current working directory. Applies only when the harness is launched from inside that directory (or a subdirectory). Pick this when you want different projects to opt in independently, or when the integration should live in version control alongside the project.
The exact files each scope touches differ per harness and per integration —
see the path comment next to each install line in the sections below.
Authentication
expandai login # OAuth (browser device flow) or API key
expandai whoami # show current auth state
expandai logout # clear credentials and optionally remove installed integrationsCredentials are stored at $XDG_CONFIG_HOME/expandai/config.json (default
~/.config/expandai/config.json, mode 0600).
Environment overrides:
EXPAND_API_KEY— overrides the stored auth method.EXPAND_API_URL— overrides the API endpoint (defaults tohttps://api.expand.ai).
fetch
expandai fetch <url> returns the rendered page as markdown. Handles
JavaScript-heavy SPAs and bot-protected sites that plain curl can't read.
expandai fetch https://example.com # markdown (default)
expandai fetch example.com # https:// is added automatically
expandai fetch https://example.com --format json # full response with metadata
expandai fetch https://docs.example.com/api --search "authentication"Flags:
--format text|json— output mode (defaulttext).--search <query>— semantic search. Returns relevant snippets instead of the full page.--max-results <n>— snippet count when--searchis set. Default5, max50.--min-score <n>— minimum relevance score,0–1. Default0.6.
Recommended: hook install
expandai hook install <host> <scope> is the ideal setup on harnesses that
support it. One command, two effects:
- Installs a runtime webfetch hook that intercepts the agent's native web-fetch tool and silently substitutes ExpandAI's markdown for whatever the agent would have fetched on its own.
- Registers the MCP server at
<scope>so the agent can also explicitly callmcp__expandai__fetchfor the fullselectAPI (markdown, snippets, screenshot, links, JSON extraction, etc.).
expandai hook install claude-code global
expandai hook install opencode projectScope behavior: global writes to the harness's user settings
(~/.claude/settings.json for Claude Code, ~/.config/opencode/plugins/ for
OpenCode) — the substitution fires for every session of that harness on the
machine. project writes to per-directory equivalents
(<cwd>/.claude/settings.json, <cwd>/.opencode/plugins/) — the
substitution only fires when the harness is launched from that directory.
Why both, not just one
- The runtime hook makes the agent's native fetch path return ExpandAI markdown automatically, so even agents that haven't been told about expand.ai get clean rendered output for SPAs and bot-protected pages. No prompt changes required.
- The MCP server alone requires the agent to consciously choose
mcp__expandai__fetchover its built-in tool, which it usually won't unless something nudges it (a skill, a prompt). - Together, default web access is upgraded transparently, and explicit refinement (snippets, screenshots, structured extraction) is still one MCP tool call away.
How the substitution actually works
- Claude Code —
expandai hook install claude-code <scope>writes aPreToolUsematcher intosettings.jsonthat scopes toWebFetch. When the agent invokesWebFetch, the runner reads the SDK's hook payload from stdin, fetches the URL via expand.ai, and emits{ permissionDecision: "deny", additionalContext: <markdown> }. The denial blocks the native fetch;additionalContextis the documented channel for injecting content into the model's next turn, so the markdown still reaches the model in place of WebFetch's raw output. - OpenCode —
expandai hook install opencode <scope>copies anexpandai-webfetch.jsplugin into.opencode/plugins/. The plugin hookstool.execute.afteronwebfetch, shells out toexpandai hook opencodewith the URL, and overwritesoutput.outputwith the returned markdown. (tool.execute.beforecan only mutate args, not replace results, which is why we run inafter.)
Cursor and Codex don't expose a hook system, so hook install only accepts
claude-code and opencode. For those harnesses, use skill install +
mcp install instead.
Skill
The CLI ships a SKILL.md that teaches an agent when to reach for
expandai fetch. SKILL.md is the open-standard format that Claude Code,
Cursor, OpenCode, and Codex auto-discover for tool guidance.
expandai skill install claude-code global # ~/.claude/skills/expandai/
expandai skill install cursor project # <cwd>/.cursor/skills/expandai/
expandai skill install opencode global # ~/.config/opencode/skills/expandai/
expandai skill install codex project # <cwd>/.agents/skills/expandai/Scope behavior: global drops SKILL.md into the harness's user-level
skills directory, so the agent auto-discovers it in every session. project
drops it into the cwd-level skills directory, so it's only discovered when
the harness is launched from that directory — useful for committing the
skill alongside a project so collaborators pick it up automatically.
MCP server
expandai mcp run speaks MCP over stdio. Any MCP-aware client can call the
fetch tool, which exposes the full select API (markdown, snippets,
screenshot, links, JSON extraction, etc.).
hook install already registers the MCP server on Claude Code and OpenCode,
so this command is mostly for Cursor and Codex, or for installing the MCP
server without the runtime hook:
expandai mcp install claude-code global # ~/.claude.json
expandai mcp install claude-code project # <cwd>/.mcp.json
expandai mcp install cursor global # ~/.cursor/mcp.json
expandai mcp install cursor project # <cwd>/.cursor/mcp.json
expandai mcp install opencode global # ~/.config/opencode/opencode.json
expandai mcp install opencode project # <cwd>/opencode.json
expandai mcp install codex global # ~/.codex/config.toml
expandai mcp install codex project # <cwd>/.codex/config.tomlScope behavior: global writes the expandai entry to the harness's
user-level MCP config — the server is discoverable in every session.
project writes to the per-directory MCP config — the server is only
discoverable when the harness is launched from that directory, and the
config file is well-suited for checking into version control.
expandai mcp uninstall <host> <scope> removes the entry without touching
other servers in the same config file.
Uninstall
expandai uninstall # everything across every host and scope
expandai uninstall hook # all hooks (claude-code + opencode)
expandai uninstall mcp cursor global # just the Cursor global MCP entry
expandai uninstall skill # all skills across all hosts and scopesexpandai logout also offers an interactive multi-select cleanup when run in
a TTY.
License
Apache-2.0. See LICENSE.
