npm @bounded-systems/bounded-tools-mcpstdioupdated 2mo ago
A local, read-only MCP server (and a matching CLI) over bounded.tools' signed static API.
What can you do with bounded tools mcp?
@bounded-systems/bounded-tools-mcp
A local, read-only MCP server (and a matching CLI) over bounded.tools' signed static API.
It exposes the parts of the site that are served as verifiable, content-addressed
JSON โ the Web-Build Conformance report and the SPDX SBOM โ to any MCP client
(Claude Desktop, Claude Code, etc.), and verifies every response byte-for-byte
against the site's Sigstore-signed sha256 manifest before handing it back. If
the bytes a client would receive don't match the signed manifest, it refuses to
return them.
It runs locally over stdio โ the client spawns it as a subprocess. There is no hosted server and no network listener, which preserves the site's static / no-attack-surface posture.
A thin implementation of a generic core
This package is thin. All of the reusable machinery โ the verifying fetch
client, the sha256 manifest + Sigstore checks, and the
VerbSpec โ MCP (tools + resources) / VerbSpec โ CLI projection โ lives in
@bounded-systems/static-mcp.
bounded-tools-mcp supplies only:
- the verbs (
src/verbs.ts) โget_conformance,get_sbom, each authored once as a@bounded-systems/verbspecVerbSpec; - the resource catalog (
src/catalog.ts) โ thetools://โฆresources; - the config values (
src/config.ts) โ the origin and expected signer identity; and - the entry (
src/index.ts) โ which picks a surface and hands the spec to the core.
src/verbs.ts โโ
src/catalog.ts โโโถ buildToolsSpec(config) โโถ @bounded-systems/static-mcp
src/config.ts โโ serveVerifiedStaticMcp(spec, config) (MCP, stdio)
runStaticCli(spec, config, argv) (CLI)
Two surfaces, one definition. verbspec projects each verb to both an MCP tool and a CLI subcommand. The exact same verb set backs the MCP tools and the CLI commands โ no second definition, no drift.
What's exposed (and what isn't)
bounded.tools is a static site whose verifiable surface is intentionally small. Only artifacts the site serves as signed, content-addressed JSON are exposed here โ each is fetched and verified byte-for-byte against the signed manifest:
| Served as | Artifact | Exposed |
|---|---|---|
| signed JSON | api/v1/conformance.json |
โ
get_conformance ยท tools://conformance |
| signed JSON | sbom.spdx.json |
โ
get_sbom ยท tools://sbom |
| signed JSON | site.webmanifest |
โ
tools://webmanifest (resource only) |
| signed HTML + Markdown | the blog (blog/*.html, blog/*.md) |
โ not JSON โ see below |
Honesty over surface area. The blog is covered by the signed manifest, but it is served as HTML + Markdown, not as a JSON feed or per-post JSON documents. The verified-static core fetches-and-JSON-parses each artifact, so exposing the blog as a "tool" would mean fabricating a JSON shape the site does not actually serve. It is therefore left out rather than faked. If bounded.tools later publishes a signed
posts.json(and per-post JSON),list_posts/get_postverbs drop straight in, exactly as insite-mcp.
Install / run
Requires Node โฅ 18.17. The verbspec dependency is published to JSR, so installs
resolve it through JSR's npm bridge โ the included .npmrc sets
@jsr:registry=https://npm.jsr.io. (Consuming from a fresh environment, add that
one line to your npm config.)
# MCP server over stdio (what an MCP client launches):
npx -y @bounded-systems/bounded-tools-mcp
# CLI โ the SAME verbs, printing the verified JSON:
npx -y @bounded-systems/bounded-tools-mcp get_conformance
npx -y @bounded-systems/bounded-tools-mcp get_sbom
The MCP server logs a readiness line to stderr (stdout is the MCP channel):
bounded-tools-mcp ready (stdio) โ https://bounded.tools; signature mode=off
MCP client configuration
{
"mcpServers": {
"bounded-tools": {
"command": "npx",
"args": ["-y", "@bounded-systems/bounded-tools-mcp"],
"env": { "BOUNDED_TOOLS_MCP_SIGNATURE_MODE": "warn" }
}
}
}
Resources
| Resource URI | Endpoint | Contents |
|---|---|---|
tools://conformance |
api/v1/conformance.json |
Web-Build Conformance Standard report (HTML / WCAG 2.2 / ARIA) |
tools://sbom |
sbom.spdx.json |
SPDX software bill of materials |
tools://webmanifest |
site.webmanifest |
W3C web app manifest (PWA site metadata) |
Tools / CLI commands (read-only)
The same two verbs, on both surfaces:
| Tool / command | Args | Returns |
|---|---|---|
get_conformance |
โ | The Web-Build Conformance report |
get_sbom |
โ | The SPDX software bill of materials |
Resource reads and tool results carry a _meta.verification block (the
manifest-relative path, source URL, the verified sha256, and the manifest
signature status). The CLI prints the verified JSON; a verification failure exits
non-zero with nothing on stdout.
Verification / trust model
The site publishes a single signed manifest, https://bounded.tools/site.sha256
(sha256sum format), and a Sigstore bundle over it, site.sha256.sigstore.json.
The core enforces:
- Per-file hash check (always on). Fetch the manifest once per process; for
every resource, fetch it, SHA-256 the received bytes, and require that digest
to equal the manifest entry. A tampered file, a stale CDN edge, or a MITM โ
mismatch โ
VerificationErrorinstead of a response. A path absent from the manifest is likewise refused. - Manifest signature check (optional).
BOUNDED_TOOLS_MCP_SIGNATURE_MODE=warn|requireverifies the Sigstore bundle against the deploy workflow identity (โฆ/bounded-systems/site/.github/workflows/deploy.yml@refs/heads/main, OIDC issuerhttps://token.actions.githubusercontent.com). This is the same keyless identity published inhttps://bounded.tools/provenance.json.
Configuration
| Variable | Default | Meaning |
|---|---|---|
BOUNDED_TOOLS_MCP_BASE_URL |
https://bounded.tools |
Origin serving the site + API + manifest |
BOUNDED_TOOLS_MCP_SIGNATURE_MODE |
off |
off | warn | require |
BOUNDED_TOOLS_MCP_SIGNER_IDENTITY |
deploy workflow SAN | Expected Sigstore certificate identity |
BOUNDED_TOOLS_MCP_SIGNER_ISSUER |
GitHub Actions OIDC | Expected Sigstore OIDC issuer |
BOUNDED_TOOLS_MCP_FETCH_TIMEOUT_MS |
15000 |
Per-request fetch timeout |
Development
npm install # resolves @bounded-systems/static-mcp (npm) + verbspec (JSR bridge)
npm run build # tsc โ dist/
npm test # node --test via tsx (server + CLI; no network)
npm run typecheck
node scripts/headless-check.mjs # live end-to-end against bounded.tools
Publishing
One tag publishes the same version to three registries, mirrored. Pushing a
v* tag runs publish.yml, which fans out to:
| # | Registry | Identifier | Auth |
|---|---|---|---|
| 1 | npm | @bounded-systems/bounded-tools-mcp |
trusted publishing (OIDC) + provenance |
| 2 | JSR (mirror) | @bounded-systems/bounded-tools-mcp |
tokenless OIDC (npx jsr publish) |
| 3 | MCP Registry | io.github.bounded-systems/bounded-tools-mcp |
GitHub-OIDC namespace auth (mcp-publisher) |
There are no long-lived secrets โ every registry authenticates with the
job's short-lived GitHub Actions OIDC token (id-token: write). npm needs
npm โฅ 11.5 (the workflow upgrades npm to guarantee this). The mcp-registry job
is decoupled from the npm job (needs: verify, NOT needs: npm): the
registry proves package ownership by reading the mcpName field off the
already-published npm package, so it can run/retry independently.
[!IMPORTANT] Versions must stay in sync. The release version lives in four places that must all match:
package.json,deno.json,server.json, and thev<version>git tag. The workflow'sverifyjob hard-fails the whole release on any mismatch, so npm and JSR can never drift apart. The MCP Registry also requirespackage.jsonto carry"mcpName": "io.github.bounded-systems/bounded-tools-mcp"(it reads that field off the published npm package to prove ownership).
One-time setup (maintainer) โ do these BEFORE the first tag
(a) npm โ Trusted Publisher (on npmjs.com)
- Sign in as an owner of the
@bounded-systemsscope. - Open the package page for
@bounded-systems/bounded-tools-mcpโ Settings โ Trusted Publisher. For a brand-new package you may need to publish0.1.0once manually (or create the package), then switch to trusted publishing. - Choose GitHub Actions and enter:
- Organization / user:
bounded-systems - Repository:
bounded-tools-mcp - Workflow filename:
publish.yml - Environment: (leave blank)
- Organization / user:
- Save. No token is generated or stored anywhere.
(b) JSR โ create + link the package (on jsr.io)
- Sign in to jsr.io with GitHub and create the package
@bounded-systems/bounded-tools-mcpunder the@bounded-systemsscope. - Open the package's Settings tab โ under GitHub Repository enter
bounded-systems/bounded-tools-mcpand click Link. Linking the repo enables tokenless OIDC publishing from this workflow.
(c) MCP Registry โ nothing to pre-authorize
The io.github.bounded-systems/* namespace is auto-authorized via GitHub
OIDC: because this repo lives under github.com/bounded-systems,
mcp-publisher login github-oidc proves ownership from the Actions run itself.
Cut a release (the single command)
# 1. Bump the version in ALL of: package.json, deno.json, server.json. Commit.
# 2. Tag with the SAME version and push โ this is the only command:
git tag v0.1.0 && git push origin v0.1.0
Local dry-runs (verify without publishing)
npm pack --dry-run # npm tarball contents
npx --yes jsr publish --dry-run --allow-slow-types # JSR (or: deno publish --dry-run --allow-slow-types)
mcp-publisher validate ./server.json # MCP Registry schema check
bounded-tools-mcp depends on
@bounded-systems/static-mcp; that core is published independently (its ownv*tag โ JSR + npm) before cutting this tag.
License
MIT โ see LICENSE.
Install
Add bounded tools mcp to your client. Pick the one you use.
claude mcp add bounded-tools-mcp -- npx -y @bounded-systems/bounded-tools-mcpcodex mcp add bounded-tools-mcp -- npx -y @bounded-systems/bounded-tools-mcpamp mcp add bounded-tools-mcp -- npx -y @bounded-systems/bounded-tools-mcp{
"mcpServers": {
"bounded-tools-mcp": {
"command": "npx",
"args": [
"-y",
"@bounded-systems/bounded-tools-mcp"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"bounded-tools-mcp": {
"command": "npx",
"args": [
"-y",
"@bounded-systems/bounded-tools-mcp"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
code --add-mcp '{"name":"bounded-tools-mcp","command":"npx","args":["-y","@bounded-systems/bounded-tools-mcp"]}'Or add the block manually to `.vscode/mcp.json` under `servers`.
{
"mcpServers": {
"bounded-tools-mcp": {
"command": "npx",
"args": [
"-y",
"@bounded-systems/bounded-tools-mcp"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"bounded-tools-mcp": {
"command": "npx",
"args": [
"-y",
"@bounded-systems/bounded-tools-mcp"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"bounded-tools-mcp": {
"command": "npx",
"args": [
"-y",
"@bounded-systems/bounded-tools-mcp"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"bounded-tools-mcp": {
"type": "local",
"command": "npx",
"args": [
"-y",
"@bounded-systems/bounded-tools-mcp"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"bounded-tools-mcp": {
"command": {
"path": "npx",
"args": [
"-y",
"@bounded-systems/bounded-tools-mcp"
]
}
}
}
}Add to your Zed `settings.json`.
npx -y @bounded-systems/bounded-tools-mcpRun `goose configure`, choose **Add Extension โ Command-line Extension**, and paste this command.
2 tools
bounded tools mcp exposes 2 tools to a connected agent.
- get_conformance
- โ
- get_sbom
- โ
Score
66 / 100
Good
- Documentation25/25
- Maintenance16/25
- Trust6/20
- Capability7/15
- Install experience12/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 64 days ago
- Has a release history
- Repository is not archived
- No licence detected
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 2 tool(s) documented
- Provides prompt templates
- Provides resources
- 12 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint โ no local install
Version history
| Versions | Published |
|---|---|
| 0.1.0Latest | Jun 29, 2026 |