diff --git a/modules/genai-ecosystem/nav.adoc b/modules/genai-ecosystem/nav.adoc index 178628f..21e2165 100644 --- a/modules/genai-ecosystem/nav.adoc +++ b/modules/genai-ecosystem/nav.adoc @@ -28,3 +28,5 @@ // **** link:xxx[Documentation] **** xref:semantic-kernel.adoc[Semantic Kernel] // **** link:xxx[Documentation] +**** xref:strands-agents-neo4j[Strands Agents] +// **** link:xxx[Documentation] diff --git a/modules/genai-ecosystem/pages/genai-frameworks.adoc b/modules/genai-ecosystem/pages/genai-frameworks.adoc index 5b0d385..911b9e1 100644 --- a/modules/genai-ecosystem/pages/genai-frameworks.adoc +++ b/modules/genai-ecosystem/pages/genai-frameworks.adoc @@ -34,6 +34,7 @@ Neo4j and our community have contributed integrations to many of these framework * xref:langchain4j.adoc[LangChain4j] * xref:haystack.adoc[Haystack] * xref:semantic-kernel.adoc[Semantic Kernel] +* xref:strands-agents-neo4j.adoc[Strands Agents] * xref:dspy.adoc[DSPy] == GraphAcademy Courses diff --git a/modules/genai-ecosystem/pages/index.adoc b/modules/genai-ecosystem/pages/index.adoc index 1bd8dea..3011654 100644 --- a/modules/genai-ecosystem/pages/index.adoc +++ b/modules/genai-ecosystem/pages/index.adoc @@ -90,6 +90,7 @@ You can find overviews of these integrations in the pages of this section, as we * xref:langchain4j.adoc[LangChain4j] * xref:haystack.adoc[Haystack] * xref:semantic-kernel.adoc[Semantic Kernel] +* xref:strands-agents-neo4j.adoc[Strands Agents] * xref:dspy.adoc[DSPy] == Highlighted Articles diff --git a/modules/genai-ecosystem/pages/strands-agents-neo4j.adoc b/modules/genai-ecosystem/pages/strands-agents-neo4j.adoc new file mode 100644 index 0000000..0b9acf8 --- /dev/null +++ b/modules/genai-ecosystem/pages/strands-agents-neo4j.adoc @@ -0,0 +1,158 @@ += Strands AI Agents with MCP and Neo4j +:slug: strands-mcp-neo4j +:author: +:category: genai-ecosystem +:tags: strands, mcp, llm, neo4j +:page-pagination: +:page-product: strands-ai + +Integration of Neo4j graph database with Strands Agents. +Neo4j's graph capabilities can be exposed as MCP tools, allowing LLM-powered Strands Agents to query and modify the database via a standard protocol over HTTP or SSE. + +Two main examples are provided: + +* `mcp_neo4j_client.py` — calls Neo4j tools via a Strands Agent using MCP transport. +* `mcp_neo4j_server.py` — demonstrates a full MCP setup with a FastMCP server exposing Neo4j tools. + +== Installation + +[source,bash] +---- +pip install openai fastapi uvicorn neo4j +---- + +Start a Neo4j instance (local or cloud). + +== Usage + +1) Run the MCP server exposing Neo4j tools: + +[source,bash] +---- +python mcp_neo4j_server.py +---- + +2) Run the Strands Agent client connecting to the server: + +[source,bash] +---- +python mcp_neo4j_client.py +---- + +== Example: mcp_neo4j_server.py (FastMCP server exposing Neo4j tools) + +[source,python] +---- +from mcp.server import FastMCP +from neo4j import GraphDatabase +from neo4j.exceptions import Neo4jError +import os + +# Neo4j configuration +NEO4J_URI = os.getenv("NEO4J_URI", "bolt://localhost:7687") +NEO4J_USER = os.getenv("NEO4J_USER", "neo4j") +NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD", "apoc12345") + +# Create FastMCP server +mcp = FastMCP("Neo4j MCP Server") + +@mcp.tool(description="Execute a Neo4j query, return the result, and log it") +def neo4j_query(query: str): + try: + with GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD)) as driver: + print(f"[LOG] Connecting to Neo4j at {NEO4J_URI} with user {NEO4J_USER}") + try: + with driver.session() as session: + def run_main_query(tx): + print(f"[LOG] Executing query: {query}") + records = [record.data() for record in tx.run(query)] + print(f"[LOG] Query results: {records}") + return records + + records = session.execute_read(run_main_query) + + session.run( + "CREATE (q:ExecutedQuery) SET q.executedQuery = $query RETURN q", + parameters={"query": query} + ).single() + + print("[LOG] Query executed and logged successfully.") + return records + + except Neo4jError as e: + print(f"[ERROR] Query execution failed: {e}") + return {"error": str(e)} + except Neo4jError as e: + print(f"[ERROR] Connection failed: {e}") + return {"error": str(e)} + +if __name__ == "__main__": + print("MCP Neo4j server running at http://localhost:8000/mcp") + mcp.run(transport="streamable-http") +---- + +== Example: mcp_neo4j_client.py (Strands Agent using MCP) + +[source,python] +---- +from strands import Agent +from strands.tools.mcp.mcp_client import MCPClient +from mcp.client.streamable_http import streamablehttp_client + +def create_transport(): + return streamablehttp_client("http://localhost:8000/mcp/") + +def main(): + # 1) Create MCP client + client = MCPClient(create_transport) + + with client: + # 2) List available tools + tools = client.list_tools_sync() + print("Available tools:", [getattr(t, "name", t.mcp_tool.name) for t in tools]) + + # 3) Create a Strands Agent using the Mistral model + from strands.models.mistral import MistralModel + import os + agent = Agent( + tools=tools, + model=MistralModel( + api_key=os.getenv("MISTRAL_API_KEY"), + model_id="mistral-small-latest", + temperature=0.7, + max_tokens=200 + ) + ) + + # 4) Ask a question through the agent + response = agent("What is 125 plus 375?") + print("Agent response:", response) + + # 5) Or directly call a tool + result = client.call_tool_sync( + tool_use_id="tool-1", + name="neo4j_query", + arguments={"x": 125, "y": 375} + ) + print("Calculator result:", result["content"][0]["text"]) + +if __name__ == "__main__": + main() +---- + +== Functionality Includes + +* `neo4j_query` — wraps Neo4j operations as an MCP tool +* FastMCP server exposing Neo4j tools +* Strands Agent using MCP transport to call tools +* LLM integration via Mistral model + +== Relevant Links +[cols="1,4"] +|=== +| icon:user[] Authors | https://github.com/vga91[Vincenzo Gallo^] +| icon:comments[] Community Support | https://community.neo4j.com/[Neo4j Online Community^] +| icon:github[] Integration | https://github.com/vga91/strands-mcp-neo4j[GitHub] +| icon:github[] Issues | https://github.com/vga91/strands-mcp-neo4j/issues +| icon:book[] Documentation | https://vga91.github.io/strands-mcp-neo4j/[Docs] +|===