Skip to content

MCP Integration ​

Purple8 Hyper Graph v0.72.0 ships a built-in MCP server (HTTP + SSE + Streamable HTTP) exposing 176 MCP tools across 19 namespaces, with Focused MCP Tool Profiles (?profile=starter|builder|ops|full) so AI agents only load the exact tools they need. Any MCP-compatible AI agent — Claude Desktop, Cursor, GitHub Copilot, ChatGPT Desktop, or a custom agent loop — connects directly to the running Purple8 server and gets typed, role-filtered tools.

Focused MCP Tool Profiles (?profile=) ​

Pass ?profile= on /mcp or /mcp/sse (or send the X-MCP-Profile header) to scope tools/list:

ProfileEndpointToolsBest For
starter/mcp?profile=starter28Non-technical operators, Claude Desktop, and rapid prototyping (schema.*, core graph.* LPG + RDF CRUD/search/traverse, data.commit / data.ingest_*, journey.*, rag.*).
builder/mcp?profile=builder117Cursor, Claude Code, and Copilot app builders (starter + full graph.*, schema.*, data.*, memory.*, models.*, egress.*, scheduler.*, feedback.*, registry.*).
ops/mcp?profile=ops37Operations, compliance & governance (journey.*, sentinel.*, guardrails.*, feedback.*, admin.*).
full/mcp (or ?profile=full)176All 19 namespaces including aec.*, soc.*, supergraph.*, quantum.*, and evolution.*.

Architecture ​

MCP Client (Claude Desktop / Cursor / ChatGPT Desktop / custom agent)
  │  MCP over Streamable HTTP (POST /mcp)  ← MCP 1.x clients
  │  MCP over HTTP + SSE (GET /mcp/sse)   ← legacy clients
  ▼
http://localhost:8000/mcp      ← built into the Purple8 server, no separate process
  │  internal call
  ▼
GraphEngine + JourneyEngine + RAG pipeline + Quantum engine (same process)

The MCP server runs as part of purple8_graph.secure_server — no separate process, no separate install. Start Purple8, both MCP endpoints are live.

Hosted on AWS / Fly / Kubernetes? The endpoints are identical — replace http://localhost:8000 with your instance's https:// URL. Jump to Connecting to a hosted instance.


Quick start ​

Step 1 — Start the server ​

bash
export P8G_ADMIN_EMAIL=admin@example.com
export P8G_ADMIN_PASSWORD=changeme
export SECRET_KEY=your-secret-key
export LLM_PROVIDER=openai
export OPENAI_API_KEY=sk-...

python -m purple8_graph.secure_server
# Streamable HTTP: http://localhost:8000/mcp
# SSE (legacy):    http://localhost:8000/mcp/sse

Step 2 — Create an API key ​

bash
TOKEN=$(curl -s -X POST http://localhost:8000/auth/token \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@example.com","password":"changeme"}' | jq -r .access_token)

curl -X POST http://localhost:8000/auth/api-keys \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"claude-agent","role":"editor"}'
# Returns: { "key": "p8g_...", ... }  — store this, shown once
bash
# Streamable HTTP — MCP 1.x (Claude Desktop 2026+, ChatGPT Desktop)
claude mcp add purple8 --transport http http://localhost:8000/mcp \
  --header "X-API-Key: p8g_your-key"

# SSE — legacy clients
claude mcp add purple8 --transport sse http://localhost:8000/mcp/sse \
  --header "X-API-Key: p8g_your-key"

Step 4 (alternative) — Connect Claude Desktop ​

claude_desktop_config.json only launches local (stdio) servers — it ignores url. For a local instance use the stdio bridge:

json
{
  "mcpServers": {
    "purple8-graph": {
      "command": "purple8-hyper-graph",
      "args": ["mcp-server", "--url", "http://localhost:8000", "--api-key", "p8g_your-api-key-here"]
    }
  }
}

For a hosted instance, see Connecting to a hosted instance below.

Restart Claude Desktop — Purple8 tools permitted by your role and API key appear in the tool chooser.

Step 4 (alternative) — Connect Cursor ​

In Cursor settings → MCP → Add server:

json
{
  "purple8-graph": {
    "url": "http://localhost:8000/mcp",
    "headers": {
      "X-API-Key": "p8g_your-api-key-here"
    }
  }
}

Connecting to a hosted instance ​

The MCP endpoints are part of the Purple8 HTTP server, so they work the same way on AWS, Fly, or Kubernetes as they do on localhost. You don't need to install anything locally. Change the URL to your instance's public HTTPS address and send an API key issued by that instance.

WhatValue
Streamable HTTP (preferred, MCP 1.x)https://<your-host>/mcp
HTTP + SSE (legacy clients)https://<your-host>/mcp/sse
Auth headerX-API-Key: p8g_... (or Authorization: Bearer p8g_... on /mcp)
Key sourcehttps://<your-host>/lcnc/api-keys, or POST https://<your-host>/auth/api-keys

<your-host> is your deployment's DNS name (e.g. graph.acme.com, acme-p8g.fly.dev, or your ALB/CloudFront hostname).

Keys are per-instance

An API key from your local instance won't work against the hosted one, and a hosted key won't work locally. The license key and your login password are not MCP keys either.

1. Verify from your machine ​

bash
HOST=https://graph.acme.com
KEY=p8g_...

curl -s $HOST/health                                   # 200, no auth
curl -s -o /dev/null -w "%{http_code}\n" -X POST $HOST/mcp \
  -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'
# 200 = OK · 401 = bad/missing key · 404 = MCP extra not installed on the server

2. Configure the client ​

Claude Code (CLI)

bash
claude mcp add purple8 --transport http https://graph.acme.com/mcp \
  --header "X-API-Key: p8g_..."

Claude Desktop / claude.ai — use Settings → Connectors → Add custom connector with URL https://graph.acme.com/mcp. Don't add a url entry to claude_desktop_config.json, because that file only supports local commands. If your plan can't add custom headers on connectors, use the bridge described under stdio-only clients below.

VS Code (Copilot agent mode) — .vscode/mcp.json:

json
{
  "servers": {
    "purple8": {
      "type": "http",
      "url": "https://graph.acme.com/mcp",
      "headers": { "X-API-Key": "${input:p8gKey}" }
    }
  },
  "inputs": [
    { "id": "p8gKey", "type": "promptString", "description": "Purple8 API key", "password": true }
  ]
}

Cursor — ~/.cursor/mcp.json:

json
{
  "mcpServers": {
    "purple8": {
      "url": "https://graph.acme.com/mcp",
      "headers": { "X-API-Key": "p8g_..." }
    }
  }
}

Stdio-only clients (older Claude Desktop, Windsurf, Cline, and similar) — run the bundled stdio bridge locally and point it at the hosted REST API:

json
{
  "mcpServers": {
    "purple8": {
      "command": "purple8-hyper-graph",
      "args": ["mcp-server", "--url", "https://graph.acme.com", "--api-key", "p8g_..."]
    }
  }
}

The bridge requires pip install 'purple8-hyper-graph[mcp]' on the client machine. All data stays on the hosted instance.

Custom agents (Python MCP SDK)

python
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async with streamablehttp_client(
    "https://graph.acme.com/mcp", headers={"X-API-Key": "p8g_..."}
) as (read, write, _):
    async with ClientSession(read, write) as s:
        await s.initialize()
        tools = await s.list_tools()

3. Operator checklist (self-hosted on AWS / Fly / Kubernetes) ​

ItemWhy
Install the [mcp] extra in the imageWithout it, /mcp and /mcp/sse are not mounted, and the log shows mcp_*_transport_skipped
Terminate TLS at the load balancer / ingressAPI keys travel in headers. Never expose /mcp over plain HTTP
Set P8G_PUBLIC_URL=https://<your-host>Each MCP session sends its tool calls back to this URL. If it isn't set, the server uses the request's base_url, which can be an internal http:// address behind a proxy
Disable response buffering on the proxy for /mcp*Both transports stream. In nginx use proxy_buffering off;; the server already sends X-Accel-Buffering: no
Raise idle timeouts to ≥ 300 sLong-running tools (rag.tune_collection, quantum.*) hold the stream open. The AWS ALB default of 60 s drops them
Use sticky sessions only if clients use /mcp/sseSSE sends GET /mcp/sse and POST /mcp/messages/, and both must reach the same replica. /mcp (Streamable HTTP) is stateless per request and doesn't need stickiness
Allow the /mcp paths in your WAFSome managed rule sets block text/event-stream or JSON-RPC bodies

RBAC and tenancy behave exactly as they do locally. The API key's role and tenant decide which tools and data the agent can reach.


Tools by namespace (176 tools across 19 namespaces) ​

NamespaceCountWhat agents can do
graph.*52query, vector_search, hybrid_search, traverse, add_node, add_edge, update_node, get_node, pagerank, communities, poll_changes, wait_for_changes, auto_config, delete_node (human_only), import_nquads, assert_statement, retract_statement (human_only), semantic_query, get_edge, delete_edge (human_only), edges_exist, shortest_path, morans_i, local_morans_i, centrality, link_prediction, personalised_pagerank, triangles, bridges, articulation_points, bipartite_check, bipartite_matching, mst, motifs, temporal_pagerank, dynamic_pagerank, dynamic_communities, structural_roles, rolesim, fraud_rings, simrank, laundering_paths, supply_chain_route, attack_paths, recommend, text_search, explain_query, edges_count, add_nodes_bulk, add_edges_bulk, counts, labels
aec.*18buildings_list, buildings_analyses, buildings_demo, buildings_get, buildings_delete (human_only), buildings_run, vga_build, structural_rigidity, structural_critical_members, bim_clashes, design_egress, mep_max_flow, spectral_fiedler, topo_optimise, morl_generate, mpnn_propagate, hypergraph_build, ifc_rewrite
admin.*14smtp_status, smtp_configure (human_only — JWT required), audit_verify, recovery_status, retention_list, retention_set, retention_delete, retention_sweep, hold_list, hold_place, hold_release, kms_status, storage_scrub, lineage_get
schema.*12get, define_node_type, get_node_type, update_node_type, delete_node_type (human_only), list_node_types, define_edge_type, get_edge_type, update_edge_type, delete_edge_type (human_only), list_edge_types, validate
data.*11ingest_text, ingest_file, commit, replace_file, patch_file_properties, list_file_versions, list_files, get_table, link_table_rows, index_table_columns, query_table_rows
journey.*9define, list, start, advance, status, sla_alerts, list_hitl, resolve_hitl, audit
quantum.*8anneal, optimize, simulate, encode_state, measure, vqe_step, compare, profile
evolution.*8create_experiment, list_experiments, propose, suggest, report, production, rag_retrieval, routing_policy
models.*7list, search_known, upsert, remove, get_policy, set_policy, route_explain
rag.*6query, graph_query, hybrid_query, profile_collection, tune_collection, rerank
registry.*6list_tools, register_tool, register_mcp_server, register_a2a_agent, remove_tool, test_tool
sentinel.*5summary, list_findings, get_finding, reject, drift_check
egress.*4add_sink, list_sinks, remove_sink, status
feedback.*4open, record, resolve, summary
scheduler.*4add_trigger, list_triggers, remove_trigger, status
soc.*3stats, containments_active, audit_log
memory.*2history, search
supergraph.*2peers_list, query
guardrails.*1evaluate

Self-Hosted Licensing Tiers: Developer (Self-Hosted Free) includes up to 50K nodes and 1 concurrent MCP agent. Enterprise / Custom (Self-Hosted) supports unlimited nodes, unlimited MCP agents, and full compliance/HA features.


RBAC per tool ​

RBAC is enforced per tool call via the role on the API key:

RoleAccess
viewerRead-only: graph.* reads, rag.*, memory.*, schema.* reads
editorViewer + writes: graph.* mutations, data.*, journey.start/advance, quantum.*, scheduler.*, egress.*, feedback.*
adminEditor + admin: journey.define/resolve_hitl, schema.* mutations, registry.*, admin.smtp_status
super_adminAll tools

human_only tools — admin.smtp_configure and other destructive tools marked human_only=True are blocked for API-key (agent) callers. A human must authenticate via interactive JWT session to call them.


Authentication ​

All tool calls require X-API-Key: p8g_<key> or Authorization: Bearer <jwt> in the HTTP headers. API keys are created via POST /auth/api-keys or the LCNC dashboard at /lcnc/api-keys.


Example agent interactions ​

Query RDF and LPG evidence together ​

graph.semantic_query accepts the same tagged pattern body as POST /semantic/query. It returns typed bindings, ordered evidence and mixed LPG views; output_format: "nquads" instead returns a JSON envelope with the selected asserted RDF document and limit_reached. No LPG facts are silently converted to RDF.

Existing graph read permissions and row/field/PII/classification policies apply before matching. N-Quads additionally requires data:export; API-key label and tool scopes still constrain access. Raw work statistics are withheld (stats: null) rather than exposing hidden index sizes. See the semantic network contract for the request shape, policy behavior, complete-response limits and errors.

Assert a native RDF fact ​

graph.assert_statement takes {"statement": {...}} using native RDF term objects. The tenant comes from authentication; blank nodes require a scope. Authorized retries preserve the same canonical assertion and its existing owner. Read/create permissions, whole-assertion visibility and per-label restrictions apply to the canonical record and its projections before mutation.

graph.retract_statement targets exactly one quad and physically removes it; it requires an admin, read/delete permissions and legal-hold clearance. It is human_only, matching the existing destructive tools: AI agent API-key callers cannot retract, even with an admin role. See governed semantic mutations for request/response shapes, restrictions, retry semantics and error behavior.

Import externally produced RDF ​

graph.import_nquads accepts nquads, a stable blank_node_scope and optional lower max_input_bytes/max_statements bounds. It uses the active REST request schema, full syntax/authorization preflight and the same canonical assertions; DocIntel is not required. Existing data:import plus node/edge read/create permissions and policy/tool scopes apply.

Writes are not atomic across the document. An interrupted import can report an acknowledged prefix while its failing write may also be durable. Retry the entire original document with the same scope and tenant, not a guessed suffix. See bounded N-Quads import for exact caps, response counts, blank-node mapping and recovery behavior.

Build a knowledge graph from documents ​

User: "Extract these public contract documents for review before adding them"

Agent calls:
  data.ingest_file { "url": "https://example.com/contract.pdf", "source_name": "contract.pdf", "auto_commit": false }
  # If pending, repeat the call with the returned job_id to resume.
  # Review the completed preview, including evidence and warnings.
  data.commit { ...reviewed preview... }
  # Inspect embedding/document/structured-content/original-file outcomes.

data.ingest_file accepts public URLs, not local paths. For local files, upload/extract through REST or docintel.process_file, then use data.commit. DocIntel is optional: data.commit also accepts your own extractor's complete REST ingestion payload. See Bring Your Own Ingestion for review, job resumption, original retention, and complete evidence retrieval.

Answer a relational question ​

User: "What are the key risks across all projects owned by Alice?"

Agent calls:
  rag.hybrid_query {
    "question": "risks in projects owned by Alice",
    "max_hops": 2,
    "seed_k": 10
  }

fusion_alpha defaults to 0.0 (pure vector search) — do not pass a nonzero value unless you've confirmed graph edges carry real semantic relationships (not just ANN-neighbor artifacts). See When to enable graph fusion before setting fusion_alpha > 0. Prefer calling rag.profile_collection or rag.tune_collection first — they derive a safe, corpus-specific value instead of guessing.

Solve a scheduling optimisation problem ​

User: "Schedule 8 jobs across 3 machines to minimise total makespan"

Agent calls:
  quantum.optimize {
    "n": 24,
    "Q": [[ ... ]],   // n×n QUBO coupling matrix encoding job/machine assignment costs
    "domain": "scheduling"
  }

Define and run a workflow ​

User: "Set up a loan approval workflow and start one for customer C-001"

Agent calls:
  journey.define { "name": "loan_approval", "stages": [...] }
  journey.start { "journey_name": "loan_approval", "entity_id": "C-001" }
  journey.status { "instance_id": "..." }

See Also ​


Complete 176-Tool tools/list Parameter & Schema Reference ​

Machine-readable JSON Schema (tools/list): https://docs.graph.purple8.ai/mcp-tools.json · https://www.purple8.ai/mcp-tools.json

schema.* (12 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
schema.get(none)(none)viewerReturn the full graph schema snapshot for the current tenant — all node-type and edge-type definitions plus constraints and version. Call this first to disco...
schema.validate(none)(none)viewerValidate the tenant's live graph data against the defined schema. Reports missing required properties, type/enum violations, edge source/target-type violatio...
schema.list_node_types(none)(none)viewerList every defined node type for the current tenant.
schema.get_node_typetype_name(none)viewerFetch a single node-type definition by its type_name.
schema.define_node_typetype_namedescription, app_id, data_classification, properties, required_labels, immutable_properties, allowed_edge_typesadminDefine a new node type — the primitive that lets an agent build the data model itself. The type_name becomes the canonical label for nodes of this type. Set...
schema.update_node_typetype_namedescription, app_id, data_classification, properties, required_labels, immutable_properties, allowed_edge_typesadminUpdate an existing node-type definition (full replace). The type_name must match an existing type. Does not migrate existing nodes — only the schema entry ch...
schema.delete_node_typetype_name(none)adminRemove a node-type definition. Does NOT delete existing nodes — it only removes the schema entry, so nodes of this type become orphan-labelled until redefine...
schema.list_edge_types(none)(none)viewerList every defined edge type for the current tenant.
schema.get_edge_typetype_name(none)viewerFetch a single edge-type definition by its type_name.
schema.define_edge_typetype_namedescription, app_id, source_node_types, target_node_types, properties, cardinality, data_classificationadminDefine a new edge (relationship) type. Constrain which node types may be the source/target, declare edge properties, and set cardinality (one_to_one | one_to...
schema.update_edge_typetype_namedescription, app_id, source_node_types, target_node_types, properties, cardinality, data_classificationadminUpdate an existing edge-type definition (full replace). The type_name must match an existing type. Fails 404 if not defined.
schema.delete_edge_typetype_name(none)adminRemove an edge-type definition. Does NOT delete existing edges — only the schema entry is removed. ⚠ human_only — agents are blocked; a human operator must p...

graph.* (52 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
graph.querycypherparametersviewerExecute a Cypher query against the Purple8 knowledge graph and return matching records. Use for nodes, edges, paths, or aggregated data.
graph.vector_searchquery_textlabel, kviewerFind the k nearest nodes to a natural-language query using the HNSW vector index.
graph.hybrid_searchquery_textlabel, kviewerCombine vector similarity with graph traversal for highest-recall retrieval. Best when graph structure matters.
graph.traversenode_iddepth, edge_type, directionviewerWalk the graph from a starting node following edges up to a given depth.
graph.add_nodenode_idtype, label, node_type, labels, propertieseditorInsert a new node into the graph (accepts type, label, or node_type). Requires editor role.
graph.add_edgesource_id, target_id, edge_typeedge_id, properties, weighteditorCreate a directed edge (relationship) between two existing nodes. This is the primary agentic handoff mechanism — agents write their output as edges (e.g. DE...
graph.update_nodenode_idproperties, labelseditorUpdate properties or labels on an existing node. Properties are merged with existing values (patch semantics — only the keys you supply are changed). Labels...
graph.get_nodenode_id(none)viewerRetrieve a node and all its stored properties by ID.
graph.pagerank(none)label, top_kviewerRun PageRank on the graph and return the top-ranked (most influential) nodes.
graph.communities(none)labelviewerDetect communities (Louvain) in the graph. Useful for discovering entity clusters.
graph.poll_changes(none)since_sequence, limit, event_typeviewerPoll the CDC (Change Data Capture) event stream for recent graph mutations. Returns up to limit events that occurred after since_sequence (exclusive). Us...
graph.wait_for_changes(none)since_sequence, timeout, limit, event_typeviewerBlock until the next graph mutation after since_sequence, or until timeout seconds elapse — a push-latency alternative to graph.poll_changes. Where poll_...
graph.auto_config(none)M, ef_construction, segment_size, batch_size, max_hot_segments, alphaviewerInspect the hardware-derived QCDR configuration recommendation for this Purple8 engine, and optionally simulate the impact of parameter overrides before comm...
graph.delete_nodenode_idfile, erase, reasoneditor (human_only)Delete a node and all its incident edges from the graph. Returns {"deleted": true} when the node existed and was removed, or {"deleted": false} when...
graph.import_nquadsnquads, blank_node_scopemax_input_bytes, max_statementseditorImport bounded RDF 1.1 N-Quads with an explicit stable blank_node_scope. Full parse and authorization preflight precede writes. Quads commit individually, no...
graph.assert_statementstatement(none)editorIdempotently assert one native RDF quad with exact lexical terms, explicit blank-node scope and optional graph name. Uses existing node/edge create and read...
graph.retract_statementstatement(none)adminPhysically remove exactly one native RDF quad, preserving other graph memberships. Admin-only; existing node/edge delete and read permissions, visibility pol...
graph.semantic_querypatternsbindings, node_bindings, limit, limits, max_output_bytes, output_formatviewerRead-only indexed RDF/LPG pattern query with policy-filtered evidence. Use tagged rdf, lpg and lpg_edge patterns. Returns unified bindings and evidence or, w...
graph.get_edgeedge_id(none)viewerFetch a single edge (relationship) by its edge_id, returning its type, source and target node IDs, and properties. The edge counterpart of graph.get_node.
graph.delete_edgeedge_id(none)editorDelete a single edge (relationship) by its edge_id. The edge counterpart of graph.delete_node — completes graph CRUD so an agent can remove a relationship wi...
graph.edges_existpairs(none)viewerBatch relationship-existence check (up to 500 pairs per call). Given a list of directed pairs (each source_id + target_id, optional edge_type), returns which...
graph.shortest_pathnode_id, target_idweight_property, edge_typeviewerFind the shortest weighted path from one node to another (Dijkstra). Returns the ordered node sequence and total cost, or a 404 if the target is unreachable....
graph.morans_inode_label, value_property, weight_edge_typeweight_property, row_standardise, permutationsviewerCompute Moran's I global spatial autocorrelation statistic over a set of nodes. Measures whether nodes with similar value_property cluster together (I > 0)...
graph.local_morans_inode_label, value_property, weight_edge_typeweight_property, row_standardise, permutations, significance_levelviewerCompute LISA (Local Indicators of Spatial Association) for every node in the graph — the local version of Moran's I. Classifies each node as HH (hot spot), L...
graph.centrality(none)top_k, normalise, sample_size, pivot_strategyviewerBetweenness-centrality ranking (Brandes' algorithm, exact or approximate) — the nodes that lie on the most shortest paths, i.e. the graph's structural bottle...
graph.link_predictionnode_idmethod, top_k, labelviewerPredict likely-but-missing edges for a node using a chosen similarity method: jaccard, adamic_adar, resource_allocation, preferential_attachment, common_neig...
graph.personalised_pagerankseed_idalpha, max_iterations, top_kviewerCompute Personalised PageRank (PPR) rooted at a seed node (Phase 7.12). Ranks nodes by random-walk proximity to seed_id with configurable damping alpha and m...
graph.triangles(none)(none)viewerCount triangles per node and compute local and global clustering coefficients across the graph (Phase 7.11).
graph.bridges(none)(none)viewerFind bridge edges whose removal disconnects the graph using iterative Tarjan DFS in O(V+E) time (Phase 7.11). Identifies single-point-of-failure links in inf...
graph.articulation_points(none)(none)viewerFind biconnected components and articulation points (cut vertices whose removal disconnects the graph) via Tarjan's algorithm (Phase 7.11).
graph.bipartite_check(none)label_a, label_bviewerDetermine whether the graph (or a pair of node labels) is bipartite via BFS 2-colouring and return the two partitions (Phase 7.11).
graph.bipartite_matchinglabel_a, label_bedge_typeviewerCompute maximum cardinality bipartite matching between two node label partitions via Hopcroft-Karp in O(E √V) (Phase 7.11).
graph.mst(none)weight_propertyviewerCompute the Minimum Spanning Tree / Forest using Kruskal's algorithm + union-find (Phase 7.11).
graph.motifs(none)size, node_limitviewerCount directed 3-node triad motif patterns (feed-forward loops, cycles, mutual dyads, etc.) in the graph (Phase 7.11).
graph.temporal_pagerank(none)decay_lambda, reference_time, damping, max_iterations, tolerance, top_kviewerCompute PageRank with exponential recency decay exp(-λ × age) on edge timestamps so recent relationships carry higher authority (Phase 7.3).
graph.dynamic_pagerank(none)added_edges, removed_edges, prev_scores, damping, max_iterations, tolerance, top_kviewerIncremental PageRank update after edge additions or removals (Phase 7.3). Re-scores only the k-hop frontier of changed edges instead of recomputing the entir...
graph.dynamic_communities(none)added_edges, removed_edges, prev_communities, max_iterations, seedviewerIncremental community detection after edge additions or removals (Phase 7.3). Re-runs label propagation only on the 2-hop neighbourhood of affected nodes.
graph.structural_roles(none)degree_bins, clustering_bins, persistviewerFingerprint nodes into structural role classes using logarithmic degree bins and clustering-coefficient bins (Phase 7.4).
graph.rolesimnode_idtop_k, clustering_binsviewerFind nodes with the highest structural role similarity to a query node (Phase 7.4 RoleSim) — identifies structurally equivalent brokers, hubs, or leaves even...
graph.fraud_rings(none)min_density, min_ring_size, max_iterations, seedviewerDetect dense-subgraph communities likely to represent collusive fraud rings (Phase 7.5). Runs label propagation and returns communities whose internal edge d...
graph.simranknode_idtop_k, iterations, decayviewerCompute SimRank structural similarity scores relative to a query node for Sybil / synthetic-identity detection (Phase 7.5).
graph.laundering_pathssource_id, target_idmax_paths, max_depth, edge_typeviewerEnumerate all simple (cycle-free) directed fund-flow paths between source_id and target_id for AML / money-laundering investigations (Phase 7.5).
graph.supply_chain_routesource_id, target_idcost_property, heuristic_property, edge_typeviewerFind the minimum-cost route between two nodes using multi-criteria A* search with optional edge cost_property and node heuristic_property (Phase 7.5).
graph.attack_pathsentry_node, asset_nodemax_depth, max_paths, risk_property, edge_typeviewerEnumerate and rank cybersecurity attack paths from entry_node to asset_node scored by the product of per-edge exploitability weights in descending risk order...
graph.recommenduser_nodeitem_edge_type, top_kviewerGenerate collaborative-filtering item recommendations for user_node over bipartite user-item interaction edges (Phase 7.5).
graph.text_searchqk, labelviewerFull-text BM25 / keyword search over graph nodes (zero embeddings or LLM required). Returns policy-filtered matching nodes ranked by relevance score.
graph.explain_querycypherparametersviewerReturn the Cost-Based Query Planner execution plan and selected strategy (PROPERTY_INDEX_SCAN, LABEL_INDEX_SCAN, VECTOR_SEARCH, TRAVERSAL, FULL_SCAN, HYBRID)...
graph.edges_count(none)(none)viewerReturn the total number of edges in the graph (the edge counterpart to graph.counts).
graph.add_nodes_bulknodes(none)editorBatch-insert up to 1,000 nodes in a single WAL-batched transaction (20x faster than individual graph.add_node calls).
graph.add_edges_bulkedges(none)editorBatch-insert up to 1,000 directed edges in a single WAL + Rayon batch (23.5x faster than individual graph.add_edge calls).
graph.counts(none)labelviewerReturn the total number of nodes in the graph, optionally filtered by label. A cheap situational-awareness call an agent can make before deciding how to quer...
graph.labels(none)(none)viewerList every node type (label) in the graph with how many nodes carry it, largest first. Cheap — O(types), not O(nodes). Call this first to learn what the grap...

data.* (11 tools) ​

__n number, __d ISO date, __b bool) next to the original string, and a property index is buil...
Tool NameRequired ParamsOptional ParamsMin RoleDescription
data.ingest_texttext, source_nameprofile_hint, auto_commit, job_id, wait_seconds, file_refeditorExtract entities and relationships from raw text and write them into the graph. Calls preview first, then commits the complete extraction on success. auto_co...
data.commitentities, relationshipsidentity_policy, source_name, metadata, doc_type, chunking_hint, section_boundaries, suggested_embedding_model, markdown ...editorCommit a reviewed extraction or your own extractor's output without invoking DocIntel. Uses the complete POST /ingest/commit contract: entities, relationship...
data.replace_filefile_id, urlre_extract, intent, base_versioneditorUpload a new version of an existing file blob. The current blob is automatically archived as v1 (idempotent). The new bytes become v{N+1}. The File node is u...
data.patch_file_propertiesfile_idfilename, description, tags, classificationeditorUpdate mutable metadata on a File node without touching the stored blob or bumping the version number. Fields: filename, description, tags (list of strings),...
data.list_file_versionsfile_id(none)viewerReturn the full version history of a stored file, oldest to newest. Each entry contains: version (int), filename, size_bytes, content_hash, file_ref, modifie...
data.get_tabletable_id(none)viewerSummary of a stored document table (from a commit with tables): columns, inferred column_types, indexed_columns (with which layer set them), typed_status / t...
data.link_table_rowstable_id, rulesreplaceeditorDeclare rule-based links from a table's rows to entities and apply them. Each rule: column (header name), target_label (e.g. Organization), match (exact_id |...
data.index_table_columnstable_id, columns(none)editorMark table columns as indexed: each row gets a typed copy (
data.query_table_rowstable_idwhere, limitviewerFilter one table's rows. 'where' maps a column to a value (equality) or to operators {$eq,$ne,$lt,$lte,$gt,$gte,$in,$nin,$exists}. Indexed typed columns comp...
data.ingest_fileurl, source_nameprofile_hint, auto_commit, job_id, wait_seconds, file_refeditorSend a document file (PDF, DOCX, PPTX, XLSX, HTML, IFC, CSV, …) to Purple8 DocIntel for parsing, entity extraction, and graph ingestion. The document is fetc...
data.list_files(none)limit, offsetviewerList stored files in the current tenant's File Library with pagination.

journey.* (9 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
journey.startjourney_type, entity_id(none)editorCreate a new Journey Engine instance for an entity and move it to the first stage. All transitions are recorded as immutable graph edges. Requires editor role.
journey.advanceinstance_id, to_stagenoteseditorAdvance a journey instance to the next stage. Actor and notes are written to the audit trail as an ADVANCED_TO edge. Requires editor role.
journey.statusinstance_id(none)viewerReturn the full state and audit trail for a journey instance — every stage transition, AI recommendation, and HITL decision.
journey.define(none)operation, ai_enabled, journey_type, description, stages, overwriteadminDefine a new journey type (workflow template) with ordered stages, owner systems, and per-stage SLA policies. Once defined, instances can be started with jou...
journey.list(none)journey_type, entity_id, status, list_types, runtime_statusviewerList journey instances with optional filters. Use this to discover what is in flight, find instances for a specific entity, or check all instances of a given...
journey.sla_alerts(none)journey_type, operation, instance_id, event_id, notes, reason, expected_stage_entered_at, limit ...viewerInspect and operate tenant SLA monitoring. operation=breached (default) returns active journey instances that have breached their SLA. health reports local m...
journey.list_hitl(none)instance_id, assigned_role, statusviewerList pending Human-In-The-Loop (HITL) tasks — decisions that require a human (or agent acting as human proxy) to approve, reject, or escalate before the jour...
journey.resolve_hitltask_id, action, actordecision, advance_to_stage, notes, new_assigned_roleeditorResolve a Human-In-The-Loop (HITL) task — approve, reject, or escalate it. On approval the journey automatically advances to the next stage if advance_to_sta...
journey.auditinstance_idlimitviewerRetrieve the immutable audit trail for a journey instance. Returns every stage transition, HITL decision, SLA event, and AI-step note recorded against the in...

rag.* (6 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
rag.queryquestion(none)viewerFlat Vector RAG — retrieves the most relevant graph nodes by pure vector similarity (HNSW + RRF fusion + keyword fallback), then calls the configured LLM to...
rag.graph_queryquestionmax_hops, seed_k, max_nodes, write_inferred, label_filter, max_tokens, temperatureviewerGraph-native RAG — seeds the search with vector-nearest nodes, then expands a multi-hop BFS subgraph and builds a relationship-rich context before LLM genera...
rag.hybrid_queryquestionmode, fusion_alpha, max_hops, seed_k, max_nodes, write_inferred, vector_expansion, semantic_path_scoring ...viewerHybrid Graph-Vector RAG — fuses vector similarity AND graph structural signals at every stage: dual-seed fusion (Weighted RRF over vector rank + degree centr...
rag.profile_collection(none)label_filterviewerAnalyse the graph topology and return recommended RAG retrieval settings. Profiles node count, edge density, degree distribution, edge-type distribution, and...
rag.tune_collectioneval_setlabel_filter, max_iterations, save_asviewerGrid-search hybrid RAG retrieval parameters against a small eval set and return the best-performing configuration. Runs profile_collection() to derive a topo...
rag.rerankcandidatestop_k, alphaviewerGraph-signal reranking of vector / hybrid search candidates. Takes a list of {node_id, score, ...} candidates (as returned by graph.vector_search or rag....

models.* (7 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
models.list(none)(none)viewerList the models the router may use for this tenant: built-in baseline overlaid by tenant-defined entries (source, tier, provider, context, cost, strengths, e...
models.search_known(none)query, provider, limitviewerSearch the public registry of 4,000+ known LLMs (context window, per-token cost, vision support) to find a model name to add. Requires viewer role.
models.upsertmodelprovider, tier, context_tokens, vision, local, strengths, cost_in_per_mtok, cost_out_per_mtok ...adminAdd or replace a model in this tenant's catalogue. Only 'model' is required; provider, tier, context_tokens, vision and cost are auto-filled from the known-m...
models.removemodel(none)adminRemove a tenant-defined model entry. If it overrode a built-in, the built-in reappears. Requires admin role.
models.get_policy(none)(none)viewerReturn this tenant's model-routing policy (signal weights, vetoes, hard tasks).
models.set_policy(none)policy, include_builtinadminReplace the model-routing policy. 'policy' is a partial dict merged over defaults (weights, weight_thresholds, veto_signals, veto_thresholds, hard_tasks, bas...
models.route_explain(none)task_type, input_tokens, needs_vision, needs_strict_json, tool_count, contains_pii, require_local, prior_failure_rate ...viewerDry-run the model router: given a task description, return the chosen model, tier, fallback chain and the full decision trace. No LLM call is made.

scheduler.* (4 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
scheduler.add_triggertrigger_id, trigger_type, action_typeinterval_seconds, cron, event_type, condition, tenant_id, webhook_url, signing_secret, emit_event_type ...adminRegister a temporal or event-driven trigger that fires an action. Trigger types: 'interval' (every N seconds), 'cron' (5-field cron: 'm h dom mon dow'), or '...
scheduler.list_triggers(none)(none)adminList all registered trigger ids on the scheduler. Requires admin role.
scheduler.remove_triggertrigger_id(none)adminUnregister a trigger by id. Idempotent. Requires admin role.
scheduler.status(none)(none)adminReturn scheduler running state, all trigger specs, and fire/error counters. Use to verify automations are live. Requires admin role.

egress.* (4 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
egress.add_sinksink_id, urlsigning_secret, event_types, tenant_id, headersadminRegister an outbound webhook sink that delivers graph change events (nodes/edges/journeys) to an external system as HMAC-signed JSON. The mirror image of inb...
egress.list_sinks(none)(none)adminList all registered outbound sink ids. Requires admin role.
egress.remove_sinksink_id(none)adminUnregister an outbound sink by id. Idempotent. Requires admin role.
egress.status(none)(none)adminReturn egress manager state, registered sinks, and delivery counters (delivered / failed / in-flight). Requires admin role.

feedback.* (4 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
feedback.recordtarget_idtarget_kind, kind, rating, label, comment, correction, source, context ...editorRecord human or agent feedback about any graph entity — a RAG answer, a retrieved node, an inferred edge, or a journey. Stored as an immutable graph record t...
feedback.open(none)limitviewerList unresolved feedback items for this tenant (newest first). The agent's work queue for acting on ground-truth signal. Requires viewer role.
feedback.summary(none)(none)viewerAggregate feedback signal for this tenant: total/resolved counts, mean rating, and label + kind tallies. Use to gauge answer quality drift over time. Require...
feedback.resolvefeedback_id, resolution(none)editorMark a feedback item as handled, recording how it was addressed (mirrors HITL resolution). Emits a feedback_resolved CDC event. Requires editor role.

registry.* (6 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
registry.register_toolname, base_urltransport, description, method, credential, input_schema, static_headers, required_roles, timeout_s ...adminFederate an EXTERNAL tool into this Purple8 gateway so every agent can call it alongside the built-in tools — Jira, a database HTTP API, Slack, a model endpo...
registry.register_mcp_serverprefix, base_urlcredential, static_headers, required_roles, timeout_s, allow_insecureadminFederate a whole downstream MCP server (any Model / IDE / Bedrock / vendor MCP endpoint that speaks JSON-RPC 2.0). Purple8 calls tools/list on it and registe...
registry.register_a2a_agentprefix, card_urlcredential, static_headers, required_roles, timeout_s, allow_insecureadminFederate a peer AI agent that speaks the A2A (Agent2Agent) protocol. Purple8 fetches its Agent Card and registers one tool per advertised skill as '{prefix}....
registry.list_tools(none)(none)viewerList the externally-federated tools registered on this gateway for the current tenant (credentials redacted). Requires viewer role.
registry.remove_toolname(none)adminDeregister a federated tool by name. Idempotent. Requires admin role.
registry.test_toolnameargumentsadminDry-run invoke a federated tool to validate connectivity and credentials before relying on it. Returns the downstream response. Requires admin role.

memory.* (2 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
memory.historysession_idlast_nviewerRetrieve the ordered message history for a session. Use last_n to reconstruct the LLM context window on session resume. Returns list of {seq, role, content,...
memory.searchqueryentity_id, kviewerSemantic search across closed session summaries using vector similarity. Returns the k most relevant past sessions for a given query. Optionally filter by en...

guardrails.* (1 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
guardrails.evaluatetext, check_typesource_context, expected_schema, call_stack, total_tokens, retry_count, elapsed_sviewerRun Purple8 AI guardrail checks on a text payload before writing it to the graph or passing it to an LLM. Checks for prompt injection, scope escape, PII, tok...

sentinel.* (5 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
sentinel.list_findings(none)status, source, min_severity, limitviewerList Sentinel findings — data drift, SOC threshold proposals, emerging threats — most severe first. Each finding carries evidence, a DecisionGate trace and a...
sentinel.get_findingfinding_id(none)viewerFetch one Sentinel finding with full evidence, gate trace and proposal.
sentinel.summary(none)(none)viewerCounts of Sentinel findings by status, source and severity.
sentinel.rejectfinding_idnoteadminDismiss an open Sentinel finding as noise, with a note. (Approval is human-only and not available to agents.)
sentinel.drift_checkkind, namevalues, vectors, scoreviewerCompare current data against a stored baseline. kind=distribution (values, PSI), embeddings (vectors, centroid shift) or quality (score, e.g. RAG F1). Signif...

admin.* (14 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
admin.smtp_status(none)(none)adminReturn the current outbound email (SMTP) configuration status for this Purple8 instance. Shows whether SMTP is active, the host, port, and FROM address. The...
admin.smtp_configurehost, username, passwordport, from_name, from_addressadminConfigure outbound SMTP for this Purple8 instance so that password-reset and user-invite emails work. HITL REQUIRED — you MUST ask the human operator for the...
admin.audit_verify(none)from_seq, to_seqadminVerify this tenant's hash-chained audit trail. Recomputes every record's hash and link to the previous record, and checks signed anchors. Returns ok, first_b...
admin.recovery_status(none)(none)adminRead this tenant's storage recovery readiness and persistence capabilities. Reports WAL/cold-slab persistence, native snapshot availability and historical po...
admin.retention_list(none)(none)adminList this tenant's retention policies (labels, retain_days, action). Read-only.
admin.retention_setmatch, retain_days, actionpolicy_id, name, age_field, anonymise_fields, enabledadminCreate or update a retention policy: nodes matching match.labels (required) and optional classification/properties, older than retain_days, are purged, archi...
admin.retention_deletepolicy_id(none)adminDelete a retention policy by policy_id. Audited.
admin.retention_sweep(none)dry_run, max_actionsadminRun the retention sweeper now. dry_run=true (default) only reports what would be purged/archived/anonymised and which legal holds blocked records.
admin.hold_list(none)include_releasedadminList legal holds (active only unless include_released=true). Read-only.
admin.hold_placereasonnode_ids, matchadminPlace a legal hold. Held records cannot be purged, hard-deleted or removed by retention until the hold is released. Give node_ids and/or match {labels, class...
admin.hold_releasehold_id, reason(none)adminRelease a legal hold by hold_id, with a reason. Records become eligible again. Audited.
admin.kms_status(none)(none)viewerReturn the current AES-256-GCM envelope encryption status, active KMS provider (local/vault/aws/gcp/azure), and key count.
admin.storage_scrub(none)(none)adminRun an online non-destructive CRC32 integrity scrub over BrickWAL frames and cold slabs without taking the database offline.
admin.lineage_getentity_id(none)viewerRetrieve full data provenance and transformation lineage events for an entity_id.

soc.* (3 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
soc.stats(none)(none)viewerReturn autonomous Security Operations Center (SOC) threat detection and containment statistics (critical/high active containments, total released).
soc.containments_active(none)(none)viewerList currently active SOC threat containments and quarantined actor sessions.
soc.audit_log(none)limitviewerRetrieve the SOC security incident and autonomous containment audit log.

supergraph.* (2 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
supergraph.peers_list(none)(none)viewerList declared regional/domain Purple8 SuperGraph federation peers and their approval status.
supergraph.queryqueryparams, domains, journey_id, deduplicateviewerExecute an approved federated query across stitched SuperGraph peer instances.

quantum.* (8 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
quantum.annealn, Qproblem_id, n_steps, t_start, t_end, schedule, seed, hybrid, warm_starteditorRun Simulated Annealing (optionally with greedy refinement) on a QUBO problem and return the best binary solution found. Suitable for combinatorial optimisat...
quantum.optimizen, Qproblem_id, domain, force_methodeditorTopology-aware QUBO solver dispatch — automatically selects between greedy descent, simulated annealing, tabu search, and hybrid SA+greedy based on problem s...
quantum.simulaten_sitesbond_dim, phys_dim, seed, operator, ising_heditorConstruct a random Matrix Product State (MPS) tensor network and optionally compute the expectation value ⟨ψ|O|ψ⟩ for a given MPO operator. Useful for valida...
quantum.encode_stateamplitudes_realamplitudes_imag, state_id, domain, metadataeditorEncode a quantum state vector and store it as a Purple8 graph node. The state is HNSW-indexed via an interleaved real/imag embedding so it can be retrieved b...
quantum.measurestate_idn_shots, seedviewerSimulate projective measurement of a stored quantum state. Loads the state vector from the graph store and samples n_shots computational-basis outcomes accor...
quantum.vqe_stepn_visible, n_hiddenhamiltonian, J, h, n_samples, learning_rate, use_sr, seed, weights_a ...editorExecute one Variational Quantum Eigensolver step using a pure-numpy RBM (Restricted Boltzmann Machine) variational ansatz. Pass the weights from the previous...
quantum.comparestate_id_a, state_id_b(none)viewerCompute the quantum fidelity F = |⟨ψ_A|ψ_B⟩|² between two stored quantum states. Both states must have been previously encoded via quantum.encode_state. Retu...
quantum.profilendensity, domainviewerRecommend the optimal QUBO solver for a given problem size and density. No computation is performed — this is a pure advisory call. Returns the recommended s...

evolution.* (8 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
evolution.routing_policyoutcomescost_weight, generations, min_gainadminInternal intelligence: evolve the tenant's model-routing policy against observed outcomes ({profile: TaskProfile fields, tier: small|default|flagship, succes...
evolution.rag_retrievaleval_set, profile_namelabel_filter, generationsadminInternal intelligence: evolve hybrid-RAG retrieval params (fusion_alpha, max_hops, seed_k) against an eval set of question/expected_answer pairs (token-F1 on...
evolution.create_experimentname, genesdescription, maximize, population_size, min_trialseditorExternal intelligence: create an online experiment that evolves any parameters of your application from reported outcomes. genes: list of {name, gene_type: f...
evolution.list_experiments(none)(none)viewerList the tenant's evolution experiments with generation, best and production scores.
evolution.suggestname(none)viewerGet the next candidate config (genome_id + config) to try in an experiment.
evolution.reportname, genome_id, score(none)editorReport the observed score for a candidate returned by evolution.suggest. When every candidate has min_trials reports, the next generation is bred.
evolution.productionname(none)viewerThe human-approved production config of an experiment — serve this outside the experiment.
evolution.proposenamemin_gaineditorOpen a Sentinel finding to promote an experiment's best candidate if it beats production by min_gain (relative, default 0.05). Promotion needs human approval.

aec.* (18 tools) ​

Tool NameRequired ParamsOptional ParamsMin RoleDescription
aec.buildings_list(none)(none)viewerList all stored BIM building models in the current tenant's graph (Phase 8).
aec.buildings_analyses(none)(none)viewerList all available analyses that can run against a stored BIM building (clashes, change_impact, compliance, egress, critical_members, rigidity, robustness, m...
aec.buildings_demo(none)nameeditorCreate and persist a sample 2-storey BIM office building (footings, columns, beams, spaces, water pump/valves/outlets, pipes, ducts) in the graph so any Phas...
aec.buildings_getbuilding_id(none)viewerRetrieve a stored BIM building summary and all its constituent BuildingElement nodes.
aec.buildings_deletebuilding_id(none)adminDelete a stored BIM building and all its constituent elements. ⚠ human_only — agents are blocked; a human operator must perform this action directly.
aec.buildings_runbuilding_id, analysisparamsviewerRun a Phase 8 AEC analysis against a stored building: clashes, change_impact, compliance, egress, critical_members, rigidity, robustness, max_flow, or fault_...
aec.vga_buildfloor_plansample_pointsviewerBuild a Space Syntax Visibility Graph (VGA) from a 2D floor plan boundary and obstacles (Phase 8.1).
aec.structural_rigiditynodes, edgesdimensionviewerEvaluate 2D/3D Maxwell/Laman structural rigidity of a frame or truss graph (Phase 8.2).
aec.structural_critical_membersnodes, edgesdimensionviewerIdentify single-point-of-failure structural members (bridges) and biconnected components via iterative Tarjan DFS (Phase 8.2).
aec.bim_clashesnodes, edgestype_a, type_b_prefixviewerDetect spatial/topological clashes between structural and MEP elements in a BIM graph (Phase 8.3).
aec.design_egressnodes, edges, exit_node_ids(none)viewerOptimise emergency evacuation routes and bottleneck min-cuts from all spaces to exit_node_ids (Phase 8.4).
aec.mep_max_flownodes, edges, source_id, sink_idsystem_typeviewerCompute Edmonds-Karp maximum flow and bottleneck capacity across an MEP utility network (Phase 8.5).
aec.spectral_fiedlernodes, edgesnormalised, safety_threshold, graph_idviewerCompute the Graph Laplacian algebraic connectivity (λ₂ Fiedler value and Fiedler vector) for structural robustness (Phase 8.7).
aec.topo_optimisebounding_boxresolution, load_node_ids, support_node_ids, volume_fraction, max_itereditorStart a 3D SIMP-on-graph structural topology optimisation job over a bounding-box volume mesh (Phase 8.8).
aec.morl_generatenodes, edgeszone_labels, reward_weights, episodes, seededitorTrain a Multi-Objective Reinforcement Learning (MORL) GCN policy and return the Pareto-optimal spatial layout (Phase 8.9).
aec.mpnn_propagatenodes, edgesload_vector, hidden_dim, message_steps, graph_idviewerRun the pure-numpy Message-Passing Neural Network (MPNN) physics surrogate to predict nodal displacements and stress proxies (Phase 8.10).
aec.hypergraph_buildnodes, hyperedgesmethodviewerExpand multi-way AEC hyperedges (joints, zones, assemblies) via clique or star expansion (Phase 8.11).
aec.ifc_rewritenodes, edgestargetviewerRewrite a raw IFC BIM graph into a domain-specific analytical graph ('structural', 'vga', or 'mep') via declarative rules (Phase 8.12).

Purple8 Hyper Graph v0.72.0 · AI-Native Execution Infrastructure · NVIDIA Inception Member.