Web Speed
README.md
# web-speed-mcpb
The Claude Desktop extension for [Web Speed](https://getwebspeed.io). Double-click
it, paste a key, done.
This repo builds one artifact: `web-speed.mcpb`. It contains no Web Speed logic —
the engine is hosted, and this is the ~1.5 MB of plumbing that lets Claude Desktop
reach it.
## Why this exists
Installing Web Speed on Claude Desktop used to mean hand-editing
`claude_desktop_config.json` with an absolute path and a pasted API key. That is
the single place people got stuck, and it produced silent drift — three configs on
one machine, pointing at three different interpreters, with the same key in
plaintext in all of them.
## What's inside
```
manifest.json the extension descriptor (validated in CI)
server/index.js ~30 lines: hand stdio to mcp-remote, pointed at the hosted API
node_modules/ mcp-remote, vendored
icon.png 512×512
```
`server/index.js` runs the same invocation the `/account` install tab has been
handing out by hand:
```
mcp-remote https://api.getwebspeed.io/mcp/sse --header "X-Web-Speed-Key: ..."
```
That command was already proven against this server. The extension's job is to
stop the user having to type it.
### Why mcp-remote is vendored
The manual instructions use `npx -y mcp-remote@latest`. Inside a bundle that is
three problems:
1. `npx` resolves over the network on **every start** — a flaky connection becomes
"the extension is broken".
2. `@latest` means an upstream release can break a working install overnight, with
no version pinned anywhere the user can see.
3. On Windows, Claude Desktop wraps commands in `cmd.exe`, which breaks on the
space in `C:\Program Files\nodejs`. The manual instructions work around this
with a global `npm install`; a vendored copy sidesteps it.
Node itself ships **inside** Claude Desktop on macOS and Windows, so there is no
runtime for the user to install.
## Building
```bash
pnpm install --prod
pnpm dlx @anthropic-ai/mcpb validate manifest.json
pnpm dlx @anthropic-ai/mcpb pack . web-speed.mcpb
```
Two things in `pnpm-workspace.yaml` are load-bearing and easy to delete by
accident:
- **The file must exist**, even empty. If you have a pnpm workspace root
anywhere above this directory — a `pnpm-workspace.yaml` in `$HOME` will do it —
then without a local one `pnpm install` resolves against that instead and
`node_modules` lands somewhere else entirely.
- **`nodeLinker: hoisted`.** The bundle ships `node_modules` inside the archive, so
the tree has to be real directories. pnpm's default symlinks into `.pnpm/` pack
as broken links and the extension dies on load. In pnpm 10+ this setting lives
in `pnpm-workspace.yaml`, not `.npmrc` — putting it in `.npmrc` silently does
nothing.
Verify a build actually runs before releasing it:
```bash
pnpm dlx @anthropic-ai/mcpb unpack web-speed.mcpb /tmp/ws-check
find /tmp/ws-check -type l # must print nothing
WEBSPEED_API_KEY=wsp_... node /tmp/ws-check/server/index.js
```
The last command should sit waiting on stdin rather than exiting. Sending it an
MCP `initialize` frame should return `serverInfo`.
## Configuration
| Variable | Default | |
|---|---|---|
| `WEBSPEED_API_KEY` | — | Required. Supplied by Claude Desktop from the install form. |
| `WEBSPEED_MCP_URL` | `https://api.getwebspeed.io/mcp/sse` | Override for local testing. |
## Releasing
Tag `v*`. CI validates, packs, signs, and attaches `web-speed.mcpb` to the release.
`manifest.json`'s `version` and `package.json`'s `version` must match — CI fails the
build if they don't. The API server serves the download as a redirect to the
release asset, pinned by `MCPB_RELEASE_TAG`, so **bump that env var on Railway when
you tag** or `/download/web-speed.mcpb` keeps pointing at the previous release.
## License
GPL-3.0-or-later.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues