Back to the catalog

Proposition 65

Is a chemical on California's Proposition 65 list, and does it need a warning?

Open source Repository Open in the app JSON README (API)

About

Is a chemical on California's Proposition 65 list, and does it need a warning?

Details

Kind
MCP servers
Topic
No topic detected
Publisher
dev.toolstop
Origin
official
Category
ferramentas
Transport
http
Version
0.1.0
Last push
2026-08-31T16:43:51Z
Repository state
ativo
Language
JavaScript
License
MIT
Added
2026-08-29 03:01:31
Updated
2026-08-29 03:01:31
Origin id
dev.toolstop/prop65

README

# toolstop

Small, stateless MCP servers. Each one does a single narrow job exactly, so an
assistant can call it instead of guessing.

Every server runs on Cloudflare Workers at `<name>.toolstop.dev`, holds no
state, and can also run locally over stdio.

## Servers

| Server | Does | Endpoint |
|---|---|---|
| [check-digits](packages/mcp-check-digits) | Validates check digits for IBAN, LEI, ISBN, GTIN/UPC/EAN, VIN, NPI, ISIN, ABA routing numbers and payment cards | `https://check-digits.toolstop.dev` |

## Connecting

Remote, over streamable HTTP. No install, no account:

```json
{
  "mcpServers": {
    "check-digits": {
      "type": "url",
      "url": "https://check-digits.toolstop.dev"
    }
  }
}
```

Local, over stdio:

```bash
npx @toolstop/check-digits
```

## Design

**Stateless.** No database, no vector index, no metered upstream API. A request
is answered from its arguments alone. Servers scale to zero and an idle one
costs nothing.

**Zero runtime dependencies.** No MCP SDK, no schema library. MCP over
streamable HTTP is request/response, which makes hand-rolled dispatch small
enough to be worth it: faster cold starts, and no supply chain.

**Telemetry records shape and outcome, never argument values.** A check-digit
server that logged its input would be storing real IBANs and card numbers. The
transport emits one row per request describing *what kind* of call happened and
whether it succeeded. `packages/_shared/transport.test.mjs` asserts that no raw
argument value can reach it.

The row also carries a session id, and it is derived from the **network** the
request came from, truncated to a /24 or /48 before hashing, never the full
address. Hashing the whole IP would not have anonymised it: the IPv4 space is 32
bits and the other inputs are public, so the id was walkable back to one address
until this was fixed on 2026-08-10. Each server's README states the complete
recorded row rather than only what is left out.

**Every tool declares `readOnlyHint`, a complete `inputSchema` and an
`outputSchema`**, so a client can tell what a call will do before making it and
what shape comes back. The transport refuses to start a server whose tools do
not state their annotations, rather than defaulting them to something reassuring.

## Repo layout

```
packages/_shared/     shared transport, dispatch and telemetry
packages/mcp-<name>/  one server
scripts/discover.mjs  derives the CI matrix from the filesystem
scripts/smoke.mjs     protocol check against a live endpoint
```

See [CLAUDE.md](CLAUDE.md) for the operating manual.

## Development

```bash
npm install
npm test                                # every server plus the shared transport
node scripts/smoke.mjs mcp-check-digits # protocol check against the live endpoint
```

## License

MIT

More