graphview
Allows loading an Obsidian vault as a read-only graph source, mapping notes and wikilinks into a navigable, searchable graph with provenance and recall visualization.
Allows connecting to any SQLite database via a YAML mapping to visualize its tables as graph nodes and edges, including support for recall search, provenance, and coverage analysis.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@graphviewTrace the provenance of the north signal port fact."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
graphview-mcp
See what your agent knows, and how it finds it.

A real memory: 1,949 nodes distilled from four months of an assistant's work, played back in time, then opened up.
An agent's memory is a graph nobody has ever looked at whole: facts, entities, versions, the episodes they came from. This is a read-only viewer and MCP server for that graph. It shows the memory as a full-screen graph you can rotate, flatten, search and replay in time; it puts a box in front of the memory's own recall so you can ask it a question and watch which facts light up; and it measures what the recall can and cannot reach.
It reads an Obsidian vault, the memory.json of the Knowledge Graph Memory MCP,
or any SQLite database you describe in a few lines of YAML. It never writes to
any of them.
Status: 0.1, used daily on one real memory. Working name.
What it is for
Debugging recall. Ask the question your assistant got wrong. See which facts the recall returned, where they sit, what they link to, and whether the right fact exists but was not reached. Run a whole benchmark through it and colour the graph by how often each fact came back: what stays dark is memory no question ever reaches.
Reading a memory's health. Facts nobody linked to anything form a rim around the graph. Small groups cut off from the rest are islands. Names that differ by a letter are probably the same thing twice. One export gives you the checklist, and the next export tells you what moved.
Trust. Click a fact and see the versions it replaced and the episodes it was distilled from. "Why does the assistant believe this?" has an answer.
It is built on one small canonical model (nodes with id, label, type, source, props, created_at, typed edges), so a memory you have never seen can be
mapped in an afternoon.
Related MCP server: Mnemosyne
Try it in two minutes
git clone https://github.com/adecubed/graphview-mcp && cd graphview-mcp
uv run graphview serve examples/vaultThe browser opens on a fictional lab's notes. Drag to rotate, scroll to zoom, click a node, type a question. Then the same lab as an agent would remember it: episodes distilled into facts, facts that supersede earlier versions, facts nobody linked, confidence that decays. Two SQLite files, a YAML, and a stand-in recall in sixty lines:
uv run python examples/memory/recall_server.py # in another terminal
uv run graphview serve --config examples/memory/graphview.yamlAsk it which port does north signal run on. The recall answers, its facts
light up, and clicking one shows the versions it replaced and the episodes it
came from. Everything in examples/ is invented (make_vault.py and
make_memory.py regenerate it).
graphview serve memory.json works the same way for a Memory MCP file. Your own
SQLite memory needs a mapping: see Configuration.
As an app, not a browser tab
uv run --extra app graphview appopens graphview in a window of its own, through the system's web view
(WebView2 on Windows, WebKit on macOS and Linux), with no memory given a panel
asks which one to open: a notes folder, a memory.json, or a graphview.yaml.
The choice is remembered in ~/.graphview, so the next graphview app opens
straight on it; --choose asks again. Installed as a package it is
uvx "graphview-mcp[app]" app.
The viewer
Do this | To |
drag | rotate (3D) or pan (2D) |
wheel | zoom towards the pointer; zooming out recentres |
right-drag | pan |
click a node | fly to it: text, properties, links, provenance |
type, Enter | ask; matches light up, the rest fades |
| one step back |
| drop any selection, show the whole graph |
2D / 3D | flat map or free space; the choice is remembered |
| time-lapse: watch the memory grow by creation date |
colour by | type, source, recall hits, or any measure the nodes carry (confidence, last used, degree…) |
path from here… | in a node's panel: pick another node, the shortest chain lights up |
export list | the worklist as a Markdown checklist (see below) |
| focus the question box |
Nodes with no links at all do not drift around: they form the rim, a ring in 2D and a shell in 3D, in the colour of what they are. What a memory holds but has not tied to anything marks where the graph ends. Small disconnected groups are counted as islands. Both can be hidden from the filters panel.
URL options: ?dim=2, ?bloom=1 (extra glow, heavier), ?labels=0 (no node
names on the graph or on hover, for recording a real memory; panels still show
text when opened), ?debug=1 (exposes window.__graphview).
Asking the memory
Without a recall, the box is a forgiving text search: atlas server finds
atlas_server, accents and word order do not matter.
With a search: block in the mapping, the box talks to your memory's own
recall, whatever it is (vector search, BM25, an LLM-composed answer):
search:
url: http://127.0.0.1:9000/ask
method: POST
body: {query: "{query}"} # or params: for a query string
results: data.items # where the list sits in the reply
id: "fact:{key}" # node id built from each result
text: content # shown as the snippet
answer: summary # optional: a written answer, shown above the hits
timeout: 30The written answer is shown, the hits are listed with their text, and the graph lights up those nodes and what they link to. A hit the graph does not hold is still listed, marked as not in the graph. If the endpoint is down, text search answers and the status bar says so.
Recall coverage
How much of the memory can the recall reach? Run a batch of questions through it:
graphview coverage --config graphview.yaml --questions cases.json --probe entityQuestions come from files (.json, .jsonl, or text, one per line; objects
with question and optionally expected) and from probes: --probe TYPE asks
one question per node of that type, made of its name, best connected first
(--probe-limit, default 300). The pass counts how often each node came back,
per kind of node the search returns, and the viewer then offers recall hits
under colour by. What no question ever reaches stays dark; if that part has a
shape (one period, the rim, one kind of fact) you have a diagnosis a benchmark
score does not give.
When a question says what it expects, as benchmark cases do
("expected": [["8766"], ["harbour", "port"]]: every group, any alternative,
whole tokens), the pass records where the text came back: in the listed hits
(✓), only in the answer composed around them (◐), or nowhere (✗). That tells a
retrieval miss from a generation miss. The filters panel lists the questions,
worst first; click one to run it and see what came back instead.
The report is saved as ~/.graphview/coverage-<hash>.json. It holds the
questions and node ids, so treat it like the memory it describes.
Reading a memory's health
Export list, at the bottom of the filters, saves a Markdown checklist of what probably wants fixing at the source:
likely duplicates: same-type nodes whose names differ by separators, case, accents or a letter or two;
very connected nodes: linked to a large share of the graph. A real hub, or a generic word that got extracted as an entity and now adds noise to every search;
islands, and unlinked nodes with their text.
The viewer changes nothing; this is the list you take to whatever does. Each
export adds a line of counts to a history, so the next one opens with a trend
table and what moved since last time: the way to tell whether the memory is
getting better. The same lists are a tool (worklist) for the agent.
Provenance
A prop can hold ids of rows kept elsewhere, such as the episodes a fact was distilled from. Declare which prop refers to which lookup, and the query that resolves one id:
nodes:
- query: SELECT 'fact:' || key AS id, key, content, source_episodes FROM sem.facts
id: id
label: key
type: fact
props: [content, source_episodes] # a JSON list in the column becomes a list
refs: {source_episodes: episode}
lookups:
episode:
query: SELECT task_id AS id, created_at, summary FROM epi.episodes WHERE task_id = ?The node panel then shows "source episodes: 26 episodes · show" and resolves
them on click. The provenance tool gives an agent the same rows together with
the chain of what the node superseded and what superseded it: any edge type
called supersedes, which a query: edge can build with json_each when the
column holds a JSON list of keys. examples/memory/graphview.yaml does all of
this.
When the same list sits on other nodes, the panel says so ("listed on 6 other
nodes: a batch, not this node's own sources") and refs carries shared_with.
A distiller that stamps every fact it writes with the whole batch it was reading
leaves exactly that trace; it is the first thing this view showed us about ours.
Configuration
Write a graphview.yaml and pass it with --config. Several sources load into
one view, each with its own colour under colour by: source.
sources:
- name: notes
adapter: wikilinks
path: ~/vault
- name: memory
adapter: sqlite
path: /data/graph.db
attach: # other databases, joined read-only under an alias
sem: /data/semantic.db
nodes:
- table: entities # or query: "SELECT ..."
id: id
label: name
type: {column: kind} # or a fixed string: type: person
created_at: created_at # feeds the time-lapse
props: [email, notes]
- query: SELECT 'fact:' || key AS id, key, content FROM sem.facts
id: id
label: key
type: fact
props: [content] # content / text / description show as the node's text
edges:
- table: links
from: from_id
to: to_id
type: {column: link_type}
props: [weight]
masking: false # true hides emails, phone and card numbers, IBANs, US SSNs
limit: 5000 # nodes sent to the viewer; above it the best-connected are kept
colors:
person: "#ffd166"When two tables have overlapping ids, give one an id_prefix: doc and use
from_prefix / to_prefix on the edges that point at it. In a vault, type:
in a note's frontmatter sets its node type and created: or date: its date;
without them the type is note and the date is the file's.
As an MCP server
{
"mcpServers": {
"graphview": {
"command": "uv",
"args": ["run", "--directory", "/path/to/graphview-mcp", "graphview", "mcp", "--config", "/path/to/graphview.yaml"]
}
}
}Tools: get_graph, get_node, neighbors, search, path, provenance,
worklist, graph_stats, list_types, reload, open_viewer(focus?, query?).
Answers are sized for an agent's context, not for a screen: parallel links
merge into one with a count, neighbours come as id, label and type, and both
nodes and links are capped, with the real totals in meta. The viewer gets the
full data. open_viewer opens the browser on this machine, focused on a node or
on a question, so "show me what you know about X" becomes a picture.
Safety
The sources are never written to. SQLite, attached databases included, is opened with
mode=roandquery_only; a missing file is an error, not a new database. The one place graphview writes is its own folder,~/.graphview(orGRAPHVIEW_HOME): the worklist history, a date and a few counts per export with the sources identified by a hash, and the coverage report when you run one.The viewer's server listens on
127.0.0.1only, checks theHostheader, and needs a random token on every API call. The token travels in the URL fragment, which browsers do not send or log. A port already in use is an error, not a silent shadow.The
search:URL comes from your config file and nothing else; the graph and the page cannot change it.With masking on (
masking: true, or--maskfor one run) everything served, search included, comes from a masked copy, and the source's own search is not called, so a query cannot be used to probe for a hidden value. The default patterns are regexes and will not catch names: check before you share a screenshot.mask_patterns:replaces the defaults.
Adapters
An adapter is a class with a name and load() -> Graph, one file under
src/graphview/adapters/; the wikilinks one is eighty lines. Everything else,
the tools, the viewer, the masking, the worklist, works on the canonical model.
See CONTRIBUTING.md.
What would you add?
This was built against one real memory and two invented ones. If you run an agent with a memory of its own, the most useful thing you can tell us is what you could not see in it: open an issue with what your memory looks like and what question you wanted the graph to answer.
Things we think are next, in no order:
an open contract (
graph_schema/graph_query) so any MCP server can make itself viewable without an adapter: the proposal, and the questions we cannot answer alone, are indocs/graph-contract.md;SQL auto-introspection (tables to node types, foreign keys to links), and Postgres, DuckDB, Neo4j, GraphML, CSV;
several memories in one view with a colour per origin (federation);
everything the memory holds about one person, as an exportable list;
topics found automatically and named after their hubs;
an inline MCP Apps view next to the chat.
Development
uv run pytest
cd viewer-src && npm ci && npm run buildThe built viewer is committed under src/graphview/viewer/, so Python users do
not need Node; CI rebuilds it and fails if the bundle drifts from the source. It
is built on 3d-force-graph and
Three.js; the full list of what the bundle contains is in
src/graphview/viewer/THIRD_PARTY_NOTICES.txt.
Licence
Apache-2.0.
Available Tools
11 toolsget_graphA
Subgraph as {nodes, links, meta}. Filters are optional. Above limit nodes
the best-connected ones are kept (meta.sampled). Parallel links are merged
into one with a count; above max_links the heaviest are kept
(meta.links_truncated). Prefer search and neighbors over a wide get_graph.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| sources | No | ||
| max_links | No | ||
| edge_types | No | ||
| node_types | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and performs strongly. It discloses concrete behaviors: best-connected nodes are kept above 'limit', parallel links are merged with a 'count', heaviest links are kept above 'max_links', and sampling/truncation are surfaced via meta fields. This gives an agent a realistic model of how the tool behaves beyond the bare schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short sentences and every sentence contributes: output shape, filtering, sampling/merging behavior, and routing guidance. It is dense but not bloated, and the most important information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists and the tool has no required parameters, the description covers the important behavioral details, optional filters, truncation semantics, and an explicit alternative suggestion. It leaves some parameter-level documentation gaps, but an agent has enough to invoke the tool reasonably.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does add meaningful semantics for 'limit' and 'max_links' by explaining their effects on sampling and truncation, and it notes that filters are optional. However, 'sources', 'edge_types', and 'node_types' are left to their titles and schema types, with no per-parameter guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Subgraph as {nodes, links, meta}', making the resource and the return shape clear even though it lacks an explicit action verb. It further distinguishes itself from siblings by instructing to prefer 'search and neighbors over a wide get_graph'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The final sentence explicitly tells the agent to prefer 'search and neighbors over a wide get_graph', naming alternatives and giving a clear when-not condition. It does not fully spell out the positive conditions under which get_graph should be the preferred tool, but the guidance is actionable enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_nodeA
One node with its properties and its links grouped by link type. Each group
has the real total and its max_per_type heaviest neighbours (id, label,
type, count of parallel links). Use neighbors to walk further.
| Name | Required | Description | Default |
|---|---|---|---|
| node_id | Yes | ||
| max_per_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden and it does well by disclosing the exact response shape: grouped links, real total, and max_per_type heaviest neighbours with listed fields. It does not discuss errors or authentication, but for a single-node read operation the disclosed behavior is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, dense sentences with no filler. The core output is front-loaded, and the traversal hint is placed last without bloating the description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists and the description already lays out the response structure, link grouping, and truncation semantics, an agent has what it needs to call this tool correctly. The only omission is node_id format details, which the schema supplies.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds real meaning to max_per_type by defining it as the number of heaviest neighbours included per link-type group. node_id is implicit from the tool name and schema title, so the only non-obvious parameter is explained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that this tool returns one node with its properties and its links grouped by link type, and then explains the grouping semantics in detail. It is specific enough to distinguish from siblings like get_graph or neighbors without opening their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The closing instruction 'Use neighbors to walk further' explicitly points to the sibling tool for traversal, and 'One node' implies this is for inspecting a specific node rather than the whole graph. It lacks explicit when-not-to-use conditions for get_graph or search, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
graph_statsA
Counts by node type, link type and source, plus load warnings.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral disclosure burden. It reveals that the tool returns counts and load warnings, and the verb 'Counts' implies a read-only operation. However, it does not explain the meaning of load warnings, potential performance cost, or failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence that front-loads the core purpose and includes the most important output dimensions. Every word adds useful information, with no repetition or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and a simple aggregation task, the description covers the main invocation needs. The lack of an output schema means the exact return format is unspecified, but the description names the aggregation dimensions and the warning feature, leaving only minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there are no parameter semantics to document. Baseline 4 applies because invocation requires no arguments and the schema already confirms this.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Counts') and identifies the resource (graph statistics) with clear aggregation dimensions: node type, link type, and source. It also distinguishes this tool from siblings like get_graph and list_types by focusing on aggregate counts and load warnings rather than raw graph data or type lists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance about when to choose graph_stats over its siblings such as get_graph, list_types, or neighbors. No context, exclusions, or alternative conditions are given, so an agent must infer the appropriate use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_typesB
Node types, link types and sources, each with its count and display colour.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure, but it only lists output contents. It does not mention whether the operation is read-only, how results are ordered or grouped, or whether any filtering is applied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single short fragment with no wasted words, and the core resource is stated first. It loses a point for lacking a verb and not being structured as a clear directive, though it is otherwise compact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter listing tool with no output schema, the description gives the essential return content: types/sources with counts and colors. However, 'sources' is ambiguous, and the description does not clarify what the returned list is for or when it should be used relative to the sibling tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the description does not need to explain parameter usage. Since there are no parameters to document, the baseline of 4 applies and the description adds no irrelevant param details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific resources (node types, link types, sources) and the output attributes (count, display colour), making the tool's purpose recognizable. However, it is a noun phrase without an explicit verb, and it does not explicitly contrast with sibling tools like graph_stats or get_graph.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided about when to call list_types versus alternatives such as graph_stats or get_node. The description implies a catalog/listing use case but never states it, and there are no exclusions or routing cues.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
neighborsB
Subgraph around a node, following links in both directions up to depth.
Same sampling and link merging as get_graph.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | ||
| limit | No | ||
| node_id | Yes | ||
| max_links | No | ||
| edge_types | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral disclosure burden. It does disclose traversal direction (both directions), depth limiting, and that sampling/link merging match get_graph. However, it does not explain what the returned subgraph contains, whether it is read-only, or any side effects or limitations beyond depth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with the core purpose and key traversal behavior. The clause 'Same sampling and link merging as get_graph' is efficient but somewhat reliant on the sibling description, yet it keeps the text tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is an output schema, so return shape is presumably covered. However, with no annotations and zero schema parameter coverage, the description should explain the parameters and perhaps the sampling semantics more fully. The tool is not overly complex, so the description gives a reasonable starting point, but an agent would still need to inspect get_graph or the schema to fully understand limit, max_links, and edge_types.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for explaining all five parameters. It only gives meaning to 'depth' and implies 'node_id' via 'around a node'. Limit, max_links, and edge_types are completely unexplained, and the reference to get_graph does not define them for this tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as retrieving a subgraph around a specific node, following links in both directions up to a depth. This distinguishes it from siblings like get_node (single node) and get_graph (probably whole graph or larger subgraph), though it does not explicitly name an alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is implied by 'Subgraph around a node' and the reference to get_graph for sampling and link merging. However, there is no explicit statement of when to prefer this tool over siblings, and no exclusions or alternative suggestions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_viewerA
Open the 3D viewer in the user's browser. focus is a node id to fly to;
query runs a search in the viewer. The URL works only on this machine.
| Name | Required | Description | Default |
|---|---|---|---|
| focus | No | ||
| query | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the behavioral disclosure burden. It adds useful facts: the viewer opens in the user's browser and the URL is machine-specific. It does not mention error handling, return behavior, or whether the call blocks, but these are minor for a simple browser-launching tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with the main action front-loaded. Each sentence earns its place: one states what the tool does, the other clarifies the parameters and the environment limitation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity tool with two optional parameters and no output schema, the description covers the essential aspects: the action, parameter meanings, and a critical environmental constraint. It omits only incidental details like return behavior or blocking semantics, which are easy to infer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides no parameter descriptions (0% coverage), so the inline explanations are essential. `focus` is clearly defined as a node id to fly to and `query` as a search action, giving the agent enough meaning to pass correct values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action—opening the 3D viewer in the user's browser—and clearly names the resource being acted on. It also introduces the two parameters that shape the action, making the tool's role distinct from the sibling data-query tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when the tool is useful by explaining that `focus` flies to a node and `query` runs a search in the viewer, but it does not explicitly contrast this with sibling tools like `search` or `get_graph`. The note that the URL works only on this machine is a useful constraint, yet it does not fully spell out when to choose this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pathA
How two nodes are connected: the shortest chain of nodes between them, link
direction ignored, with the typed links along it. found is false when there
is no way through. Get the ids from search.
| Name | Required | Description | Default |
|---|---|---|---|
| to_id | Yes | ||
| from_id | Yes | ||
| edge_types | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses key behaviors: direction is ignored, the result includes typed links, and a 'found' flag indicates reachability. This goes beyond the schema and gives the agent essential execution details. However, it does not mention edge cases like missing nodes or performance characteristics, which are minor for a read-only path query.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with zero fluff. The first sentence states purpose and behavior; the second explains the output flag and input sourcing. It is front-loaded and every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has three parameters, no annotations, and an output schema (which covers return structure). The description explains the core logic and gives an input prerequisite, but omits the meaning of 'edge_types'. Given the output schema exists, the description need not detail return values, but the missing parameter explanation makes it incomplete. A 3 reflects adequate but not full coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description must compensate. It implicitly explains 'from_id' and 'to_id' via 'Get the ids from search' and 'between them,' but it does not explain the 'edge_types' parameter at all. The phrase 'with the typed links along it' describes the output, not the input filter. This leaves a significant gap for one of three parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: finding the shortest path between two nodes, ignoring direction, and returning typed links. It distinguishes itself from siblings like 'neighbors' (direct connections) and 'get_graph' (whole graph) by specifying a path search. The purpose is unambiguous and actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear usage hint: 'Get the ids from search,' indicating a prerequisite for calling this tool. It implies when to use it (you need node ids) but does not explicitly contrast with alternatives like 'neighbors' or 'get_graph'. This is clear context without exclusions, warranting a 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
provenanceA
Where a node comes from: the chain of nodes it superseded (nearest first), the ones that superseded it, and its source rows (e.g. the episodes a fact was distilled from), when the mapping declares them.
| Name | Required | Description | Default |
|---|---|---|---|
| node_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does well: it specifies the two directional chains, the nearest-first ordering, and the conditional on source rows. It does not explicitly state read-only behavior or error cases, but it is an accurate and informative behavioral contract.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence front-loads the core purpose and packs the three output categories and the ordering/conditional into the remaining clauses. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with an output schema, the description covers the key semantics of the result and one important edge condition. It lacks explicit usage guidance and a direct node_id parameter description, but nothing essential to invoking the call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, node_id, has no schema description, and the tool description never names it directly. However, 'a node' in 'Where a node comes from' makes it clear node_id identifies the node whose provenance is requested, so the description partially compensates for 0% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly defines the tool's result: the supersession chain (both ancestors and descendants) plus source rows, so an agent can tell provenance from get_node/neighbors. It lacks an imperative verb ('get'/'fetch'), but 'Where a node comes from' is a specific, unambiguous purpose statement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The opening phrase 'Where a node comes from' establishes clear use context: call this when lineage or derivation is needed. It does not mention alternatives or exclusions, so it misses the top score, but the intended usage is not merely implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reloadB
Read every source again. Returns the new stats.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It only says sources are read again and new stats are returned; it does not disclose side effects like cache invalidation, cost, permission requirements, or impact on other data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The core action is front-loaded and every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema and no annotations, so the description should explain return values and side effects more thoroughly. It says 'returns the new stats' but not what those stats contain or how they are structured, and it leaves the reload behavior ambiguous.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description does not need to explain parameter meanings. The baseline of 4 applies because there is nothing for the description to compensate for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Read every source again' clearly expresses a refresh/reload action, and 'Returns the new stats' gives the result. It does not explicitly differentiate from siblings like graph_stats or get_graph, but the operation described is distinct enough.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use reload versus alternatives, nor any mention of prerequisites or conditions. The description implies it should be used when current stats are wanted, but that context is left entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchA
Find nodes by text in their label or properties. Best matches first.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It adds useful context about search scope ('label or properties') and ordering ('Best matches first'), which goes beyond the schema. However, it does not explicitly state that the operation is read-only or describe any side effects, though 'find' implies a non-destructive search. Given the simplicity of a search tool, this is adequate but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (two sentences) and front-loads the core purpose. There is no fluff or redundant information. However, it could be slightly more structured by explicitly mentioning the limit parameter's behavior, but overall it is efficiently written.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity and the existence of an output schema, the description covers the essential purpose and scope. However, it omits details about the limit parameter's effect on results and any potential edge cases (e.g., empty queries, case sensitivity). The description is not fully complete for an agent to know all behaviors without inspecting the schema further.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains the 'query' parameter implicitly by stating it searches text in labels/properties, but it does not explain the 'limit' parameter at all, despite it being present with a default. The description adds some meaning for query but fails to clarify limit's purpose or behavior, leaving a gap for agents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Find nodes') on a specific resource ('nodes') with a clear criterion ('by text in their label or properties'). It also mentions result ordering ('Best matches first'), which differentiates it from sibling tools like get_node (exact retrieval) or neighbors (graph traversal). This is a precise, unambiguous purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool: when you need to find nodes by text content. However, it does not explicitly mention alternatives or when not to use it, though the sibling list implies that other tools serve different purposes (e.g., get_node for exact IDs). This is clear context without exclusions, so it earns a 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
worklistA
What in this graph probably wants fixing at its source: likely duplicates
(same-type nodes with near-equal names), hubs linked to a large share of the
graph (possibly generic words), islands (small groups cut off from the main
body) and unlinked nodes. summary has the real totals; each list is cut
to max_items.
| Name | Required | Description | Default |
|---|---|---|---|
| max_items | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of disclosure. It reveals important behavioral traits: results are heuristic ('probably', 'likely'), each list is truncated to max_items, and 'summary' contains the real totals. This goes beyond what the schema shows and helps set expectations about incomplete lists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences with no filler: the first enumerates the problem categories, the second clarifies truncation and summary behavior. The phrasing is slightly run-on, but every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single optional parameter and an output schema, the description covers the essential usage context, truncation semantics, and the heuristic nature of the result. It does not describe the output structure in detail, but the presence of an output schema reduces the need for that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description explicitly explains max_items as the cap on each list, which is the parameter's core meaning. It could also mention that the default of 40 applies per list, but the current text is sufficient for a single optional parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies a specific resource ('this graph') and a specific output (a list of probable source-level problems: duplicates, hubs, islands, unlinked nodes). The verb is implied rather than explicit, and it does not directly contrast with siblings, but the categories are distinctive enough that an agent can tell it apart from get_graph or graph_stats.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is implied: call this tool to see what likely needs fixing in the graph. However, there is no explicit statement of when to use it instead of siblings like graph_stats, search, or get_node, and no exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v0.1.0- First observed
get_graph - First observed
get_node - First observed
graph_stats - First observed
list_types - First observed
neighbors - First observed
open_viewer - First observed
path - First observed
provenance - First observed
reload - First observed
search - First observed
worklist
TDQS
Scored across 11 tools
Each tool has a clearly distinct purpose: opening the viewer, fetching subgraphs, getting single nodes, exploring neighbors, searching, statistics, pathfinding, provenance tracking, worklist analysis, type listing, and reloading. No overlap or ambiguity between tools.
Names are all lowercase and readable, but they mix verb-noun patterns (get_graph, list_types) with standalone nouns (neighbors, path, provenance, worklist). This inconsistency could cause an agent to hesitate on the expected action, though descriptions mitigate confusion.
11 tools is well-scoped for a graph viewer. Each tool covers a distinct aspect of graph exploration and maintenance without redundancy, and the count is neither sparse nor overwhelming.
The tool surface comprehensively covers the domain of graph viewing: browsing, searching, navigation, statistics, relationship tracing, provenance, and integrity checking. There are no obvious dead ends, and the missing CRUD operations are irrelevant since this is a read-only viewer.
Maintenance
Related MCP Connectors
Personal knowledge graph as an AI memory layer over MCP - read, save, and link your memories.
- KogniteOAuthdev.kognite
Hosted agent memory: store, search, and recall facts across sessions from any MCP client.
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Token-efficient MCP memory for Markdown vaults. Tiered search, GraphRAG, AI memories.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to persist and retrieve structured thinking graphs using SQLite-backed memory with support for CRUD operations, graph search, and path finding.1-
- AlicenseAqualityBmaintenanceProvides persistent, graph-based memory for AI agents via MCP, enabling semantic search, wikilink traversal, reminders, and injection protection.931Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables storing and querying a personal knowledge graph as a shared memory, allowing agents and tools to remember facts, entities, relations, and recall relevant context via natural language hybrid search.1MIT
- AlicenseNot gradedqualityDmaintenanceEnables LLM assistants and agents to query and manage a personal markdown vault as a graph-based knowledge base using hybrid retrieval, with tools for searching, editing, tagging, and recalling memories across MCP-compatible clients.57 PyPI4MIT