← Back to list

From Static Graph to Agent Tool: Wiring a Knowledge Graph for Consumption with FastMCP

Over the last several months I have been digging into knowledge graphs, and not so much the building side of it. There is already a lot…

Venkatesh Manikantan · 2026-06-19 22:07 · 0 claps · 6.5 min read
#ai-agents-in-action #mcps #fastmcp #knowledge-graph #deep-agent
Open on Medium ↗
Wiki topics: RAG · RAG & Retrieval AGT · AI Agents

From Static Graph to Agent Tool: Wiring a Knowledge Graph for Consumption with FastMCP

Over the last several months I have been digging into knowledge graphs, and not so much the building side of it. There is already a lot written about ontology design and the different principles you can apply when you model a domain. What kept pulling at me was the other end of the pipeline, the consumption layer, the part that an agent or a deep agent actually reaches into when it wants to use all that connected structure.

Here is the thing I kept coming back to. The methodology for building a KG ontology changes from one domain to another, and that is fine, that is expected. You model healthcare differently from how you model a supply chain. But once the graph exists, the question that matters is how anything is supposed to read it. What use is a rich, connected repository if nothing can harness the traversals running through it? A graph that cannot be queried in the way an agent thinks is just a very expensive database nobody talks to.

So my quest in this exploration led me into FastMCP, and into how quickly you can stand up custom, modular tools that a deep agent can call to walk a graph on its own terms.

A quick intro to FastMCP

FastMCP is a Python framework that turns plain functions into MCP (Model Context Protocol) tools. Once a function is registered as a tool, a client like Claude Code, Claude Desktop, or your own agent can call it. The framework reads your type hints to build the input schema and reads your docstring to tell the model what the tool does and how to use it, so you write normal Python and the protocol plumbing gets generated for you (gofastmcp.com).

A bit of context that is worth knowing. FastMCP 1.0 was folded into the official MCP Python SDK back in 2024. What people install today is the standalone, actively maintained project from Prefect, and it has gone well beyond the base protocol with auth, clients, deployment, server composition, and more (github.com/PrefectHQ/fastmcp). The reach is not small either. By the project’s own numbers it is downloaded around a million times a day and some version of FastMCP sits behind roughly 70 percent of MCP servers across all languages (gofastmcp.com). So this is not a fringe library, it is close to the default way people expose tools to LLMs in Python.

FastMCP gives you three building blocks to work with. Tools are executable functions the model can call to do something, like run a query or walk a graph. Resources are read only data the client can pull in as context. Prompts are reusable templates that steer the model’s behaviour. For graph consumption, tools are where most of the action is (kdnuggets.com).

Step 1: Define a server

from fastmcp import FastMCP
mcp = FastMCP("Your server name")

That single object represents your whole MCP application. Everything else hangs off it.

Step 2: Register the tools

from .tools.graph_tools import tool_1, tool_2, tool_3
mcp.tool()(tool_1)
mcp.tool()(tool_2)
mcp.tool()(tool_3)

mcp.tool()(fn) is exactly the same as decorating fn with @mcp.tool(). I like the explicit registration style when the tools live in their own module, because it keeps the graph logic separate from the server wiring. FastMCP then reads the type hints to build the JSON input schema and the docstring to tell the model what the tool is for and how to call it (mcpcat.io). So your docstring is not just documentation anymore, it is the instruction the agent reads before it decides to use the tool. Worth writing carefully.

Step 3: Run

mcp.run()                                  # stdio (default)
mcp.run(transport=..., host=..., port=...) # HTTP/SSE
# Launch: python -m mcp_plugin

By default FastMCP runs over stdio, which is what you want for a local client like Claude Desktop. When you need to serve it over the network for a remote agent, you switch the transport to HTTP or SSE and pass a host and port (danilchenko.dev). Same code, different reach.

What a tool actually looks like

Here is the kind of thing I mean when I talk about consuming a graph. This is a tool that finds the semantic path between two nodes of interest in a KG. A simple example: Find Path

def _node_exists(graph, name: str) -> str:
    """Resolve a node name, falling back to a case-insensitive match."""
    if name in graph:
        return name
    for n in graph.nodes():
        if n.lower() == name.lower():
            return n
    return ""

def find_path(source: str, target: str, all_routes: bool = False) -> str:
    """Find semantic path(s) between *source* and *target* in the KG.
    Parameters
    ----------
    source     : start node name
    target     : end node name
    all_routes : if True, return up to 5 distinct paths instead of just the shortest
    Returns the sequence of nodes and relations connecting the two nodes.
    """
    graph = kg_cache.graph
    # Resolve names to real node ids (case-insensitive), with clear errors
    src = _node_exists(graph, source)
    tgt = _node_exists(graph, target)
    if not src:
        return json.dumps({"error": f"Source node '{source}' not found"})
    if not tgt:
        return json.dumps({"error": f"Target node '{target}' not found"})
    if all_routes:
        paths = all_paths(graph, src, tgt, max_depth=6, max_paths=5)
        return json.dumps({
            "source": src,
            "target": tgt,
            "paths_found": len(paths),
            "paths": paths,
        }, indent=2)
    path = shortest_path(graph, src, tgt)
    if path is None:
        return json.dumps({"error": f"No path found between '{src}' and '{tgt}'"})
    return json.dumps({
        "source": src,
        "target": tgt,
        "path_length": len(path) - 1,
        "path": path,
    }, indent=2)

The local dev loop, and UIs in the chat

This is the part that genuinely surprised me. People tend to compare MCP servers to FastAPI, and the analogy holds further than I expected. The way FastAPI gives you Swagger UI to poke at your endpoints, FastMCP gives you a local preview. Running fastmcp dev apps launches a browser based preview where you pick a tool, fill in the arguments, and see what it returns, without connecting to a real MCP host. It also ships an MCP message inspector so you can watch the protocol traffic underneath while you debug (jlowin.dev)

FAST MCP: Running on local Host

FAST MCP: Running on local Host

Output of FAST MCP

Output of FAST MCP

Why this matters for deep agents

The reason I went down this road in the first place is consumption, and deep agents are where it pays off. A simple agent calls a tool in a loop and that works for small tasks. Deep agents are the ones built for the harder jobs, the multi step research, the analysis that needs planning, context management, and delegation (medium.com).

The clean part is that MCP tools plug straight into them. With LangChain’s deepagents library you connect to your MCP servers, pull the tools, and hand them to the agent in one parameter:

from langchain_mcp_adapters.client import MultiServerMCPClient
from deepagents import create_deep_agent

mcp_client = MultiServerMCPClient({
    "kg": {"url": "http://localhost:8000/sse", "transport": "sse"},
})
mcp_tools = await mcp_client.get_tools()
agent = create_deep_agent(
    tools=mcp_tools,
    instructions="You can traverse the knowledge graph using the provided tools...",
)

Deep Agents support MCP directly through that same tools= parameter, so any custom function, LangChain tool, or tool from any MCP server drops in the same way (docs.langchain.com). That is the whole point. Your graph traversal logic lives in one FastMCP server, and any MCP compliant agent in any framework or language can consume it. There is a real trade here worth being honest about. In process LangChain tools add zero network overhead, while MCP tools live in a separate process and add somewhere around 10 to 50 milliseconds per call (dev.to). For graph consumption that latency is nothing next to what you gain in portability.

Where I landed

What I came away with is simple. FastMCP is a quick way to turn any set of functions into tools an agent can call, and that set does not have to be about knowledge graphs at all. Mine happened to be. The graph stays where it is, the traversal logic gets wrapped once, and from then on any deep agent can walk it through clean, well described tools without ever touching the underlying query language.

The building side of knowledge graphs will keep being domain specific and that is fine. But the consumption side, the part that decides whether all that connected structure ever gets used, is where I think more of us should be spending time.

FastMCP made that side feel approachable, and that is why I keep reaching for it.

References


메타데이터
post_id
cbb9e1f5f2c2
slug
from-static-graph-to-agent-tool-wiring-a-knowledge-graph-for-consumption-with-fastmcp-cbb9e1f5f2c2
url
https://medium.com/@venkateshvishwanath99/from-static-graph-to-agent-tool-wiring-a-knowledge-graph-for-consumption-with-fastmcp-cbb9e1f5f2c2
canonical_url
https://medium.com/@venkateshvishwanath99/from-static-graph-to-agent-tool-wiring-a-knowledge-graph-for-consumption-with-fastmcp-cbb9e1f5f2c2
author_url
https://medium.com/@venkateshvishwanath99
status
ok
fetched_at
2026-06-26 03:39:16