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.

io.github.charliemtnez/ghost-inspector-mcp

NPM · GHOST-INSPECTOR-MCP · SCANNED AUG 7

Analyze, validate and safely update Ghost Inspector end-to-end browser tests

Available components

64 Trust /100
Trust breakdown (6 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 →

Supply Chain Security86
  • No malware found by supply-chain analysis.Pass
  • Known CVEs were checked across the 94 of 98 dependencies we could resolve, so this covers what we could see, not the whole tree.Partial
  • No install/post-install scripts declared.Pass
  • Dependency health was assessed across the 94 of 98 dependencies we could resolve, so this covers what we could see, not the whole tree. View diagnostics → Partial
Provenance & Transparency48
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
  • Clear OSI-approved license (MIT).Pass
  • Actively maintained (last published 0 days ago).Pass
  • Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability64
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 4552 tokens (~325/item across 14 items; 14 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 Management3
  • Stability observed for 1 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Install

Add this component to your MCP client. Where a client-specific snippet is available, pick your client below and copy it straight into your config; otherwise use the connection detail shown.

npm · ghost-inspector-mcp

# add to Claude Code
claude mcp add charliemtnez-ghost-inspector-mcp -- npx -y ghost-inspector-mcp
# add to Codex CLI
codex mcp add charliemtnez-ghost-inspector-mcp -- npx -y ghost-inspector-mcp
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "charliemtnez-ghost-inspector-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "ghost-inspector-mcp"
      ],
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add charliemtnez-ghost-inspector-mcp --command npx --arg -y --arg ghost-inspector-mcp
# ~/.hermes/config.yaml
mcp_servers:
  charliemtnez-ghost-inspector-mcp:
    command: "npx"
    args: ["-y", "ghost-inspector-mcp"]
// mcp.json
{
  "mcpServers": {
    "charliemtnez-ghost-inspector-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "ghost-inspector-mcp"
      ]
    }
  }
}
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.

  • 7 Aug 26 +29
    • Tool coverage: unverified → 100 functional
    • Stability: unverified → 0.03 functional
    • MCP protocol: unverified → pass functional
    • Security disclosure: fail → pass functional
    • First check of Tool coverage: 100 functional
    • First check of Schema quality: fail functional
    • First check of Schema quality: excellent functional
    • First check of Schema quality: fail functional
  • 6 Aug 26 0
    • Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window). security
    • MCP protocol: unverified → pass functional
    • Tool coverage: unverified → 100 functional
    • First check of Tool coverage: 100 functional
    • First check of Schema quality: fail functional
    • First check of Schema quality: excellent functional
    • First check of Schema quality: fail functional
    • Package version: 0.1.1 → 0.2.0 functional
  • 5 Aug 26 35

    First indexed and scored.

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 7 Aug 2026 · Analysed npm/[email protected]

Provenance No attestation

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

Result No attestation
Ecosystem npm
Dependencies 94 packages
Packages resolved 94
Deprecated 94
Stale 29
Tree resolution Partial

The dependency tree was only partially resolved, so these counts may be incomplete.

MCP tools · 14 exposed · ~4,224 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.

Tool Tokens
gi_create_suite ~236

Creates an empty suite, optionally inside a folder. The folder is honoured at creation, so no follow-up move is needed. Refuses when a suite of the same name already exists in the same place, because Ghost Inspector allows the duplicate and nothing distinguishes the two afterwards. Pass allowDuplicateName only when the repetition is genuinely intended. 🔴 Getting the name right matters more than usual: this server never exposes suite deletion, because DELETE /suites/{id}/ cascades to every test inside with no version history and no recycle bin. Folders have no delete route in the API at all. Anything created here is tidied up by hand, in the web UI. Creating adds and overwrites nothing, so no concurrency token applies.

NameTypeReqDescription
allowDuplicateNamebooleanProceed even though a suite of this name already exists here.
folderstringFolder id to create it in. Omit to leave it unfiled.
namestringyesSuite name. Must be unique where it is being created.
organizationstringOrganization id. Defaults to GHOST_INSPECTOR_ORG_ID.

No output schema declared.

No examples provided.

gi_duplicate_test ~352

Copies an existing test, then places it in a suite and renames it in one call. Returns the new test with its steps and its dateUpdated. 🔴 This is how a test comes into existence here, and it is not a create. Ghost Inspector has no endpoint that builds a test from nothing — POST /tests/ is the listing wearing a POST — so a source test is mandatory and there is no way around that. Pick the closest existing test and adapt the copy with gi_update_test. 🔴 The copy's schedule is cleared unless keepSchedule is set. Whether a copy inherits its source's testFrequency is not verified, and in an account whose tests submit live forms against production, an inherited schedule means an unattended run posting real data. The uncertain case is pinned to the safe direction. The copy carries the source's steps verbatim, including any `execute` steps: it imports the same modules, so editing those modules still affects it. If the copy is placed in a suite with a different viewport or browser, selectors that resolved for the source may not resolve for it — validate with gi_validate_test before trusting it. If the copy is made but placing or renaming it fails, the response says so and returns the id, because the copy is already real and needs cleaning up.

NameTypeReqDescription
keepSchedulebooleanKeep any inherited schedule. Off by default; leaving it off is the safe choice.
namestringNew name. Defaults to "<source> (Copy)".
sourceTestIdstringyesThe test to copy. Required — there is no create.
suiteIdstringSuite to place it in. Defaults to the source's suite.

No output schema declared.

No examples provided.

gi_get_test ~216

Returns a single test's stored definition, identity and current state: steps, startUrl, suite, whether it is a module, its last run, and its `dateUpdated`. 🔴 `dateUpdated` is the concurrency token. gi_update_test requires it as `expectedDateUpdated` and refuses the write if the record moved since you read it. Call this first and pass the value through. Do not discover the token by sending a deliberately wrong one and reading the correct value off the refusal — that defeats the guard, which exists to prove the edit was composed against the definition that is actually stored. The steps returned are the test's OWN steps. An `execute` step names an imported module in `value` and is not expanded here, so the definition you edit may be smaller than the run you observed: a result expands every module inline. If the step you need to fix came from a module, edit that module's test, not this one.

NameTypeReqDescription
testIdstringyesThe 24-character test id.

No output schema declared.

No examples provided.

gi_inventory ~243

Read-only tour of the whole account: every folder, the suites inside it, and per-suite counts of passing / failing / module / not-yet-run tests, plus the names of the failing ones. Start here — no other question about this account can be answered without knowing what is in it. Import-only tests (modules: shared steps that other tests import, the equivalent of a function) are counted in their own bucket and never as failures. Marking a test import-only deletes its stored results, so every module looks permanently unrun; folding that into a failure count invents breakage that does not exist and aims cleanup at the steps the live tests all share. Read the `notes` field before drawing conclusions. Fetches roughly 440 KB from the API and returns a summary of it, so ask for the whole account rather than probing folder by folder. Totals always describe the entire account even when a filter narrows the listing.

NameTypeReqDescription
failingOnlybooleanList only suites with at least one failing test. Totals stay account-wide.
folderstringCase-insensitive substring of a folder name. Omit to see every folder.

No output schema declared.

No examples provided.

gi_module_usage ~336

Answers the one question the API cannot: if I edit this module, which tests break? Builds the reverse index of `execute` steps — for every imported test, its direct importers and its full transitive blast radius through nested chains. Run this BEFORE editing any module. Also surfaces three things that only appear once the index exists: import-only tests nobody imports (dead, or a test that lost its caller and is silently not running); imported tests NOT flagged import-only, which run standalone *and* inside their importers, so an edit changes both paths; and execute steps pointing at ids that no longer exist. 🔴 It also finds `vacuousTests`: tests that execute no steps at all, because their definition is only `execute` calls and the chain bottoms out in empty modules. Those pass — nothing can fail — so the dashboard shows them green while they assert nothing, which is worse than a red test and invisible any other way. Emptying one shared module does this to every test that imports it. This is the expensive tool. `steps` is absent from the test listing, so it costs one request per test in the account — a few seconds for a few hundred tests, at deliberately low concurrency because the rate limit is undisclosed. Call it once and work from the result rather than per module. A definition that cannot be read is counted in `scanned.unreadable`, never skipped silently, because a missing definition understates a blast radius.

NameTypeReqDescription
modulestringCase-insensitive substring of a module name. Narrows the listing and names every importer instead of capping the list.

No output schema declared.

No examples provided.

gi_move_suite ~213

Moves a suite, with all of its tests, into another folder. Reversible — unlike everything else on the write path — and the response carries `previousFolder` so the undo is one call. `expectedCurrentFolder` is required: state the folder you believe the suite is in, and the move is refused if it is somewhere else, which is the case where you are about to move the wrong suite. The result is verified by re-reading: the folder must have changed and `testCount` must be identical, since a move should never detach a test. Note that `DELETE /folders/{id}/` does not exist, so a folder left empty by a move can only be removed from the web UI. Folder names have to be right the first time.

NameTypeReqDescription
expectedCurrentFolderstringyesThe folder id you believe this suite is in right now. Refused if it is not.
folderIdstringyesDestination folder id.
suiteIdstringyesSuite to move.

No output schema declared.

No examples provided.

gi_propose_repair ~297

Turns a diagnosis into a concrete argument: what to change, in which test, and the token needed to write it. Read-only — it applies nothing and returns steps for you to validate first. 🔴 This server cannot see the page. It has the definition, the error and the Ghost Inspector contract, so proposals come in two kinds and are never blurred. `applicable` proposals carry a rewritten step and come from rules that hold whatever the page contains — an assertTextPresent with no target always fails, an eval without an explicit return is always undefined. `advisory` ones name a real problem that cannot be fixed without looking at the DOM, and deliberately stop there rather than inventing a selector. Refuses outright on a stale diagnosis. A failure that predates a change describes a definition that is no longer stored, so a repair built on it would overwrite whatever replaced it, with no version history to recover. 🔴 `editTarget` is frequently NOT the test you asked about. Results expand imported modules inline, so the failing step often belongs to a module — and `proposedSteps` is that module's full step list, not this test's. Editing a module affects every test importing it. Validate `proposedSteps` with gi_validate_test before writing. A proposal that has not been run is a hypothesis.

NameTypeReqDescription
testIdstringyesThe failing test. Its diagnosis drives the proposal.

No output schema declared.

No examples provided.

gi_run_test ~343

Executes a test exactly as saved and waits for the verdict. Use it to confirm a repair actually worked, or to get a fresh result when the stored one is stale. 🔴 Nothing is truncated here. Unlike gi_validate_test, which runs a throwaway copy and stops before anything can submit, this runs the real test against the real startUrl — in most accounts, production. If the test fills and submits a form, this posts a real record into whatever that form feeds, and nothing here can withdraw it. Because of that, a test that submits is refused unless `confirmSubmit` is set. The check inlines imported modules first, since a test whose steps are only `execute` calls hides its submit inside one. A test that submits nothing runs without the flag. If a chain cannot be fully expanded it counts as submitting — an unnecessary confirmation is cheaper than an unintended record. If you only need to know whether the selectors still resolve, this is the wrong tool: gi_validate_test answers that without submitting. 🔴 A wait that expires is NOT a failure. Browser runs take 20-70 seconds and slow ones take longer; the response returns the result id and says the run is still going. Read the outcome with gi_test_result rather than concluding the test failed.

NameTypeReqDescription
confirmSubmitbooleanRequired only when the test contains a step that could submit a form. Setting it means you accept a real submission against a real environment.
testIdstringyesThe 24-character test id. Import-only tests cannot run.
timeoutMsintegerHow long to wait before handing back the result id. Default 240000.

No output schema declared.

No examples provided.

gi_stale_tests ~284

Call this BEFORE diagnosing or editing any red test. Splits failures into two piles by comparing the whole `execute` chain's `dateUpdated` against each test's last run. `staleFailures` are red tests whose definition or module chain changed AFTER the failing run. The failure describes a version that no longer exists — a colleague may already have fixed it and the test simply has not run again. Editing on top of one destroys their work, and Ghost Inspector keeps no version history of steps. One level deep is not enough here, because modules nest; the whole chain is walked. `genuineFailures` have had no change since the failing run, so the failure still describes the current definition. Start there, oldest first. 🔴 Re-running is not free advice: many Ghost Inspector suites submit real forms against production. Confirm what a test does before triggering it. Also reports the case nobody looks for: passing tests whose chain changed after their last run, whose green result describes the old definition and proves nothing about the current one. Import-only modules are excluded rather than evaluated, since they have no results to compare against. Costs one request per test, a few seconds for a few hundred tests.

NameTypeReqDescription
includePassesbooleanList the passing-but-unverified tests too. Off by default because it is the long bucket; the count is always reported.

No output schema declared.

No examples provided.

gi_test_result ~425

The last run of one test: the step that failed, its error, and whether the result can be trusted at all. Read-only. This is the starting point for repairing a failure — gi_stale_tests tells you which tests to look at, this tells you what happened in one of them. 🔴 Read `verdict` and `staleness` BEFORE the error. A verdict of `stale` means the test or one of its imported modules changed after this run, so the failure describes a definition that is no longer stored. Diagnosing from it is diagnosing from nothing, and a colleague may already have fixed it. Re-run the test and read the fresh result instead. 🔴 `failingStep.resolvedTarget` is the selector that resolved, NOT what the test looks for. Ghost Inspector collapses an authored fallback array to the one it used, and sometimes normalises it so it matches nothing in the definition textually. `authoredTargets` is what was actually written. Reporting the resolved one as the intent is a real and easy misreading. 🔴 `failingStep.ownedBy` names the test that contributed the step. Results expand imported modules inline, so the failing step frequently belongs to a module rather than to the test you asked about — that module is what needs editing, and editing it affects every test that imports it. The step's position in the result is meaningless against the definition; use `ownedBy.sequenceInOwner`. Other cases it distinguishes rather than blurring: a module (import-only tests have no results at all), a run still in flight (`passing: null` is pending, never failed), a red run with no failing step (the failure was outside the steps — a start URL that would not load), and results that have been purged, which it reports as a horizon instead of as silence.

NameTypeReqDescription
runsBackinteger0 (default) is the latest run. Higher walks backwards, within the retained window.
testIdstringyesThe 24-character test id.

No output schema declared.

No examples provided.

gi_update_test ~438

Replaces a test's steps and/or renames it. 🔴 Ghost Inspector keeps NO version history of steps and no recycle bin, so this is permanent. Four guards run on every call and none can be turned off. (1) The whole `execute` chain's `dateUpdated` is compared against the test's last run; if anything changed after it, the test is stale and the call is refused, because a fix diagnosed from a failure that describes a deleted version is diagnosed from nothing — and a colleague may already have fixed it. (2) The complete prior definition comes back as `backup`, on refusals too; it is the only rollback that exists, so keep it. (3) The change is applied. (4) The record is re-read and diffed, both that what was sent landed exactly and that every field you did not send is untouched — `HTTP 200` proves neither. `expectedDateUpdated` is required: state the `dateUpdated` you believe is current, and the write is refused if the record has moved since. Read the test first; a refusal tells you the current value so a retry is one step. Before overwriting a red test, prefer gi_validate_test, which runs the current definition without saving and without submitting a form. If the staleness guard trips and you have genuinely verified the current state, `confirmStaleDiagnosis` proceeds — read what the refusal says first.

NameTypeReqDescription
confirmStaleDiagnosisbooleanProceed even though the chain changed after the last run. Only after verifying the current definition yourself; otherwise you may be overwriting someone else's fix.
expectedDateUpdatedstringyesThe dateUpdated you read from this test. Proof you have seen its current state; the write is refused if it no longer matches.
namestringNew name. Renaming does not move the test or break importers, which reference it by id.
stepsarrayReplacement step list, in order. Replaces the whole array — send every step you want kept.
testIdstringyesTest to change.

No output schema declared.

No examples provided.

gi_vacuous_tests ~260

Finds tests that pass while verifying nothing. Green is the dangerous colour: a red test gets investigated, a hollow green one sits there while every report says coverage is fine. Three classes, kept apart because conflating them hides two of them. `executesNothing` runs zero steps — its definition is only `execute` calls into empty modules. `assertsNothing` runs its steps and contains no assertion anywhere in the chain, so it can only fail if a step errors; act on this one first, it is usually the largest. `worthChecking` is a SHORTLIST, not a verdict: their single assertion is the final step, so if its target also exists on the page the test starts from, it passes with the feature completely broken. 🔴 That third class cannot be settled from the definition — the selector is simply present on the starting page and no earlier step mentions it. Scanning for a repeated target finds none of them. To decide, run the test with the decisive action removed and see whether the assertion still passes; if it does, the test proves nothing. Modules are excluded before counting: import-only deletes results, so including them would condemn the shared layer every live test depends on. Costs one request per test.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

gi_validate_test ~417

Runs a test definition through on-demand execution, which executes it and discards it — nothing in the account is created or changed. Use it to check that a selector chain still resolves before editing a test, and to check a definition you are authoring before saving it. 🔴 It drives a real browser against a real URL, so it is an action with real-world effects even though nothing is saved. Two guards apply and neither can be turned off. Modules are inlined first, because a test whose steps are just `execute` calls hides its submit inside a module and guarding the definition as written would miss it. Then the run is truncated at the first step that could submit a form, and that step is replaced by an assertion on the same target — so the whole chain is verified, including that the submit control is reachable, without ever activating it. There is no way to make this tool submit; that stays a deliberate curl. For an existing test the suite's viewport and browser are replicated, because tests inherit those and a selector can resolve on desktop and fail on mobile. Read `ranAs.configSource` to see what was actually used. A browser run takes 20-100 seconds; the tool polls until it finishes. `passing: null` in the raw API means not finished, never failed.

NameTypeReqDescription
browserstringOverride, e.g. "chrome". Omit to replicate the suite's.
definitionobjectAd-hoc definition to validate instead of an existing test.
dryRunbooleanReport exactly what would run — after modules are inlined and the submit guard applied — and stop. Nothing is sent to Ghost Inspector, no browser starts, no page loads, and no organization id is need…
testIdstringExisting test to validate. Its suite's viewport and browser are replicated.
viewportstringOverride, e.g. "1280x800". Omit to replicate the suite's.

No output schema declared.

No examples provided.

gi_whoami ~164

Confirms the configured API key works, lists the organizations it can reach, and reports whether writing is enabled. Read-only and safe to call first when diagnosing setup. 🔴 Call this before concluding that this server cannot modify anything. Every tool is registered whether or not its gate is open, so a tool being listed says nothing about whether it will run. `writesEnabled` and `runsEnabled` are the authority — GHOST_INSPECTOR_ALLOW_WRITES and GHOST_INSPECTOR_ALLOW_RUNS. When one is false the operator must set the matching variable and restart this server; it cannot be turned on from a tool call. Returns each organization's id — export the one you want as GHOST_INSPECTOR_ORG_ID to enable on-demand validation runs.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.