npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@platinum-dev/mcp

v0.3.0

Published

MCP server exposing Platinum sandbox microVMs as task-shaped tools (stdio transport).

Readme

@platinum-dev/mcp

The Platinum MCP server — 22 task-shaped tools that let any MCP-capable agent (Claude Code, Cursor, Windsurf, Claude Desktop) drive Platinum sandbox microVMs. Built on the official @modelcontextprotocol/sdk (pinned) over @platinum-dev/sdk — every call goes through the typed SDK client.

Quick start (the first-party path: the pt CLI)

pt login                    # once — key goes into the OS keychain
pt mcp init claude          # or: cursor | windsurf
# restart the agent, then ask it to list Platinum tools
  • pt mcp init <agent> merges {"command":"pt","args":["mcp","start","--permissions","read,exec,write"]} into the agent's MCP config — no token is ever written to the file; pt mcp start reads the keychain at launch.
  • pt mcp config [agent] prints the same snippet for manual setup.
  • pt mcp start runs this server on stdio.

Scoping flags on pt mcp start

| Flag | Effect | |---|---| | --permissions read,exec,write,manage | Register selected groups (read, exec, write, manage). Default is read,exec,write; manage is opt-in (env: PT_MCP_PERMISSIONS) | | --readonly | Register only read tools (list/read/search) — the model never sees exec/write/manage tools | | --allow-public-expose | Permit sandbox_expose with public:true (default: private tokenized URLs only; env: PT_MCP_ALLOW_PUBLIC_EXPOSE) | | --confine-sandbox <id> | HARD-lock every tool to one box: a foreign sandbox_id is rejected, sandbox_create/sandbox_delete are not registered (env: PT_MCP_CONFINE_SANDBOX) | | --sandbox <id> | Pin all default-sandbox tools to one box; never auto-creates (env: PT_MCP_SANDBOX) |

Tools (23)

Grouped by permission; a fresh pt mcp init grants read,exec,write (14 tools) and manage is opt-in.

read — sandbox_list, template_list, fs_read (offset/limit paging, utf8/base64), fs_list, fs_search (mode: name glob / mode: content regex), fs_stat, secret_list, secret_get, sandbox_secrets_list (all three METADATA ONLY) exec — run_command, run_code (python | node | bash | sh) write — fs_write (5 MB cap), fs_mkdir (mkdir -p), fs_delete (recurse for non-empty) manage (opt-in) — sandbox_create, sandbox_delete (batch, 404 = already gone), sandbox_expose (returns the full preview URL), sandbox_unexpose, sandbox_revoke_exposure, sandbox_set_egress (block_all/allow_only/block/allow_all), secret_bind, secret_unbind, secret_delete

Org secrets: what is exposed, and what is not

A secret is an org credential the sandbox never holds — the host's egress proxy writes it into the headers you named, on HTTPS only, for the exact hostnames on its allowlist. The value is not returned by any endpoint, and these tools go through @platinum-dev/sdk, so the SDK's "a raw response body is never handed back" projection is inherited here.

sandbox_create takes secrets: ['stripe-live'] (id or name, or {secret, alias?, header?}, max 16) — the same authority secret_bind needs, in the same manage group, but applied before the box boots, so the sandbox is never up with the destination reachable and the credential absent. sandbox_secrets_list answers the question an agent inside the loop actually has: is this credential armed (spend it), arming (wait and retry) or unavailable (something has to change first)?

These are deliberately absent, and should stay absent:

| Not a tool | Why | |---|---| | secret_create, secret_rotate | Both take the PLAINTEXT VALUE as an argument. A tool argument lands in the model's context, the transcript, and every MCP client log — a strictly worse channel than the shell history the CLI's stdin-only rule already refuses. Store a value as a human: printf %s "$KEY" \| pt secret create … | | secret_update | Editing allow/headers IS disclosure: add a host you control, spend the credential against it once, and you have read it out. The control plane says so by requiring secrets:use on top of secrets:write for exactly those fields. | | the declarative set-replace (PUT /:id/secrets) and detach-by-alias | Whole-set operations. A replace sent with a partial list silently revokes every credential the caller forgot, and an agent rebuilding a set from context is the caller most likely to forget one. secret_bind / secret_unbind express the same power one binding at a time. |

secret_unbind can return a warning: the revoke always lands, but if the host rejects the updated egress policy the sandbox's requests to that hostname fail closed until it is re-applied. The tool leads with that warning rather than reporting a clean success.

Under --confine-sandbox, secret_delete is not registered (it revokes bindings org-wide) and secret_get shows only the confined sandbox's bindings.

Behavior agents get for free:

  • sandbox_id is optional on exec/fs tools. Exec tools reuse-or-create a small ephemeral default sandbox (tagged metadata.mcp_default, rediscovered via the API on every call — survives server restarts and agent context compaction; fs tools reuse it but never create it). Every result echoes the sandbox it ran on.
  • Stopped default box → auto-resume + one retry; resume failure and 404s come back as prescriptive errors, never retry loops.
  • Timeouts return partial output, clearly marked. All output is capped by one shared ~50 KB budget across stdout+stderr (agent-lowerable via max_bytes) with signposted truncation — never a silent cut.
  • 429/402 errors explicitly say do not retry and point at sandbox_list + sandbox_delete to free capacity.
  • Background processes are reaped when a command returns — daemonize with setsid.
  • The default pt-base template is busybox-based; pick a python/node template via template_list for run_code.

Env-configured use (npx / raw bun)

PT_API_URL=https://api.platinum.dev PT_TOKEN=pt_live_… bun packages/mcp/index.ts

The stdio entry (index.ts) fails loudly without PT_TOKEN. Prefer pt mcp start.

Development

cd packages/mcp && bun install
bun test test/output.test.ts        # run per-file (repo CI convention)
for f in test/*.test.ts; do bun test "$f"; done

src/server.ts exports buildServer(client, opts) — one McpServer per transport (the SDK allows a single connect per instance). The stdio entry and the pt CLI both build from this factory; a future Streamable-HTTP mount does too. The anti-drift fragment test (test/fragment.openapi.test.ts) asserts the tool schemas' API-mirroring fragments (enums, ranges) match apps/api/openapi.codegen.json.