PerspectiveGraph
OCI · GHCR.IO/LUIACUANIELLO/PERSPECTIVEGRAPH
Read-only attack-path tools: reachable routes to sensitive assets, and what a fix would cut.
Available components
Last scanned (1 hour ago)
Scores higher than 99% of OCI servers
Category Security
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 Security8
- No malware scan is available for this kind of package: the supply-chain vendors we use do not cover it. This is a permanent gap in our coverage, not a finding about the package.Unverified
- CVE check failed: a known advisory affects this package; its severity couldn't be graded. See how to fix → View diagnostics → Fail
- Install-script risk not yet assessed.Unverified
- Dependency health could not be checked: this image's dependency list comes from an SBOM its publisher attached. It names packages and versions but not whether each is deprecated, still maintained or linked to its source, so there is nothing we can fairly grade.Unverified
Provenance & Transparency100
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Cryptographically verified build provenance (signed, bound to luiacuaniello/perspectivegraph). View diagnostics → Pass
- Clear OSI-approved license (Apache-2.0).Pass
- Actively maintained (last published 2 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability73
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 1387 tokens (~173/item across 8 items; 8 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 Management57
- Stability observed for 17 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
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 8 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 8 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
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.
- 17 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 53 to 57. That category is still filling its 30-day observation window: 16 days of observed history at the previous scan, 17 at this one. The score rises as the window fills, whether or not the server changes.
- 15 Oct 26 +39
- Injection markers: unverified → pass ▲ security
- Schema quality: 118 → 173 ▼ functional
- Tool coverage: unverified → 100 ▲ functional
- Stability: unverified → 0.50 ▲ functional
- MCP protocol: unverified → pass ▲ functional
- First check of Tool coverage: 100 functional
- 14 Oct 26 0
- Package version: v1.38.0 → v1.38.1 functional
- Package version: v1.31.0 → v1.38.0 functional
- 12 Oct 26 0
- Security disclosure: unverified → pass ▲ functional
- Package version: v1.37.0 → v1.38.0 functional
- Package version: v1.31.0 → v1.37.0 functional
- 11 Oct 26 0
- Security disclosure: pass → unverified ▼ functional
- Package version: v1.32.0 → v1.37.0 functional
- 7 Oct 26 −35
- Stability: 0.13 → unverified ▼ security
- Tool safety: pass → unverified ▼ security
- Capabilities: pass → unverified ▼ functional
- Tool coverage: 100 → unverified ▼ functional
- First check of Schema quality: unverified functional
- Package version: v1.31.0 → v1.32.0 functional
- 4 Oct 26 +1
- Tool safety: pass → unverified ▼ security
- Stability: 0.10 → unverified ▼ security
- Capabilities: pass → unverified ▼ functional
- Tool coverage: 100 → unverified ▼ functional
- First check of Schema quality: unverified functional
- Package version: v1.30.0 → v1.31.0 functional
- 3 Oct 26 0
- Package version: v1.29.1 → v1.30.0 functional
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 17 Oct 2026 · Analysed oci/ghcr.io/luiacuaniello/perspectivegraph@v1.38.1
Provenance Verified
A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.
| Result | Verified |
|---|---|
| Ecosystem | oci |
| Reason | Verified |
| Discovered via | OCI referrers API |
| Source repo | luiacuaniello/perspectivegraph |
| Certificate issuer | https://token.actions.githubusercontent.com |
| Certificate SAN | https://github.com/luiacuaniello/perspectivegraph/.github/workflows/publish-images.yml@refs/heads/main |
| Rekor log index | 3250230159 |
| Predicate type | SLSA build provenance https://slsa.dev/provenance/v1 |
| Subject digest | sha256:ec7501946effe227219d8fa997992a738ff51f126f30e0906a8055820300feaa |
Background: How many MCP packages publish verified provenance →
Vulnerabilities 1 finding
| ID | CVE | Severity | Vector | Fix available |
|---|---|---|---|---|
| GO-2026-5932 | none | no |
Background: What a vulnerability scan can and cannot prove →
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 →
explain_attack_path ~143
Give the full kill chain for one route: every hop, the relationship type, that hop's probability, where the probability came from (kev/epss/runtime are observed evidence; cvss/severity/heuristic are estimates), and the MITRE ATT&CK technique. Use this before explaining or acting on a route - the hop provenance is what tells you which parts of the story are evidence and which are assumption.
| Name | Type | Req | Description |
|---|---|---|---|
| path_id | string | yes | The `id` of a route from list_attack_paths. An id lasts as long as its route: one that has since been closed is reported as no longer open, and list_attack_paths gives the current ones. |
| Name | Type | Req | Description |
|---|---|---|---|
| confidence | number|null | – | How far the score can be trusted, 0-1: the mean confidence of its hops. |
| confidenceLabel | string|null | – | The same as a band: high, medium or low. |
| correlatedHops | boolean|null | – | True when two or more hops rest on the same kind of evidence. |
| id | string|null | yes | The route's id, as asked for. |
| mixtureScore | number|null | – | The score averaged over attacker profiles, weighted by how likely each is. |
| nodes | array|null | – | The assets on the route, entry point first, target last. |
| posteriorMean | number|null | – | The score with the uncertainty of each hop and the mix of attacker capabilities taken into account, 0-1. |
| priority | number|null | – | Triage priority, 0-100: the score blended with corroboration, target sensitivity and how many routes share the entry point. This is the order of the list. |
| priorityFactors | array|null | – | The reasons behind the priority, human-readable. |
| priorityLabel | string|null | – | Priority band: P1, P2 or P3. P1 is what to fix first. |
| priorityReason | string|null | – | One sentence saying why the route is in its band, when a fact put it there; null when the blended number did. |
| profileScores | array|null | – | The score against each attacker profile. |
| remediations | array|null | – | Ways to close the route. |
| runtimeConfirmed | boolean|null | – | True when a runtime alert sits on the route. |
| score | number|null | – | End-to-end probability that an attacker completes the route, 0-1. A modelled estimate, not a measured rate: see get_score_trust. |
| scoreCiHigh | number|null | – | High end of the same interval. |
| scoreCiLow | number|null | – | Low end of the 90% credible interval around posteriorMean. A wide interval means the score rests on soft inputs. |
| scoreUpperBound | number|null | – | The score if the hops fail or succeed together rather than independently: the weakest hop's probability. |
| steps | array|null | – | The hops, in order. Each is one relationship an attacker crosses. |
| suppressed | boolean|null | – | True when an analyst has triaged the route off the board (accepted risk, false positive). It still exists, but do not present it as open work. |
No examples provided.
get_posture ~82
Summarize the environment: how many attack routes are open, how many are runtime-confirmed, how many assets and relationships are mapped, and which sensitive assets an attacker can currently reach. Start here to orient before enumerating anything: it also gives the names the other tools take - the sensitive assets routes_to_target accepts and the applications `app` arguments accept.
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| applications | array|null | – | The application names this environment knows: the values `app` arguments accept. |
| posture | object|null | – | Counts for the whole environment. |
| riskSimulation | object|null | – | The environment's overall risk, simulated over every route at once. |
No examples provided.
get_score_trust ~215
Report how well the engine's probabilities have matched reality, measured against recorded red-team or BAS outcomes: the verdict (well-calibrated / calibrated-on-average / overconfident / underconfident / insufficient-data; calibrated-on-average means only the average matches, so no individual score may be quoted as a probability), the predicted-versus-observed rates, and what to do about the gap. Call this before quoting any score as a probability. If it reports insufficient-data, the numbers are expert estimates and must be presented as the model's own estimate, not as odds. It also reports discrimination - whether the score, and separately the triage Priority order, put confirmed paths above refuted ones (AUC with a 95% interval). Do not present the ranking as evidence of which path is most dangerous unless priorityDiscrimination reads 'discriminates'; 'insufficient-data' or 'indistinguishable-from-chance' means the order has not been shown to beat a coin, and must be said so.
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| calibration | object|null | – | The scores compared with the recorded red-team and BAS outcomes. |
| validation | object|null | – | What happened to the routes that were tested. |
No examples provided.
list_attack_paths ~272
List the ranked routes from internet exposure to a sensitive asset, highest triage priority first. `score` is the modelled end-to-end exploit probability and `priority` (0-100, banded P1/P2/P3) is the triage order that also weighs corroboration and target sensitivity. IMPORTANT: these probabilities are expert estimates, not measurements calibrated against real outcomes - call get_score_trust before presenting any of them as a probability, and prefer the ranking over the absolute values. It returns one page: when `nextOffset` is not null more routes exist, and passing it as `offset` returns the next ones. Routes an analyst has suppressed are listed too, marked `suppressed`.
| Name | Type | Req | Description |
|---|---|---|---|
| app | string | – | Restrict to one application, by a name from get_posture's `applications`: a repository slug or the value of a cloud resource's `app` tag, e.g. 'payments-api'. The match is exact, and a name the envir… |
| limit | integer | – | How many routes to return, priority-first. |
| offset | integer | – | How many routes to skip from the top of the ranking: the `nextOffset` of the previous page. Leave it out for the first page. |
| Name | Type | Req | Description |
|---|---|---|---|
| attackPaths | array|null | yes | The routes, highest priority first. |
| nextOffset | integer|null | yes | Pass as `offset` for the next page. Null when this page is the last. |
| offset | integer | yes | How many routes were skipped before this page. |
No examples provided.
list_fixes ~139
Return the remediation plan: the fewest changes that remove the most risk, choke points first, each with the share of critical-path risk it eliminates and how many routes it cuts. This is usually the right answer to 'what should we do' - a hundred routes typically collapse into a handful of changes.
| Name | Type | Req | Description |
|---|---|---|---|
| app | string | – | Restrict to one application, by a name from get_posture's `applications`: a repository slug or the value of a cloud resource's `app` tag, e.g. 'payments-api'. The match is exact, and a name the envir… |
| Name | Type | Req | Description |
|---|---|---|---|
| remediationPlan | array|null | – | The changes, the one that removes the most risk first. |
No examples provided.
routes_to_target ~214
Enumerate the k best distinct routes that reach a named sensitive asset. Answers 'how many ways in are there, and do they share a choke point' - which single-path views hide. Cutting a hop that every route traverses removes them all; cutting one that appears in a single route removes one. Each route comes with its hops, ready to hand to simulate_fix. It returns the best `k` and has no further page.
| Name | Type | Req | Description |
|---|---|---|---|
| from | string | – | Optional entry point to start from, by name or node id. Omit to consider every internet-exposed entry point. |
| k | integer | – | How many distinct routes to return, best first. Fewer routes come back when fewer exist. |
| target | string | yes | The sensitive asset to reach, by name or node id: a `name` under get_posture's crownJewels (e.g. 'account-admin (effective)'), or an `id` from search_assets. A target nothing reaches returns an empty… |
| Name | Type | Req | Description |
|---|---|---|---|
| kShortestPaths | array|null | – | The distinct routes to the target, most likely first. Empty when nothing reaches it. |
No examples provided.
search_assets ~167
Full-text search across indexed assets and findings by name, CVE id, or keyword. Use it to resolve a name a human mentioned into the node ids the other tools take. It needs OpenSearch on the deployment: where that is off it answers with an error saying so, never with an empty list, and get_posture and list_attack_paths are then where names come from. It returns the best `size` matches and has no further page: narrow the query instead.
| Name | Type | Req | Description |
|---|---|---|---|
| query | string | yes | Text matched against asset and finding names, labels, ids, severities and CWEs, e.g. 'log4j', 'PII', 'CVE-2021-44228'. |
| size | integer | – | Maximum number of matches to return, best match first. |
| Name | Type | Req | Description |
|---|---|---|---|
| search | array | yes | The matches, best first. Empty when nothing matches. |
No examples provided.
simulate_fix ~155
Ask what actually happens if specific relationships are cut: re-runs the whole simulation with those edges removed and reports how many routes disappear and how the compromise probability moves. This is the tool to reach for before recommending a change - it is a deterministic counterfactual over the real graph, not an estimate, so it settles 'would this help' instead of arguing about it. It changes nothing: the graph, the environment and every recorded decision stay as they are, so it needs no confirmation and can be repeated freely.
| Name | Type | Req | Description |
|---|---|---|---|
| cuts | array | yes | Relationships to remove. Take each from a step of explain_attack_path (its from/to), or pass the `cut` of one of that route's remediations as it is. |
| Name | Type | Req | Description |
|---|---|---|---|
| whatIf | object|null | – | The same environment with the cuts applied, compared with it as it is. |
No examples provided.
How do I install the PerspectiveGraph MCP server?
PerspectiveGraph runs locally as a container image, launched with docker run --rm -i -e API_TOKEN ghcr.io/luiacuaniello/perspectivegraph:v1.38.1. Ready-made configuration for Claude, Cursor, VS Code, Codex and 3 more is on this page, copied from each client's own documentation.
oci · ghcr.io/luiacuaniello/perspectivegraph
claude mcp add luiacuaniello-perspectivegraph -- docker run --rm -i -e API_TOKEN ghcr.io/luiacuaniello/perspectivegraph:v1.38.1
This image reads API_TOKEN. Set it in your client's env block for this server; docker run -e passes it through to the container.
What is the PerspectiveGraph MCP server?
PerspectiveGraph is an MCP server listed in the public MCP registry as io.github.luiacuaniello/perspectivegraph. Read-only attack-path tools: reachable routes to sensitive assets, and what a fix would cut. This page covers its container image (ghcr.io/luiacuaniello/perspectivegraph).
Is the PerspectiveGraph MCP server safe to use?
PerspectiveGraph scores 62 out of 100 on VerifyMCP. We recorded 1 known advisory against it as of 17 October 2026. Its build provenance is signed and verified. 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 PerspectiveGraph MCP server expose?
PerspectiveGraph exposes 8 tools: get_posture, list_attack_paths, explain_attack_path, routes_to_target, list_fixes, and 3 more. Their descriptions and schemas cost roughly 1,387 tokens of context every time the server is loaded.
Is the PerspectiveGraph MCP server still maintained?
PerspectiveGraph is still listed as active in the MCP registry. We last reached this channel on 17 October 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 PerspectiveGraph MCP server under?
PerspectiveGraph declares the Apache-2.0 licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.