Skip to content

MCP server caches graph.json at startup — no hot-reload after graphify update #874

Description

@mattmillartech

Summary

The graphify MCP server (python -m graphify.serve <graph.json>) reads graph.json once at startup and serves the resulting in-memory graph for the lifetime of the process. After graphify update . writes a fresh graph.json, MCP clients keep seeing the stale graph until the MCP process restarts.

For agent-driven workflows where the agent might rebuild the graph mid-session (e.g., after touching a file it wants to query), this is a UX papercut — the agent has to know to restart the session OR fall back to the CLI to see fresh data.

Reproduction

In a Claude Code session (or equivalent MCP-capable agent):

# Initial state — agent queries graph stats
mcp__graphify__graph_stats
# → Nodes: 21,519 / Edges: 41,899

# Outside the session: rebuild
pnpm run graphify:rebuild
# graphify-out/graph.json now has 23,221 nodes

# Same agent session, query again
mcp__graphify__graph_stats
# → STILL Nodes: 21,519  ← stale

graphify explain unified-intel-check.sh --graph graphify-out/graph.json
# → Node found  ← CLI sees the fresh graph

# Until session restart, MCP is frozen on the load-time snapshot.

Why it matters

  • The mismatch between "CLI returns X" and "MCP returns Y" is confusing during agent workflows that interleave both surfaces.
  • Agents that rebuild the graph as part of their work (e.g., right after adding a new module, before querying for callers) get the wrong answer if they trust the MCP.
  • The natural agent instinct after a rebuild is "now query the MCP" — they don't know about the cache.

Proposed fix

A few options, increasing in complexity:

  1. Watch mode (simplest, no API change): the MCP server already has a graphify watch <path> mode that rebuilds on changes. Document that running the MCP server with watch-mode-equivalent file watching on graph.json makes it auto-reload on disk change. (Probably needs a small loop in graphify.serve to inotify-watch the graph file.)

  2. Add a mcp__graphify__reload tool: explicit reload trigger that re-reads graph.json. Agents can call it after a known rebuild. ~10 LOC. Backwards-compat-safe.

  3. Stale-check on each request: compare graph.json mtime vs load mtime; if changed, reload before answering. Adds one stat() per request — negligible overhead.

I'd pick option 2 (explicit + safe) or option 3 (zero-effort for agents) depending on your taste.

Workaround (today)

Session restart. Fine as a documented behavior — but worth being explicit about it in the python -m graphify.serve docstring or README so first-time users don't get confused by the cache.

Context

Continuing follow-up from #866 (Phase 8 of an agent intelligence-stack integration I shipped this week). The rebuild → MCP-still-stale mismatch caught me mid-verification and I had to document the gotcha for the operator. A built-in solution would save other users from the same workflow papercut.

Happy to contribute the PR if option 2 (explicit reload tool) is the right shape.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions