Skip to content

MCP Integration ​

Purple8 Hyper Graph v0.72.0 ships a built-in MCP server (HTTP + SSE + Streamable HTTP) exposing 125 MCP tools across 16 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=starter22Non-technical operators, Claude Desktop, and rapid prototyping (rag.*, core graph.* CRUD/search/traverse, data.ingest_*, journey.*).
builder/mcp?profile=builder72Cursor, Claude Code, and Copilot app builders (starter + schema.*, memory.*, models.*, egress.*, scheduler.*, feedback.*, registry.*).
ops/mcp?profile=ops33Operations, compliance & governance (journey.*, sentinel.*, guardrails.*, feedback.*, admin.*).
full/mcp (or ?profile=full)125All 16 namespaces including 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 (125 tools across 16 namespaces) ​

NamespaceCountWhat agents can do
graph.*28labels, query, semantic_query, assert_statement, retract_statement (human_only), import_nquads, vector_search, hybrid_search, traverse, add_node, get_node, update_node, delete_node, add_edge, get_edge, delete_edge, edges_exist, pagerank, communities, centrality, link_prediction, shortest_path, counts, poll_changes, wait_for_changes, auto_config, morans_i, local_morans_i
journey.*9define, list, start, advance, status, sla_alerts, list_hitl, resolve_hitl, audit
schema.*12get, define_node_type, get_node_type, update_node_type, delete_node_type, list_node_types, define_edge_type, get_edge_type, update_edge_type, delete_edge_type, list_edge_types, validate
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
models.*7list, search_known, upsert, remove, get_policy, set_policy, route_explain
egress.*4add_sink, list_sinks, remove_sink, status
feedback.*4open, record, resolve, summary
scheduler.*4add_trigger, list_triggers, remove_trigger, status
data.*10ingest_text, ingest_file, commit, replace_file, patch_file_properties, list_file_versions, get_table, link_table_rows, index_table_columns, query_table_rows
memory.*2history, search
quantum.*8anneal, optimize, simulate, encode_state, measure, vqe_step, compare, profile
admin.*10smtp_status, smtp_configure (human_only — JWT required), audit_verify, hold_place, hold_release, hold_list, retention_set, retention_list, retention_sweep, retention_delete
evolution.*8create_experiment, list_experiments, propose, suggest, report, production, rag_retrieval, routing_policy
sentinel.*5summary, list_findings, get_finding, reject, drift_check
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 ​

Purple8 Hyper Graph v0.72.0 · AI-Native Execution Infrastructure · NVIDIA Inception Member · Red Hat Technology Partner.