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

@rayrun/cli

v0.13.1

Published

Build and deploy MCP servers, connect clients, execute tools, and manage Rayrun

Readme

@rayrun/cli

Build and deploy complete MCP servers, connect supported MCP clients, execute approved tools through OAuth, and manage Rayrun through its public API.

pnpm --package @rayrun/cli@latest dlx rayrun setup https://copy-the-endpoint-from-rayrun.example/mcp

The command detects Claude Code, Codex/ChatGPT desktop, Cursor, VS Code, Windsurf/Devin Local, and OpenCode v2. In a terminal, choose user or project scope, use arrow keys and Space to select clients, then press Enter. Review the target files and confirm before writing. Ctrl+C cancels any prompt without changing files. Node.js 20.12 or newer is required.

Repeat --client to select targets, or use --all --yes to configure all detected clients. --yes skips the wizard. Redirected input or output and --no-input never open prompts; provide --client, --all, or --yes to select clients in those environments.

It writes only the public Rayrun endpoint. OAuth stays in each client; no token or API key enters a config file or shell history. Before writing, it creates private byte-for-byte backups under ~/.rayrun/backups/setup. Configuration writes are atomic and roll back together on failure.

rayrun setup <endpoint> --dry-run --all
rayrun setup <endpoint> --client cursor --client opencode --yes
rayrun setup <endpoint> --client codex --yes --login
rayrun setup rollback <backup-id>

Use --project for project-local configuration in Claude Code, Codex, Cursor, VS Code, Devin, and OpenCode. Legacy Windsurf remains user-scoped. Claude Code asks you to approve a project MCP server when the project opens. Codex loads .codex/config.toml after you trust the project; restart Codex after doing so.

Interactive setup runs supported OAuth login commands. Codex requests only the mcp:tools scope. --yes and non-interactive setup skip login unless you pass --login; use --no-login in scripts. For Codex, setup --login runs codex mcp login rayrun --scopes mcp:tools. Its success message means Codex is authenticated; it does not authenticate the Rayrun CLI, so rayrun status can still report missing CLI credentials. Run rayrun login separately; members receive tool access and workspace administrators also receive deployment and management access.

Choose the right authentication

The CLI has three credential paths:

  • Interactive CLI commands use one browser approval stored privately by the Rayrun CLI. The CLI keeps one rotating login and requests audience-bound tokens as needed. Members receive tool access; workspace administrators also receive deployment and management access. Check it with rayrun status and remove it with rayrun logout.
  • CI and unattended automation use RAYRUN_API_KEY from the environment. When it is set, it takes precedence over browser credentials for deployments and management.
  • MCP clients keep separate OAuth credentials. For supported clients, rayrun setup --login runs their login command; its success describes that client only.
rayrun login
rayrun status
rayrun doctor
rayrun status --json

status verifies the available audience-bound access tokens and reports the management credential, user, workspace, granted scopes, endpoints, and the .rayrun/project.json deployment target. doctor prints the same facts as explicit checks. The identity check itself does not require a resource-specific API scope, so a narrow CI key can inspect its own identity safely.

Discover and automate commands

Root help stays short; group and leaf help contain the detailed syntax:

rayrun --help
rayrun deployments --help
rayrun help deployments rollback
rayrun completion zsh
rayrun schema > rayrun-command-schema.json

Completion is available for Bash, Zsh, Fish, and PowerShell. schema publishes every command, option, compatibility alias, structured error shape, and exit-code meaning for agents and wrappers. Existing flat commands remain valid; resource-oriented aliases include tools call, connections add mcp, and connections add openapi.

Global automation options are accepted anywhere: --no-input prevents prompts and browser launch, --quiet suppresses progress, --debug includes failure diagnostics, --paginate follows every cursor page, and --fields name,uid selects fields from --json output. JSON failures go only to stderr as { "error": { "code", "message", "requestId", "retryable", "next" } }; stdout stays clean. Exit codes are 1 for command failure, 2 for usage, 3 for authentication, 4 for authorization, 5 for conflicts, and 6 for retryable service failures.

Execute tools

Execution commands connect to https://ray.run/mcp/direct and authenticate the person in a browser with OAuth. Run rayrun login explicitly before the first call. They do not use RAYRUN_API_KEY. Override the endpoint with --endpoint or RAYRUN_MCP_URL for a local or self-hosted Rayrun gateway.

rayrun tools describe linear.create_issue
rayrun call linear.create_issue '{"title":"Fix the release"}'
rayrun call linear.create_issue --input arguments.json

Tool names are service-qualified and must match the Direct Mode catalog exactly. Use --input - to read a JSON object from stdin, --json for machine-readable output, and --no-open to print browser URLs without launching them.

Direct Mode also proxies approved resources, templates, prompts, and completion. Prompt names use service.name; resource URIs use rayrun:connection/<service>/<upstream-uri>. Aggregate listings are limited to 16 eligible connections, 5,000 items, 4 MiB, and 60 seconds. One failed upstream fails the aggregate request instead of returning an ambiguous partial catalog.

If an exact call needs approval or a service authorization, the CLI opens the authenticated Rayrun page and saves a private continuation:

Execution paused: 12345678-1234-1234-1234-123456789abc
Resume: rayrun resume --execution-id 12345678-1234-1234-1234-123456789abc

Approve in the browser, then run the printed command. resume replays only the saved call with the server-issued continuation state; its accept response cannot authorize the call without the authenticated browser decision. Pending files can contain the exact tool arguments and are stored under ~/.rayrun/execution/pending. The resume window expires after 10 minutes; expired files are pruned by the next execution command or rayrun logout. OAuth tokens use the same private, per-host storage; keep RAYRUN_CONFIG_HOME on a local filesystem. POSIX systems enforce 0700 directories and 0600 files; Windows uses the current profile's ACL. logout removes local tokens and attempts revocation.

Build and deploy an MCP server

rayrun init creates a complete TypeScript MCP server using Node.js 24 and ViteMCP. Use --template fastmcp for Python 3.13 and FastMCP. Give the generated directory to Codex, Claude Code, or another coding agent and ask it to implement the server—not just one tool. The server may expose as many tools as the project needs, up to the release limit documented below.

Both templates are ready to be published to your own customers. When one of them calls a tool, Rayrun signs who they are in the Rayrun-Identity header: the ViteMCP template checks it with verifyIdentityAssertion from @rayrun/sdk and passes the end user to tools as context.auth, and the FastMCP template checks it in rayrun_identity.py. Calls from your own workspace carry no identity and are served anonymously.

rayrun init hacker-news-digest
# Python alternative: rayrun init hacker-news-digest --template fastmcp
cd hacker-news-digest
rayrun login

Give the project to the coding agent:

Build a complete Hacker News digest MCP in this project.
Add get_top_stories({ limit }) using the public Hacker News API.
Return each story's title, URL, score, and author.
Add tests, run them, and deploy the server to Rayrun.

The agent finishes by validating and deploying the server. Use the command for the selected template:

# ViteMCP
npm test

# FastMCP
uv run pytest

rayrun deploy --wait

rayrun.json contains the project's stable UUID and is committed with the source. The CLI deploys with an idempotent PUT, so a retry after a lost response finds the existing service and queued or active build instead of creating or rebuilding it. .rayrun/project.json caches only the current workspace and UUID connection ID and remains ignored. Use project status to restore that cache on a new laptop or clean CI checkout. Use project adopt to associate the committed project ID with a known existing source deployment; Rayrun never silently replaces an existing association.

rayrun deploy --secret GITHUB_TOKEN=<workspace-secret-uid> --wait
rayrun project status
rayrun project adopt <connection-id>
rayrun deployments list --connection <connection-id>
rayrun deployments logs <build-uid>
rayrun deployments releases <connection-id>
rayrun deployments rollback <connection-id> <release-uid> --wait

The generated rayrun.json is the deployment contract. Visible configuration belongs in environment; required secret environment names belong in secrets and are bound to workspace-secret UIDs at deploy time:

{
  "entrypoint": "dist/server.js",
  "environment": {
    "INVOICE_API_URL": "https://api.example.com"
  },
  "name": "invoice-automation",
  "projectId": "8ec6e172-0e3d-4dd0-b086-4afdf70bb6e9",
  "runtime": "node",
  "secrets": ["INVOICE_API_TOKEN"],
  "version": 2
}

Create and rotate secret values through stdin so they never enter shell history or process arguments. Rayrun never returns a secret value:

printf %s "$GITHUB_TOKEN" | rayrun secrets create GITHUB_TOKEN --stdin
rayrun secrets list
printf %s "$NEW_GITHUB_TOKEN" | rayrun secrets rotate <secret-uid> --stdin --redeploy
rayrun secrets archive <secret-uid>

--redeploy requires deployments:write in addition to secrets:write and exits nonzero if any bound service fails to restart. The secret rotation itself remains applied.

Bind the returned workspace-secret UID at deploy time with --secret.

Node projects must contain package.json with "type": "module" and a build script, plus package-lock.json. Python projects set "runtime": "python", use a .py entrypoint, and contain pyproject.toml plus uv.lock. Every server must listen on PORT and expose Streamable HTTP MCP at /mcp. NODE_ENV, PORT, and RAYRUN_DEPLOYMENT_UID are reserved.

The recommended scaffolds are golden paths, not framework lock-ins. Rayrun accepts locked Node and Python projects whose configured entrypoint serves Streamable HTTP MCP at /mcp on PORT. Source uploads reject symlinks, a Dockerfile, .env files, obvious private-key material, more than 512 files, or more than 16 MiB. Source is encrypted at rest. Builds use fixed Node 24 or Python 3.13 definitions and non-root runtime users. Activation happens only after the candidate returns at least one tool from tools/list; a failed candidate leaves the active release untouched.

Build logs are encrypted with the workspace data key and erased after 30 days. CI API keys need the separate deployments:logs:read scope to read them; interactive login requests it explicitly. The Dashboard's Deploy services key preset grants only the three deployment scopes required by this CLI workflow.

Rotating a bound workspace secret marks the source service for redeploy. Running rayrun deploy --wait again reuses the already-built image, verifies a candidate with the new secret version, and activates it without uploading the secret value or rebuilding unchanged source.

--wait follows the exact release UID returned by Rayrun when a built image is reused. Source validation, upload, build, and release transitions stream to stderr while the final human or JSON result stays on stdout. Interactive terminals also stream accessible build-log additions; narrow CI keys without deployments:logs:read continue with status updates. The CLI prints the build UID and exact resume command before polling, so interrupting the wait does not lose recovery context; a successful human-readable deploy also prints the service dashboard URL. Source images are limited to 512 MiB, workspace image retention is limited to 5 GiB, and inactive images remain available for rollback for 30 days.

A workspace can hold 25 source-deployed services, run 10 source builds concurrently, and start 50 isolated builds in 24 hours. One service can build at a time. A release may advertise up to 1,000 tools; build logs are capped at 1 MiB and erased after 30 days.

Private package-manager credentials are not accepted: .npmrc and Yarn credential files are excluded locally and rejected by the API. Build dependencies must be readable without placing a registry token in the uploaded project.

Deploy every GitHub push

Install the Rayrun GitHub App once, deploy the current branch head, and keep the service current on future pushes:

rayrun login
rayrun deploy github rayrun/hacker-news-mcp --wait
rayrun deployments github <repository-uid>

Use --root servers/support for a monorepo, --branch main to override the repository default, and the same --secret NAME=<workspace-secret-uid> bindings as local source deployment. Rayrun creates isolated preview services for same-repository pull requests by default; use --no-previews to disable them. Fork pull requests are ignored because previews may receive workspace secrets. Each signed webhook commit goes through the same source validation, isolated build, MCP verification, activation, logs, and rollback pipeline.

Re-running the command reconfigures the branch and only the settings you pass. --secret replaces all bindings, --clear-secrets clears them, and --previews re-enables previews. Disconnect with rayrun deployments github disconnect <repository-uid>; this stops future pushes and removes previews while retaining the primary deployed service.

Manage a workspace

Run rayrun login for interactive management. For CI, create a scoped key in Dashboard → Settings → API keys, then export it without putting it in a command argument or configuration file. RAYRUN_API_URL is optional and defaults to https://ray.run.

rayrun login

rayrun connect mcp https://mcp.example.com --name 'Internal tools'
rayrun connect openapi https://api.example.com/openapi.json --name 'Example API'
rayrun connections list
printf %s "$CONNECTION_CREDENTIAL_JSON" | \
  rayrun connections credential <connection-id> --stdin
rayrun connections authorize <connection-id>
rayrun connections index <connection-id>
rayrun connections disable <connection-id>
rayrun connections enable <connection-id>
rayrun connections delete <connection-id> --confirm <connection-id>
rayrun connections history <connection-id>
rayrun connections diff <connection-id> <version-uid>
rayrun connections restore <connection-id> <version-uid> --reason 'Restore reviewed settings'
rayrun access-profiles list
rayrun access-profiles history <profile-uid>
rayrun access-profiles diff <profile-uid> <version-uid>
rayrun access-profiles restore <profile-uid> <version-uid> \
  --reason 'Restore reviewed policy' --confirm-risk
rayrun webhooks list
rayrun webhooks create --file webhook.json
rayrun webhooks update <webhook-uid> --file webhook-update.json \
  --reason 'Pause deliveries during maintenance'
rayrun webhooks replay <webhook-uid> <delivery-uid>
rayrun webhooks delete <webhook-uid> --confirm <webhook-uid>
rayrun webhooks history <webhook-uid>
rayrun webhooks diff <webhook-uid> <version-uid>
rayrun webhooks restore <webhook-uid> <version-uid> \
  --reason 'Restore reviewed destination'
rayrun publications create acme-issues --name 'Acme issues' --services <connection-id>
printf %s "$OIDC_CLIENT_SECRET" | \
  rayrun publications sign-in set <publication-uid> \
  --issuer https://login.example.com --client-id rayrun-acme-issues --client-secret-stdin
rayrun publications publish <publication-uid> --reason 'Launch'
rayrun publications show <publication-uid>
rayrun publications update <publication-uid> --tool-access read-only \
  --reason 'Read-only while we review'
rayrun publications history <publication-uid>
rayrun publications diff <publication-uid> <version-uid>
rayrun publications restore <publication-uid> <version-uid> --reason 'Restore reviewed settings'
rayrun publications end-users <publication-uid>
rayrun publications end-users remove <publication-uid> <end-user-uid>
rayrun publications approvals <publication-uid>
rayrun publications domain set <publication-uid> mcp.example.com
rayrun publications domain check <publication-uid>
rayrun publications delete <publication-uid> --confirm-slug acme-issues
rayrun clients list
rayrun tools search create issue --connection <connection-id>
rayrun policy inspect <client-uid> --query issue
rayrun approvals list
rayrun activity list

List commands show a compact table. Add --json for stable machine-readable output, --limit to request up to 100 rows, and --cursor with the printed next cursor to continue. Add --paginate to follow all cursor pages and --fields name,uid to select fields from every returned item. The CLI calls the same hosted API and policy evaluator as the dashboard; it does not run a local gateway or store API keys.

Connection history versions the service name, slug, description, timeout, enablement, and payload capture together. Credentials, headers, OAuth state, authority policy, health, and index state never enter the snapshot. history is cursor-paginated, diff compares with the immediate predecessor, and restore creates a new attributed version using optimistic concurrency.

Access-profile history versions the name, description, default, and exact tool rules together. Client assignments and archival remain separate authorization events. Restore refuses references to tools that are no longer available; pass --confirm-risk only after reviewing every Destructive or Unknown tool allowed by the restored default or an exact rule. Immutable access-profile history is limited to 64 MiB per workspace.

Webhook history versions the destination URL, description, event selection, delivery mode, batch size, enablement, and payload forwarding together. Signing secrets, deliveries, retry state, and health never enter the snapshot. Restore revalidates the historical destination, creates a new attributed version, and preserves the current signing secret. Immutable webhook history is limited to 64 MiB per workspace. Destination paths and query strings can contain provider tokens, so diff requires webhooks:read; add webhooks:write to reveal full destination URLs. Read-only API keys receive null instead of current or historical URLs.

A publication offers hosted services to your own customers, who sign in with your OpenID Connect provider instead of joining your workspace. show prints the address their AI clients connect to and the callback URL your provider must allow. sign-in set defines the whole provider: scopes default to openid,email,profile and the auth method to client_secret_basic. It reads a client secret only from stdin; leave the secret out to keep the stored one, which works only while the issuer and client ID stay the same. Publication history versions the name, description, services, sign-in provider, tool access, profile, and limits together; client secrets, publishing, end users, and the custom domain never enter the snapshot. domain set prints the TXT and CNAME records to create, and domain check looks for them now instead of waiting for the scheduled check. Changing a publication needs publications:write, which the Manage publications key preset holds.

Publish Workspace Skills

Workspace Skills are Agent Skills packages delivered by compatible clients through Rayrun's SEP-2640 MCP extension. The package root must contain SKILL.md; local reads reject symlinks, special files, unsafe paths, more than 512 files, or more than 16 MiB.

rayrun skills validate ./skills/incident-response
rayrun skills push ./skills/incident-response --publish \
  --mode both --all-clients --reason 'Reviewed for production use'
rayrun skills list
rayrun skills show <skill-uid>
rayrun skills audience <skill-uid> --mode direct --profiles <profile-uid>
rayrun skills history <skill-uid>
rayrun skills diff <skill-uid> <version-uid>
rayrun skills pull <skill-uid> --output ./recovered-skill
rayrun skills restore <skill-uid> <version-uid> --reason 'Recover reviewed instructions'
rayrun skills disable <skill-uid>
rayrun skills archive <skill-uid>
rayrun skills delete <skill-uid> --confirm-name incident-response

push saves a draft unless --publish is explicit. A new draft never moves the existing published pointer. Pass --profiles as comma-separated access-profile UIDs to narrow discovery, or explicitly pass --all-clients. Later publish and audience commands preserve the current audience when both flags are omitted. Script, binary-file, and possible-secret warnings require --confirm-risk before publication. allowed-tools is guidance, not access policy.

pull refuses to overwrite an existing path and creates account-private directories and files. Restore creates another immutable draft revision and does not publish it. Permanent deletion removes all content and delivery summaries, cannot be undone, and keeps the Skill name reserved so an old skill:// URI cannot resolve to unrelated content.

Author hosted tool hooks

Interactive login requests the hook scopes. For CI, use a key with hook read and write scopes. Hook source executes in Rayrun’s hosted sandbox, not in the CLI process.

rayrun hooks pull <connection-id> <tool-uid> \
  --output hook.ts --types-output rayrun-hooks.d.ts

rayrun hooks test <connection-id> <tool-uid> \
  --file hook.ts --arguments '{"query":"release"}' --mock-result '{"items":[]}'

rayrun hooks save <connection-id> <tool-uid> \
  --file hook.ts --reason 'Normalize release results'
rayrun hooks history <connection-id> <tool-uid>
rayrun hooks diff <connection-id> <tool-uid> <draft-version-uid>
rayrun hooks restore <connection-id> <tool-uid> <draft-version-uid> \
  --reason 'Restore the reviewed mapping'
rayrun hooks reset <connection-id> <tool-uid> --confirm <hook-uid>@<version> \
  --reason 'Remove obsolete experiment history'
rayrun hooks deploy <connection-id> <tool-uid> --shadow
rayrun hooks logs <connection-id> <tool-uid>
rayrun hooks rollback <connection-id> <tool-uid> <revision-uid>
rayrun hooks deactivate <connection-id> <tool-uid> --shadow

pull can write the draft and generated TypeScript declarations separately. test compiles and runs before plus an optional after stage using your mock result; it never contacts the upstream. Each material save creates an immutable, attributed draft version; identical saves do not create noise. history is paginated, diff compares with the previous version, and restore creates a new draft head. Draft history and deployment revisions remain separate. Source and config history is limited to 64 MiB per workspace.

reset permanently removes the hook's history and deployment revisions using the current hook UID and version. A connection cannot be deleted while it owns hook history. deploy creates an immutable revision and defaults to active; rollback and deactivate also accept --shadow. Hook payloads follow the service capture setting, while timing, outcome, revision, request ID, and shadow comparison remain available. Captured details require a full-control key.

Version-controlled access policies

Draft, review, and activate

rayrun policy create --name "Support" --description "Support team tools"
rayrun policy export <profile-uid> --output support.json
# Edit support.json, then save the first server-side draft.
rayrun policy draft --file support.json --draft-revision 0 --reason "Support rollout"
rayrun policy review <profile-uid> <draft-uid>
rayrun policy activate <profile-uid> <draft-uid> --reason "Reviewed rollout"
rayrun policy history <profile-uid>

Creation starts with a block-all profile. Drafts are immutable proposed configurations, separate from the live policy. Review validates and compares an exact saved draft; it does not record an approval or require a second person. Activation applies that exact draft after checking the saved live version and current tools again. Add --confirm-risk only after reviewing a reported high-risk grant.

Use rayrun policy drafts <profile-uid> for draft revisions and attribution. Supply its newest revision with --draft-revision when saving the next draft. For older pages, use --before-revision with the last returned revision. Live policy history supports the existing --cursor pagination. A live policy change makes older drafts stale: export again, review your edits, and save a new draft. Both draft and live history remain readable after archival.

rayrun policy clone <profile-uid> --name "Support trial" --expected-version 4
rayrun policy deactivate <profile-uid> --expected-version 4
rayrun policy archive <profile-uid> --expected-version 5

Clone creates an unassigned block-all profile and saves the source configuration as its first draft; it copies neither assignments, owners, nor budgets. Deactivate atomically sets block-all and removes every explicit exception, retaining assignments and recording a revision. This is a fail-closed policy change, not a separate inactive flag. Restore a historical configuration or activate a fresh draft to resume access. Archive retires an unused profile and refuses profiles assigned to clients or Skills. All three operations require the caller's explicitly reviewed live version.

Apply a reviewed JSON document

Export an existing access profile, edit its JSON configuration, and review the validated difference:

rayrun policy export <profile-uid> --output policy.json
rayrun policy plan --file policy.json
rayrun policy apply --file policy.json --reason "Reviewed in PR 42"

Use rayrun access-profiles list to find the profile UID. Authenticate with rayrun login, or set RAYRUN_API_KEY in CI. Export and plan require policies:read; apply requires policies:write. Commit policy.json for pull-request review. --json returns machine-readable plans and results.

The document contains the workspace, profile, expected version, and complete configuration. Apply replaces the name, description, default mode, and explicit tool rules atomically. Removing a rule restores the profile default for that tool. Client assignments remain managed separately. A successful change creates one immutable history entry; applying an identical current document creates none.

Plan validates live tool references and reports whether high-risk access requires the existing --confirm-risk option. Apply repeats validation and rejects stale versions or another workspace. After applying, export the new version before the next edit; export refuses to overwrite an existing file. If another administrator changes the policy, re-export and review your edits against the new version rather than changing expectedVersion blindly. This workflow manages existing access profiles; it is not a Terraform provider or a multi-resource deployment.