infranodus Β· git:20261031.6da9fc4 Β· 2026-10-31 Β· sha256 3509b5d70b122ac4

infranodus git:20261031.6da9fc4A

Immutable. This exact content never changes and is served at /api/v1/blob/3509b5d70b122ac4.

---
name: infranodus
description: >-
  Text network analysis and knowledge graphs via the InfraNodus MCP server:
  text structure, content gaps, research questions and ideas, text
  comparison, SEO/GEO and Google search analysis, GraphRAG retrieval,
  structured memory. Accepts text, URLs (incl. YouTube), and saved graphs.
  Analyzes and optimizes an LLM's memories (Claude or Codex memory, mem0,
  claude-mem): optimizes their structure with optimize_knowledge_base and
  finds gaps to bridge them and enhance the memories. Also graphs code repos
  and Obsidian vaults: in a project folder ("graph this repo", "analyze this
  vault", "/infranodus") it mines docs, PDF text, docstrings, WHY/NOTE
  comments, and commit/PR/issue history into saved graphs with a report, and
  keeps them current as files change. When infranodus/manifest.json exists
  in the project root, answer questions about themes, decisions, rationale,
  or gaps by querying the existing graphs FIRST, before reading files. For
  an LLM-authored knowledge base built from sources, prefer the llm-wiki
  skill.
metadata:
  homepage: https://infranodus.com
  openclaw:
    emoji: "πŸ•ΈοΈ"
    requires:
      env: ["INFRANODUS_API_KEY"]
    primaryEnv: INFRANODUS_API_KEY
---

# InfraNodus

Text network analysis and knowledge graph tools via the InfraNodus MCP server.

## How this skill talks to InfraNodus

- **Queries and analysis** β€” use the native MCP tools in the session
  (any InfraNodus prefix: `mcp__infranodus__<tool>`, a plugin's
  `mcp__plugin_<plugin>_infranodus__<tool>`, the claude.ai connector's
  `mcp__claude_ai_InfraNodus__<tool>`, or the plain tool name in ChatGPT
  and Codex).
  The server's own instructions and tool schemas are the authoritative
  reference for every tool's parameters and workflow patterns β€” do not
  duplicate or second-guess them here.
- **Not signed in** β€” if the InfraNodus server is installed but not signed
  in (its tools are missing or return an authentication error), tell the
  user to sign in: in Claude Code, run `/mcp`, select InfraNodus and sign
  in; in ChatGPT or Codex, reconnect the InfraNodus plugin in its
  settings. Then continue.
- **Bulk uploads (repo/vault graphs) β€” session server FIRST.** Prefer the
  InfraNodus MCP server already connected to this session (e.g. the
  claude.ai InfraNodus connector): the agent performs the upload itself
  with that server's `create_knowledge_graph` tool, chunk by chunk,
  following the upload contract in
  [references/repo-graph.md](references/repo-graph.md) Step 3 (one
  `graphName` per scope, heading-aware chunks, `maxNodes: 500`, the
  scope's declared `wikilinksMode`, paced calls, 429 backoff, 413
  bisection, and the same manifest + report bookkeeping the script does).
- **Fallback β€” the bundled script.** Only when the session has NO
  InfraNodus MCP tools connected, use `scripts/upload_scopes.py`, which
  uploads through the MCP server configured in this agent's own config β€”
  `<project>/.mcp.json`, then `~/.claude.json` (this project's section,
  then global), then `~/.claude/settings.json` β€” with project scope
  winning. An `http` entry is reached at its own `url`; a `stdio` entry
  (a local or self-hosted server) is launched as its own subprocess.
  Preflight: `upload_scopes.py [project_dir] --check-auth`. The script
  can never reach a cloud OAuth connector β€” that token lives remotely β€”
  which is exactly why the connector path above is agent-driven.
- **Credentials (script path only) are never read from config files.**
  For an `http` server the key comes from `INFRANODUS_API_KEY` in the
  environment and nowhere else, and is only sent to `infranodus.com` or
  a loopback address (any other host is refused); for a `stdio` server
  the entry's own `env` block is passed to the subprocess untouched.
  There is no endpoint default and no credential fallback: one server,
  one attempt, and a failed connection falls back to the session
  connector if one exists β€”
  otherwise it is a hard stop. Do not work around this by exporting a key
  you found in some other application's config β€” that is how content
  lands in an account the user never chose.
- **If neither is available** (no session tools AND no configured server),
  `--check-auth` prints the `claude mcp add` commands for both the hosted
  and the local option. Offer to run one of them, or offer to keep the
  extracted scope files local. Never guess an endpoint.
- **Provenance** β€” each uploaded scope records `endpoint`, `transport`,
  `account`, and `verified` (the date the graph was successfully read back)
  in the manifest. When a graph query fails, compare the manifest's
  `endpoint`/`account` against the session's own server before assuming the
  graph is missing: the same `graphName` means different graphs on different
  servers and accounts.

## Quick orientation (details live in the server's tool schemas)

- Structural overview of a text/URL/graph: `generate_knowledge_graph`,
  `generate_topical_clusters`; persist with `create_knowledge_graph`
  (uploads to the same `graphName` append statements); remove statements
  from a saved graph with `delete_statements` (by category, exact text,
  query, date, ids, or all β€” `confirm: false` is a dry run that lists the
  matches; the repo/vault update flow uses it to replace changed files in
  place); edit statements IN PLACE (id, date, order kept) with
  `update_statements` β€” `edits: [{match, content}]` to correct individual
  lines (a digest principle, a memory item), or one selector plus `set`
  (add/remove categories, timestamp) / `replace: {pattern, with}` to
  relabel a source or rename a `[[concept]]` across a graph; same dry
  run β†’ `confirm: true` contract.
- What's missing / ideation: `generate_content_gaps` β†’
  `generate_research_questions` / `generate_research_ideas`;
  `develop_text_tool` for the combined pipeline.
- Retrieval: `retrieve_from_knowledge_base` (GraphRAG over a saved graph),
  `analyze_existing_graph_by_name` (structure of a saved graph),
  `generate_contextual_hint` (lightweight structural overview β€” good
  context injection before answering broad questions),
  `generate_responses_from_graph` (prompt-based answers and expert
  advice generated from a saved graph β€” good for advice/recommendation
  questions the graph should answer in its own voice),
  `list_graphs` / `search` / `fetch` for discovery.
- Reasoning check: `optimize_reasoning` on a draft synthesis β€” diagnoses
  biased/focused/diversified/dispersed and suggests which topics or gaps
  to develop further.
- Comparison: `overlap_between_texts`, `difference_between_texts`,
  `merged_graph_from_texts` (each takes a `contexts` array).
- SEO/GEO: `generate_seo_report` (90s+ timeout) or the individual
  `analyze_google_search_results` / `analyze_related_search_queries` /
  `search_queries_vs_search_results` tools.
- Diversity stats in responses: `biased` β†’ too concentrated, `focused` β†’
  somewhat concentrated, `diversified` β†’ balanced, `dispersed` β†’ scattered.

## Analyze and optimize memories

When the user asks to analyze, audit, clean up, or improve an LLM's memory
β€” Claude's (`CLAUDE.md` files, the auto-memory folder
`~/.claude/projects/<project>/memory/`), Codex's (`AGENTS.md` and its
memory files), or an external provider's (mem0, claude-mem, read through
that provider's own MCP search/list tools) β€” treat the memories as a small
knowledge base:

1. **Collect** the memories the user points at. Pass them as `statements`
   (one memory item per statement), with `categories` set to the source
   (file, provider, or memory type) and `timestamps` when the store has
   dates. Do not send secrets or anything the user excludes.
2. **Optimize structure** with `optimize_knowledge_base` (`focus:
   "general"`): what dominates, what is under-developed, which clusters
   never connect, and contradictions or duplicates worth merging. It
   analyzes without saving; pass `saveAs` only if the user wants the
   memory graph kept (e.g. `memory-<project>`), which also allows
   `compareWith` against a repo or vault graph.
3. **Find gaps to bridge** with `generate_content_gaps` (and
   `develop_conceptual_bridges` for links to the wider context): each gap
   is a missing connection between two groups of memories.
4. **Enhance the memories**: propose concrete edits β€” merge duplicates,
   fix contradictions, add a memory that bridges a gap, split overloaded
   ones β€” and show them to the user. Write changes back to the original
   store (the memory files, or the provider's own add/update tools) only
   after the user agrees.

## Repo / Vault Graphs (invoked inside a project folder)

When asked to graph, analyze, or ask questions about a repo, project, or
Obsidian vault, follow [references/repo-graph.md](references/repo-graph.md)
β€” it is the single authoritative runbook. In short:

1. `infranodus/manifest.json` exists + the request is a question β†’ route
   via the manifest (each graph records its `purpose` and `topics`) and
   query the graphs; do NOT re-extract. The content lives only in the
   graphs β€” there are no local content files.
   Manifest exists + build/update intent (or bare `/infranodus`) β†’ run
   `python3 scripts/repo2statements.py . --detect` first and lead the
   AskUserQuestion with "Update changed scopes (<its summary>)", then
   "Rebuild a scope in place", "Add a new scope", "Full rebuild". Update =
   `repo2statements.py . --update [--scope X]` β†’ `upload_scopes.py .`
   (the uploader deletes the changed files' old statements by category
   with `delete_statements`, then appends the delta to the same graph;
   files that only moved β€” same content, new path β€” are relabelled in
   place with `update_statements`, nothing re-extracted); rebuild =
   re-extract β†’ `upload_scopes.py . --force` (clears the graph first,
   same name). No changes β†’ offer query mode. Correcting a few lines of
   the authored digest = edit the file + `update_statements` edits, not a
   rebuild (repo-graph.md, Digest step 4).
2. On a bare launch with no manifest (no target named), inventory the folder, then
   AskUserQuestion what to build: full graph (recommended) / a specific
   folder / docs containing certain terms / one document (see the runbook
   for the follow-up questions). Skip that question when the user already
   named the target. Then ALWAYS ask the build mode (multi-select): **full
   ingestion** (all prose scopes, no LLM), **structure map** (deterministic:
   tree, imports, exports, docstring headlines in a repo, page links in a
   vault β€” cheap, no LLM), **digest + structural feedback** (YOU read the
   target and write simple statements on how it works β€” principles, rules,
   procedures, hand-offs β€” then `optimize_knowledge_base` on the uploaded
   graph: what dominates, what is under-developed, which clusters never
   connect), and/or
   **ontology** (the server distils entities and typed relations from the
   structure or docs graph into `onto-<project>` β€” how the parts fit together;
   costs server LLM tokens). The digest is for reviewing and improving the
   project; ontology is for navigating it. Ontology needs a structure or docs
   upload to exist first; the digest needs nothing.
3. Build: `python3 scripts/repo2statements.py .` (full), `... --structure`,
   and/or `... --digest` (prints the reading list and the format, exit
   code 2 = "now write the file", not an error; write the file it names;
   run it again with the same flags to register) β€” one flag per run β†’
   `python3 scripts/upload_scopes.py .`
   (upload, run in background β€” records routing metadata into the
   manifest, appends a dated section to the append-only
   `INFRANODUS_REPORT.md` log, deletes the intermediate scope files; add
   `--ontology` for the ontology layer, or call `generate_ontology_graph`
   with `sourceGraphName` yourself on Path A) β†’
   `upload_scopes.py . --register-project` (once). The register step asks
   ONE AskUserQuestion (spec in the runbook's Step 4; skip it when
   CLAUDE.md already has the `infranodus-memory` marker block): routing
   rules only, or also the end-of-session insight-memory convention
   (`--register-project --with-memory`) β€” a second marker block that has
   every substantive session distill the USER's insights and save them,
   on their approval, to a `<slug>-insights` memory graph via
   `memory_add_relations` (recall: `memory_get_relations`). Never install
   it unasked. Insights are the user's realizations β€” keep them apart
   from project-learnings (agent operations) and from the content graphs
   (what the files say).

## Companion skills

Sibling skills from the same family that compose with this one. Invoke
via the Skill tool ONLY when the skill appears in the available-skills
listing (match by name/description β€” never assume an install path; names
can vary slightly by install). If one is absent, mention it can be
installed from https://github.com/infranodus/skills and continue.

Knowledge-base workflows:

- **llm-wiki** β€” builds and maintains an LLM-authored knowledge base
  (summarized wiki pages, curated ontologies) from raw sources. Route
  there when the corpus needs authored content β€” scanned PDFs, "second
  brain" / research-wiki requests, anything meant to compound over time.
  This skill maps what exists; llm-wiki writes new knowledge on top. Its
  curated scopes share the same `infranodus/` manifest and their `wiki-*`
  graphs are equally queryable (see the runbook's policy rules).
- **project-learnings** β€” what agents *learned operating in* a project
  (traps, conventions, where things live, decisions), saved to an opt-in
  `learn-<project>` graph via the server's `get_project_learnings` /
  `add_project_learnings` tools. This skill maps what a repo contains; that
  one records what working in it taught the agent. Same entity names, so
  the graphs compose (`difference_between_texts` between them shows modules
  with code but no learnings). Route there at the start/end of substantive
  tasks and on "save what you learned" β€” never enable it unasked.
- **ontology-generator** β€” LLM-generated `[[wikilinks]]` ontology with
  `[relationCode]` tags from a topic or text. Offer it when the user
  wants semantic relations (X causes Y) rather than this skill's
  deterministic co-occurrence mining; output pastes straight into
  InfraNodus.
- **seo-analysis** β€” full SEO research workflow (keyword research, search
  intent, informational supply vs demand) on the same MCP tools. Prefer
  it when the request is an SEO project rather than a one-off report
  (a single `generate_seo_report` call needs no extra skill).

Thinking and analysis lenses β€” offer these when a graph diagnosis
suggests them, or on the user's own cues:

- **shifting-perspective** β€” diagnoses a discourse's structural diversity
  (`optimize_text_structure`) and develops under-represented viewpoints.
  Offer when a graph comes back biased/focused or the user is stuck in
  one frame ("what am I missing?").
- **cognitive-variability** β€” guides shifts between zoom levels and
  connect/explore modes to break rigid or looping thinking; the natural
  follow-up to a shifting-perspective structural diagnosis.
- **critical-perspective** β€” questions assumptions and hunts blind spots
  through curiosity-driven challenge. Offer when a synthesis needs to be
  challenged rather than expanded.
- **rhetorical-analyst** β€” analyzes arguments and debate tactics across
  persuasion, rhetoric, and logic; it opens with this skill's graph
  tools. Offer for debates, speeches, comment threads, "why is this
  persuasive?".
- **perspective-reversal** β€” flips a conflict or negotiation to the
  opponent's viewpoint for tactical advice. Offer when the analyzed
  discourse is adversarial (dispute, standoff, negotiation).
- **embodied-navigation** β€” applies embodied movement principles
  (equanimous scanning, adaptive fluidity, tensegrity) to situations
  mapped as networks. Offer for stuckness, rigidity, or conflict framed
  as dynamics rather than argument.
- **vipassana-meditation** β€” equanimous, non-reactive observation that
  breaks fixation loops. Offer when the conversation shows craving for a
  particular outcome or aversion to an uncomfortable finding, and bare
  attention should precede analysis.