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

@mcp-com-ai/plugin-capability-graph

v1.3.0

Published

Compile OpenAPI documents into deterministic HAPI capability graphs.

Readme

@mcp-com-ai/plugin-capability-graph

Public OSS compiler and CLI plugin for HAPI capability graphs.

The plugin exposes the OpenAPI compiler as a library, deterministic MCP tool discovery, and offline graph commands. Runtime graph mode is opt-in and leaves existing eager and deferred-search behavior unchanged when disabled.

The package has no Enterprise classifier or hosted AI dependencies.

Compiler API

import {
  compileCapabilityGraph,
  serializeCapabilityGraph,
} from "@mcp-com-ai/plugin-capability-graph";

const graph = await compileCapabilityGraph(openApiDocument, {
  source: {
    identifier: "crm-api",
    canonicalUri: "https://api.example.com/openapi.json",
  },
});

const canonicalJson = serializeCapabilityGraph(graph);

compileCapabilityGraph accepts one OpenAPI 3.x object and returns a deeply frozen CapabilityGraphV1. Invalid supported x-hapi-* extensions reject with CapabilityGraphCompilationError, whose diagnostics identify the operation, JSON pointer, and validation error.

Supported optional operation extensions:

  • x-hapi-capability
  • x-hapi-intent
  • x-hapi-effects
  • x-hapi-prerequisites
  • x-hapi-planning

A response object may also declare x-hapi-outcome, described under Response outcomes. Webhook and callback operations may declare x-hapi-event (see Event triggers), and the document root may declare x-hapi-client-facts (see Client facts).

Example:

paths:
  /orders/{orderId}/cancel:
    post:
      operationId: cancelOrder
      x-hapi-capability: [orders/management, customer-support/orders]
      x-hapi-intent:
        use-when: [The customer asks to cancel an open order]
        avoid-when: [The order has already shipped]
      x-hapi-effects:
        mode: write
        side-effecting: true
        destructive: true
        requires-confirmation: true
      x-hapi-prerequisites: [The order exists and is still cancellable]

Missing semantics are inferred deterministically and retain provenance. Schema summaries preserve $ref values instead of expanding them, so recursive models remain bounded. Equivalent path, tag, object-property, and oneOf ordering produces the same operation identities and graph fingerprint.

Runtime discovery

Enable deterministic graph-backed tool discovery for a native server:

hapi serve --specs ./openapi.yaml --mcp --capability-graph

The flag implies --deferred-tool-search. Cloudflare deployments expose the same behavior through hapi cloudflare deploy --capability-graph, which sets HAPI_CAPABILITY_GRAPH=true. The graph is compiled once during runtime initialization, and malformed explicit x-hapi-* metadata fails startup.

Offline commands

hapi graph compile ./openapi.yaml > graph.json
hapi graph compile --specs https://api.example.com/openapi.yaml --out graph.json
hapi graph inspect graph.json
hapi graph inspect ./openapi.yaml --format graphml > graph.graphml
hapi graph visualize graph.json --out capability-graph.html
hapi graph visualize ./openapi.yaml > capability-graph.html
hapi graph visualize graph.json --out plan.html \
  --initial-fact patient.identity.verified \
  --initial-fact slot.selected \
  --goal-fact appointment.booked
hapi graph search graph.json "close the deal" --limit 5
hapi graph eval graph.json ./evaluation.json

All source-taking graph commands accept either a positional source or --specs <path-or-http(s)-url>. Remote loads use bounded size, timeout, and redirect handling. Supplying both selectors is rejected. --url is not accepted because these commands compile and inspect documents without calling an upstream API. Direct Arazzo documents remain owned by hapi arazzo and hapi serve --specs; the graph compiler input is one OpenAPI document or a canonical graph.

compile emits canonical, round-trippable JSON by default. inspect provides a concise human summary or deterministic GraphML. visualize accepts canonical JSON or compiles one OpenAPI document and emits byte-stable, self-contained HTML. search uses the runtime deterministic classifier. eval exits non-zero when any fixture expectation fails.

Canonical JSON is the lossless visualization input; GraphML is export-only and cannot be read back by visualize. The HTML viewer is single-graph, local, and read-only. It has no remote assets, network requests, cookies, browser storage, service worker, API invocation, or execution control. The topology and local text/filter results are inspection aids and do not imply authorization or execution eligibility. Planning transitions, when present, appear in a separate view. The Business State Flow deduplicates canonical predicate/value facts and connects every prerequisite to its operation or workflow before showing produced and removed facts. Facts are conditions; the planner's state is the complete set of facts currently true, so this view is intentionally not presented as a formal UML state machine. Compiler-generated operation.*.completed facts are hidden by default and remain available with the technical-fact toggle.

Supplying at least one --goal-fact embeds an exact Plan Trace produced by the same deterministic planner and inputs as graph simulate. The trace shows the initial state and every before/after fact set for planned, complete, clarification-required, and unplannable outcomes. An unplannable result still produces a successful HTML artifact; the outcome is displayed in the file. Planning-only options without a goal are rejected. No planner or principal data is embedded in the browser.

The same trace also drives a Flow cards view. It shows a start card with the goal and known facts, one card per planner step in planner order, and an outcome card. A step with an unsatisfied gate says "Wait for confirmation" (or the gate kind) in text. Steps that do not depend on each other through declared facts share a row. That is not a promise of parallel execution, and every card keeps its planner step number. Open the artifact on this view with --initial-view flow-cards:

hapi graph visualize graph.json --out trip-flow.html \
  --initial-fact traveller.identity.verified \
  --goal-fact trip.booked \
  --initial-view flow-cards

Each operation card lists its required inputs: required parameters and required body property names, never credentials. It says "Needs input" when no earlier step in the plan has a planning-eligible OpenAPI Link to that operation. Otherwise it names the link and step that may supply them. Compiled graphs do not keep Link parameter mappings, so the card never claims which input a link fills. These markers are advisory and do not change the plan, its gates, or its outcome.

Fact audit

hapi graph audit checks that every planning fact can be established and every outcome can be reached:

hapi graph audit graph.json --client-verified-fact traveller.identity.verified
hapi graph audit ./openapi.yaml --no-reachability --output json

It reports:

  • Orphan requirements. A business fact some transition requires, that no transition produces, and that is not declared with --client-verified-fact.
  • Client-verified facts. Facts established outside the API, such as verified identity, declared in the contract with x-hapi-client-facts or passed with --client-verified-fact. Each shows its origin.
  • Outcomes. Business facts produced and never required. These are the candidate goals.
  • Response and event facts. Facts produced by a declared response outcome or signalled by a declared webhook or callback. They are not orphans, and they are never planned.
  • Discovery-only operations. Operations that no planning transition targets.
  • Reachability. Each outcome, or each --goal-fact, is planned from the client-verified facts with every operation eligible and every non-authorization gate treated as satisfied. This is a topology check. It does not grant authorization or confirmation.

Compiler-generated operation.*.completed facts are excluded. The command exits 0 when clean, 1 when an orphan or unreachable outcome is found, and 2 for usage, input, or compilation errors, so it can gate CI. graph visualize accepts the same --client-verified-fact option and shows the static findings as gap cards in the Flow cards view, without running the reachability sweep.

Generated HTML contains allowlisted graph summaries, authorization scheme names/scopes, diagnostics, provenance, and planning facts. Handle it with the same sensitivity as its source graph. The renderer limits input to 16 MiB, 5,000 nodes, 20,000 edges, 10,000 planning transitions, 10,000 unique planning facts, 50,000 state relations, 1,000 trace steps, 2,000 diagnostics, and 32 MiB of generated HTML. Unsupported versions, malformed references, or exceeded limits fail before stdout or the atomically written --out file is committed.

The pure browser-safe API is available separately:

import {
  projectCapabilityGraphVisualization,
  renderCapabilityGraphVisualizationHtml,
} from "@mcp-com-ai/plugin-capability-graph/visualization";

const document = projectCapabilityGraphVisualization(graph);
const html = await renderCapabilityGraphVisualizationHtml(document);

OSS and Enterprise boundary

This package owns graph compilation, inspection, exports, and deterministic classification. It never loads a licensed classifier or AI SDK.

Probabilistic transition authoring is intentionally separate. A future licensed capability-graph-transition-assistant may use Jev to score candidate relationships, but suggestions cannot affect this viewer, the graph fingerprint, or planning until a user accepts them into x-hapi-planning or Arazzo and recompiles the contract.

The TypeSafe/Jev classifier is implemented in the separate private @mcp-com-ai/enterprise-plugin-capability-classifier package. It registers an alternate classifier through Core's versioned provider seam after checking the core.enterprise or capability.graph.ai entitlement. Native managed extensions and a private static Worker profile provide the licensed code; the public npm package, standalone binary, Docker image, and Worker remain deterministic-only.

Operators with the private extension explicitly opt in with both graph mode and --capability-classifier typesafe. Omission remains deterministic.

AOT planning contracts

The package compiles and plans over the closed x-hapi-planning v1 shape:

x-hapi-planning:
  requires:
    - predicate: order.open
  produces:
    - predicate: order.approved
  removes:
    - predicate: order.open
  cost: 1

produces is required and non-empty. Predicates are lowercase canonical names, fact values must be JSON-safe, and cost must be finite and nonnegative. This metadata, fully mapped OpenAPI Links, and supported validated Arazzo workflows are the only transition sources. Missing planning metadata is never invented.

Simulate offline:

hapi graph simulate ./openapi.yaml \
  --initial-fact order.open \
  --goal-fact order.approved \
  --satisfied-gate mutation-confirmation \
  --output json

The planner uses finite nonnegative costs and bounded Dijkstra search. Defaults are depth 12, 2,000 states, 1,000 frontier entries, and 100 expansions per state; every bound has a CLI override. Outcomes are planned, clarification-required, complete, or unplannable. Authorization removes ineligible operations before search. Policy, risk, and confirmation gates are reported explicitly and never hidden in path cost.

Response outcomes

A non-success response can declare the facts it produces or removes:

responses:
  "409":
    description: Hotel is unavailable
    x-hapi-outcome:
      produces: [{ predicate: hotel.unavailable }]
      removes: [{ predicate: hotel.selected }]

produces and removes use the x-hapi-planning fact rules, and at least one must be non-empty. The status key may be a code, an NXX range, or default, but never a 2xx status, because x-hapi-planning already models success. The operation must have x-hapi-planning; otherwise the outcome is ignored with an outcome-without-planning warning.

Outcomes are alternatives the client cannot choose, so the planner never plans through one. They appear on each plan step as outcomes, including in the bounded capability_plan result. A failed guarded execution step reports the matching outcome as declaredOutcome, matching the exact status, then the range, then default. The facts are reported and never applied to execution state: the client verifies the response and re-plans. Flow cards show outcomes as "Otherwise" lines, and hapi graph audit lists their facts as response facts rather than orphans. Documents without outcomes keep their fingerprint.

Event triggers

The compiler records OpenAPI 3.1 webhooks and operation callbacks as descriptive triggers on the graph. A trigger's id is webhook:<name>:<method> or callback:<operationId>:<name>:<method>. A webhook or callback operation can declare the facts its event signals:

webhooks:
  orderPaid:
    post:
      summary: The payment provider confirmed payment
      x-hapi-event:
        produces: [{ predicate: order.paid }]

produces must be a non-empty canonical fact array. x-hapi-event on an ordinary paths operation is ignored with an event-on-path-operation warning, and an unresolvable webhook or callback reference is skipped with an unresolved-trigger warning.

Triggers are descriptive only. HAPI never subscribes to, receives, or plans through an event. A client that receives and verifies the event passes the fact as verified initial state. Flow cards name a trigger on the start card when it signals one of the plan's initial facts, and hapi graph audit lists event-signalled facts as event facts instead of orphans. Documents without webhooks or callbacks keep their fingerprint. Arazzo AsyncAPI steps are not supported yet.

Client facts

A document can declare the facts a client establishes outside the API:

x-hapi-client-facts:
  - predicate: traveller.identity.verified
    description: The client verified the traveller's identity.

Entries use the planning fact rules plus an optional non-empty description. A declared fact that no transition requires compiles with an unused-client-fact warning. The graph keeps them as clientFacts.

hapi graph audit and graph visualize treat declared facts like --client-verified-fact values and report each fact's origin as contract, option, or both. capability_context marks matching requirement cards with clientEstablished: true so an MCP client knows it must verify them. The declaration never makes a fact true: capability_plan still accepts only facts the client verified.

Expose MCP planning only with the second explicit opt-in:

hapi serve --specs ./openapi.yaml --mcp \
  --capability-graph --capability-planning

For Workers, deploy with both --capability-graph --capability-planning, or set HAPI_CAPABILITY_GRAPH=true and HAPI_CAPABILITY_PLANNING=true. The capability_plan tool accepts bounded initial/goal facts, satisfied gate codes, and bounds. It returns an allowlisted result with transition identities, costs, gates, provenance, digests, and diagnostics.

The same explicit planning opt-in also exposes capability_context. Call it with a natural-language request before planning to receive bounded, authorization-filtered candidate tools, declared goal facts, fact relationships, gates, and transition provenance. Its facts are guidance, not asserted state: select a goal, supply only verified facts to capability_plan, collect any clarification, then re-plan after a safe tool result or human choice. Context neither calls an API nor stores state, asks a user, executes a plan, or grants authority. Compiler-owned operation.*.completed facts are hidden unless explicitly requested.

Development tracing

For a local demonstration, add --dev --capability-trace to graph-enabled serve. HAPI emits bounded [HCG_TRACE] records for discovery, context, planning, graph-backed operation calls, and guarded execution. The records show declared transition relationships, observed direct calls, and validated guarded progression distinctly; they never log query text, fact values, arguments, responses, credentials, or patient data. Trace mode is opt-in and rejected outside explicit development mode.

Planning never invokes an API, the OpenAPI operation invoker, or the Arazzo executor. It does not return credentials, HTTP requests/responses, raw graph records, or runtime context.

Guarded execution

Guarded execution is public OSS and requires all three explicit options:

hapi serve --specs ./openapi.yaml --mcp \
  --capability-graph --capability-planning \
  --runtime-authority guarded

Workers use HAPI_CAPABILITY_GRAPH=true, HAPI_CAPABILITY_PLANNING=true, and HAPI_RUNTIME_AUTHORITY=guarded. The default decision authority continues to offer discovery and optional planning but never registers capability_execute.

The executor accepts only an exact canonical plan. It recomputes the plan and binds confirmations to the graph fingerprint, plan digest, server principal, and argument-digested mutation set. Confirmation receipts must be issued by a trusted provider registered through Core's versioned verifier seam; this plugin does not expose a confirmation-issuing tool.

Register a trusted verifier during startup before accepting mutation plans:

import { registerCapabilityExecutionConfirmationVerifier } from "@mcp-com-ai/core/capability-execution";

registerCapabilityExecutionConfirmationVerifier({
  version: "1",
  id: "deployment-confirmation-service",
  verify: (receipt, binding, signal) =>
    confirmationService.verify(receipt, binding, signal),
});

Before every attempt the runtime rechecks confirmation, authorization, policy, current facts, arguments/body variant, and retained schemas. OpenAPI operations run through the existing invoker; supported Arazzo workflows run as one atomic outer step under both workflow and guarded limits. Automatic retries apply only to read-only or explicitly idempotent operations and normalized transient failures. Results are completed, partial, rejected, failed, or cancelled; ambiguous upstream timeouts/network failures are recorded as indeterminate steps and stop the sequence.

Deployment limits may reduce, but never exceed, the compiled ceilings: 50 plan steps, five minutes total, 60 seconds per step, 100 total attempts, three retries per eligible step, 10 MiB per response, 100 result records, and 500 event records. Public defaults are deliberately lower (12 steps, 60 seconds total, 15 seconds per step, 16 attempts, one retry, 1 MiB responses, 50 result records, and 100 events).

MCP summaries and structured events are allowlisted: raw arguments, bodies, headers/cookies, URL credentials/query values, principal claims, confirmation proofs, fact values, and stacks are excluded. The runtime does not compensate, resume, persist state, or guarantee exactly-once execution. Receipts are short-lived and context-bound, but durable single-use replay enforcement belongs to the confirmation provider or a future persistent receipt store.