Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Percher

NPM · @PERCHER/MCP · 2 COMPONENTS

MCP-native hosting: publish and operate AI-built web apps live at name.percher.run.

0 this week 70 Trust /100

Last scanned (14 hours ago)

Scores higher than 39% of npm servers

Category Cloud Infrastructure

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security98
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • No install/post-install scripts declared.Pass
  • 65 of 232 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency6
Schema Quality & AI Usability59
  • AI-judged instruction clarity (good).Pass
  • Context-footprint check failed: tool/resource definitions use about 15875 tokens (~260/item across 61 items; 61 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
  • No destabilizing schema changes in the last 30 days.Pass
Tool Coverage78
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 35% of tool parameters carry a description.Partial
Tool Safety79
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • 1 of 7 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "percher_publish" implies "publish" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Partial
  • An AI judge read all 62 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 1 Nov 26 +15
    • Malware scan: unverified → pass ▲ security
  • 31 Oct 26 −15
    • Malware scan: pass → unverified ▼ security
    • Destructive annotations: 0% → 14% ▲ functional
    • Package version: 1.3.0 → 1.3.1 functional
  • 27 Oct 26 0
    • Stability: 0.97 → pass security
  • 26 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 93 to 97. That category is still filling its 30-day observation window: 28 days of observed history at the previous scan, 29 at this one. The score rises as the window fills, whether or not the server changes.

  • 25 Oct 26 +14
    • Malware scan: unverified → pass ▲ security
    • Stability: pass → 0.93 functional
  • 24 Oct 26 −15
    • Malware scan: pass → unverified ▼ security
    • Package version: 1.2.0 → 1.3.0 functional
  • 21 Oct 26 +15
    • Malware scan: unverified → pass ▲ security
  • 20 Oct 26 −15
    • Malware scan: pass → unverified ▼ security
    • Tool coverage: 25% → 34% ▲ functional
    • Package version: 1.1.0 → 1.2.0 functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 5 Nov 2026 · Analysed npm/@percher/mcp@1.3.1

Provenance No attestation

The registry publishes no build provenance for this version, so there is nothing to verify.

Result No attestation
Ecosystem npm

Background: How many MCP packages publish verified provenance →

Dependencies 232 packages
Packages resolved 232
Stale 65
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 61 exposed · ~15,417 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
percher_share ~201

Manage an app's collaborators (owner-only). action='list' lists collaborators + pending invites; each row's `id` is the shareId. action='invite' invites by email — role 'viewer' (read-only: analytics, deploys list, crash reports) or 'admin' (deploy + env, domains, KV, logs, PocketBase ops). An invite is PENDING until the recipient accepts; it grants no access until then, expires after 30 days, and is rate-limited to 20/h. action='set_role' changes a collaborator's role (idempotent). action='revoke' removes a collaborator or a pending invite — the recipient's next request 404s with no caching window. shareId comes from action='list'.

NameTypeReqDescription
actionstringyes–
appstring––
emailstring––
rolestring––
shareIdstring––

No output schema declared.

No examples provided.

percher_sleep ~159

Put a running app to sleep. The container stops; its routes, domains, env vars and data stay exactly as they are, and the next visitor wakes it automatically (a few seconds of cold start). Use this when a deploy, wake or scale-up was refused because the account's plan allowance is in use — the refusal names which apps are holding it, and sleeping one hands its RAM and CPU back immediately. Reversible — the next request to the app's URL brings it back, no tool call needed. Not a fix for a disk refusal: a sleeping app keeps its disk. Idempotent; an app that is already asleep returns alreadySleeping=true. Returns { status, alreadySleeping, message }.

NameTypeReqDescription
appstring––

No output schema declared.

No examples provided.

percher_supabase ~969

Supabase → PocketBase migration helper for Lovable / Bolt / v0 imports. Read-only against Percher — the Supabase personal access token (sbp_..., generate at https://supabase.com/dashboard/account/tokens) stays on the user's machine and is sent directly to api.supabase.com, never routed through Percher. action='inspect' introspects the source Supabase project and reports tables (user schemas only), authUsersCount, storageBuckets, and warnings up front (composite PKs, array columns, RLS policies, storage buckets needing separate migration, auth-user hash incompatibility). No file writes. Returns { status, projectRef, tables[], authUsersCount, storageBuckets[], warnings[], recovery, summary }. action='migrate_schema' runs the same introspection AND writes a migration PREVIEW to ./migration-preview/ (or outputDir): pb_schema.json (PocketBase collection-shape), MIGRATION_NOTES.md, and pb_migrate.js — a ready-to-run data-import script that copies rows from Supabase into PocketBase (reads credentials from env vars; auth users still need a password reset since bcrypt hashes don't carry over). A preview only — nothing lands in PocketBase until you run pb_migrate.js. Run action='inspect' first. Returns { status, projectRef, outputDir, filesWritten[], preview, recovery, summary }. action='rewrite_client' converts the project's Supabase SDK calls to the PocketBase SDK across every source file (auth + CRUD rewritten), plus swaps the package.json dependency and stubs .env keys — but ONLY when nothing Supabase remains (a hybrid project that still has storage/rpc/realtime/edge/un-mapped-auth calls keeps both SDKs + both env sets, which is correct; the report says so). `flags[]` lists locations still needing a human (file + line, no inline markers — also written to migration-preview/REWRITE_NOTES.md, which now starts with the same checklist as action='status'), in two kinds: kind='manual_review' was rewritten but its semantics differ (e.g. onAuthStateChange event shape, filter e…

NameTypeReqDescription
actionstringyes–
applyboolean––
buildboolean––
outputDirstring––
pbIdentifierstring––
projectRefstring––
rootDirstring––
scaffoldClientboolean––
supabaseIdentifiersarray––
tokenstring––

No output schema declared.

No examples provided.

percher_transfer ~174

App ownership transfer, sender side (owner-only, app-scoped). action='initiate' offers the app to another account's email; the recipient must explicitly accept for ownership to flip (offer expires after 7 days). Rate-limited to 5/h; only one pending transfer per app — TRANSFER_ALREADY_PENDING (409) otherwise. action='cancel' cancels a pending offer (transferId; only while pending). action='list' shows the app's transfer history. On accept the app moves entirely — the previous owner loses access and any connected GitHub/Forgejo webhook is disconnected (the new owner reconnects their own). action defaults to 'initiate'.

NameTypeReqDescription
actionstringyes–
appstring––
emailstring––
transferIdstring––

No output schema declared.

No examples provided.

percher_transfers ~155

Incoming ownership transfers, recipient side (account-wide, resolved from your email). action='incoming' lists pending, unexpired offers; transferId comes from there. action='accept' makes you the owner — atomic (all checks + the ownership flip run in one transaction; if you were already an admin collaborator, that row is dropped so you become owner, not both). Failures: APP_LIMIT_REACHED (your plan won't fit one more app), APP_ADMIN_SUSPENDED, TRANSFER_EXPIRED (after 7 days), TRANSFER_NOT_PENDING (already accepted/declined/cancelled). action='decline' rejects a pending offer.

NameTypeReqDescription
actionstringyes–
transferIdstring––

No output schema declared.

No examples provided.

percher_unsuspend ~103

Unsuspend an app that's been auto-suspended after a failure loop. Use only AFTER fixing the underlying cause — calling unsuspend without resolving the build/runtime failure puts the app into a 1-hour cooldown where 3 more failures (instead of the standard 8) will auto-suspend it again. Returns { ok, app, flipped, summary }; flipped=false means the app was already active.

NameTypeReqDescription
appstringyesApp name or id to unsuspend

No output schema declared.

No examples provided.

percher_versions ~23

List deployment history for an app

NameTypeReqDescription
appstring––

No output schema declared.

No examples provided.

percher_wait_for_auth ~479

Only use when `recovery.nextAction = 'wait_auth'` — i.e. percher_publish returned `status: 'auth_pending'` because the MCP session has no token. Pre-fetched device-code is in flight; this tool short-polls the exchange and, once a token lands, runs the original publish for the FIRST time (the auth_pending percher_publish call did NOT pack a tarball — that work is preserved entirely for the resume here, so the whole flow packs exactly one bundle). Inputs: - `deviceCode` — opaque string from `recovery.args.deviceCode` on the auth_pending response. Pass verbatim. - `publishArgs` — original `percher_publish` input flags from `recovery.args.publishArgs`. Pass verbatim. - `pollIntervalSec` — server-requested poll interval from `recovery.args.pollIntervalSec`. Pass verbatim when present; defaults to 5. Returns one of two shapes: - On success: the same `PublishResult` shape as percher_publish (status='live'/'queued'/'failed'/etc., recovery, url, deployId, ...). Follow `recovery.nextAction` exactly, same as a fresh percher_publish response. - On failure: `{ status: 'auth_failed', reason: 'expired'|'error', detail, recovery }`. `recovery.nextAction = 'open_login'` — call percher_publish again to start a fresh auth flow with a new device-code (do NOT call this tool again with the old code; it's dead). Polls at the server-requested interval (default ~5s, clamped to 1-30s) with a 2-minute total budget. Don't shorten the polling interval client-side — Percher's exchange endpoint enforces it server-side.

NameTypeReqDescription
deviceCodestringyesOpaque device-code returned by percher_publish.
pollIntervalSecnumber–Server-requested device-code poll interval in seconds. Echoed verbatim from the auth_pending recovery.args.pollIntervalSec. Defaults to 5 when absent; clamped to 1-30.
publishArgsobject–Original percher_publish input flags to resume with after login. Echoed verbatim from the auth_pending recovery.args.publishArgs.

No output schema declared.

No examples provided.

percher_wait_for_deploy ~814

Only use when `recovery.nextAction = 'wait_deploy'` (e.g. percher_publish returned status='queued', or percher_doctor pointed here), or when you already have a deployId and need to know whether the deploy is live yet. Never starts a new deploy — for that use percher_publish. Short-polls a single deploy and returns within `timeoutSeconds` (default 30, max 720). The default keeps each call short so the agent can resume; the bumped max equals the platform's full publish poll budget for callers that want to ride a single build to completion. Returns one of five statuses; in every case follow `result.recovery.nextAction` literally: - `live` → deploy is up; surface result.url to the user. recovery.nextAction='none'. - `failed` → terminal failure; result.error + result.recovery describe what to do. After FUTURE12 Phase 4 ambiguous build failures (generic build_failed, missing_dependency, runtime_crash, oom_killed without file-located problems) emit recovery.nextAction='run_doctor' as the primary action — call percher_doctor with recovery.args (carries `mode='deploy'` + `deployId`) and follow doctor's recovery recursively. Direct-action recoveries still emit when publish/wait already knows the answer: `set_env_vars` (missing_env with extracted keys), `fix_problems` (build problems with file/line), `retry` (infra_unavailable), `fix_config` (config_invalid), `ask_user` (quota_exceeded / unknown). `inspect_build_log` only appears when doctor explicitly hands off after classification yielded nothing. - `replaced` → terminal-but-not-failed: this row was superseded. Resolver looked at the latest deploy and the recovery field tells you what to do next: `nextAction: 'none'` with `result.url` set means the app is currently live at that URL via a newer deploy; `nextAction: 'wait_deploy'` means a newer deploy is still in flight (call percher_wait_for_deploy with the args); `nextAction: 'run_doctor'` or `nextAction: 'ask_user'` means resolution was ambiguous (no other deploys,…

NameTypeReqDescription
appstringyesApp name (the value of [app].name in percher.toml)
deployIdstringyesDeploy id returned by percher_publish (e.g. dep_abc123)
pollIntervalSecondsinteger–Seconds between polls (default 2).
timeoutSecondsinteger–Maximum wall-clock seconds to wait before returning still_running (default 30, max 720). Keeping this short is the point — the agent can resume in another short call without holding a long-lived conn…

No output schema declared.

No examples provided.

percher_webhook ~288

Your account's single outbound event webhook (account-level — one URL receives every event for every app you own: deploy.failed, deploy.succeeded, app.crashed, app.unhealthy, app.recovered, domain.expiring, security.finding). There is no per-app routing and no event filter — surface that honestly before saving. Use when the user says 'set up a webhook', 'notify my CI when a deploy succeeds', 'send deploy events to <url>', or after percher_publish when the user wants async deploy notifications instead of polling percher_wait_for_deploy. action='add' sets or replaces the URL. Each delivery is signed HMAC-SHA256 with a per-account secret; `result.signingSecret` carries that secret and is shown EXACTLY ONCE (null when the URL was unchanged and the existing secret was kept) — relay it verbatim, tell the user to store it on their receiver, and if the transcript could be archived recommend rotating via the dashboard after testing. The URL must be a public HTTPS endpoint — private IPs, localhost, link-local and metadata endpoints are rejected (SSRF guard). action='list' returns the current URL + whether a secret is set (never the secret itself). action='remove' clears the URL and stored secret (idempotent).

NameTypeReqDescription
actionstringyes–
urlstring––

No output schema declared.

No examples provided.

percher_whoami ~17

Show the signed-in user

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

Install

How do I install the Percher MCP server?

Percher runs locally as an npm package, launched with npx -y @percher/mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

npm · @percher/mcp

# add to Claude Code
claude mcp add app-percher-percher -- npx -y @percher/mcp
Common questions

What is the Percher MCP server?

Percher is an MCP server listed in the public MCP registry as app.percher/percher. MCP-native hosting: publish and operate AI-built web apps live at name.percher.run. This page covers its npm package (@percher/mcp).

Is the Percher MCP server safe to use?

Percher scores 70 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Percher MCP server expose?

Percher exposes 61 tools: percher_publish_patch, percher_publish, percher_wait_for_deploy, percher_redeploy, percher_reproduce, and 56 more. Their descriptions and schemas cost roughly 15,417 tokens of context every time the server is loaded.

Is the Percher MCP server still maintained?

Percher is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What licence is the Percher MCP server under?

Percher declares the FSL-1.1-MIT licence, which is not on the OSI-approved list. Read the terms before using it at work, and note this covers the source only, not the cost of any service it calls.