点击上方↗️「活水智能」,关注 + 星标🌟

作者:Michael Hunger
编译:活水智能
最近,Anthropic发布了一种新的模型上下文协议(Model Context Protocol,简称MCP),用于像Claude这样的LLM与外部数据源进行通信。
该协议允许本地应用程序(如Claude.ai、Zed、Replit等)在与用户的对话中访问文件系统、API和数据库以获取额外信息。这可以用来回答问题、获取更多信息,或者通过代码生成动态生成图表和可视化内容。
以下是对话中的示例展示。
如果你想亲自尝试,可以将以下配置添加到你的claude_desktop_config.json
中,并重启服务器以继续操作。这将指向一个只读的演示数据库。
{"mcpServers": {
"movies-neo4j": {
"command": "uvx",
"args": ["mcp-neo4j-cypher",
"--db-url", "neo4j+s://demo.neo4jlabs.com",
"--user", "recommendations",
"--password", "recommendations"]
}
}
}
不仅如此,他们还开源了许多连接器(服务器),并邀请社区开发更多连接器。
Neo4j MCP服务器
我们立即开始实现一个Neo4j MCP服务器,以探索其具体表现。我们还将其发布在PyPI上,你可以直接运行它。
它也包含在官方的MCP服务器存储库中。
一个交互式示例
以下是如何使用MCP从LLM查询Neo4j数据库的简单示例。
假设你有一个包含电影、演员、导演、类型和电影评分等IMDB风格数据的Neo4j数据库。
我在Claude.ai桌面配置中配置了一个公开访问的数据库,并重启了客户端。

现在,我想知道哪些电影是由昆汀·塔伦蒂诺(Quentin Tarantino)导演的,所以我会直接向Claude提问。
查询我的电影数据库,找出昆汀·塔伦蒂诺导演的电影。
Claude会弹出一个权限对话框,询问我是否允许查询Neo4j数据库(仅限本次或整个聊天会话),如果我接受,它将运行查询并以漂亮的格式返回结果。

然后它回答:

Claude回答:查询我的电影数据库,找出昆汀·塔伦蒂诺导演的电影。
我会帮你查询数据库,找出昆汀·塔伦蒂诺导演的电影。
查看从movies-neo4j(本地)读取的Neo4j Cypher结果
{
`query`: `
MATCH (d:Person {name: 'Quentin Tarantino'})-[:DIRECTED]->(m:Movie)
RETURN m.title, m.year
ORDER BY m.year
`
}
[{'m.title': 'Reservoir Dogs', 'm.year': 1992}, {'m.title': 'Pulp Fiction', 'm.year': 1994}, {'m.title': 'Four Rooms', 'm.year': 1995}, {'m.title': 'Jackie Brown', 'm.year': 1997}, {'m.title': 'Kill Bill: Vol. 1', 'm.year': 2003}, {'m.title': 'Kill Bill: Vol. 2', 'm.year': 2004}, {'m.title': 'Sin City', 'm.year': 2005}, {'m.title': 'Grindhouse', 'm.year': 2007}, {'m.title': 'Death Proof', 'm.year': 2007}, {'m.title': 'Inglourious Basterds', 'm.year': 2009}, {'m.title': 'Django Unchained', 'm.year': 2012}, {'m.title': 'The Hateful Eight', 'm.year': 2015}]
{
`query`: `
MATCH (kb:Movie)
WHERE kb.title IN ['Kill Bill: Vol. 1', 'Kill Bill: Vol. 2']
MATCH (actor:Person)-[:ACTED_IN]->(kb)
MATCH (actor)-[:ACTED_IN]->(other:Movie)
WHERE other.title <> 'Kill Bill: Vol. 1'
AND other.title <> 'Kill Bill: Vol. 2'
RETURN DISTINCT actor.name, collect(DISTINCT other.title) as other_movies
ORDER BY actor.name
`
}
[{'actor.name': 'Daryl Hannah', 'other_movies': ['Clan of the Cave Bear, The', 'Tie That Binds, The', 'Addams Family Reunion', 'Summer Lovers', 'Legal Eagles', 'Reckless', 'Pope of Greenwich Village, The', 'Splash', 'Roxanne', 'Gingerbread Man, The', 'My Favorite Martian', 'Steel Magnolias', 'Walk to Remember, A']}, {'actor.name': 'Lucy Liu', 'other_movies': ['Afro Samurai: Resurrection', 'Lucky Number Slevin', 'Mulan II', 'Cypher', "Charlie's Angels: Full Throttle", 'Ballistic: Ecks vs. Sever', "Charlie's Angels", 'Shanghai Noon']}, {'actor.name': 'Michael Parks', 'other_movies': ['Tusk', 'Death Wish 5: The Face of Death']}, {'actor.name': 'Uma Thurman', 'other_movies': ['Misérables, Les', 'My Super Ex-Girlfriend', 'Even Cowgirls Get the Blues', 'Truth About Cats & Dogs, The', 'Batman & Robin', 'Gattaca', 'Avengers, The', 'Month by the Lake, A', 'Jennifer 8', 'Mad Dog and Glory', 'Johnny Be Good', 'Henry & June', 'Be Cool', 'Producers, The', 'Tape', 'Paycheck']}, {'actor.name': 'Vivica A. Fox', 'other_movies': ['Set It Off', 'Soul Food', 'Boat Trip', 'Juwanna Mann', 'Why Do Fools Fall In Love?']}]
以下是昆汀·塔伦蒂诺导演的电影按时间顺序排列:
1. 《落水狗》(Reservoir Dogs, 1992)
2. 《低俗小说》(Pulp Fiction, 1994)
3. 《四个房间》(Four Rooms, 1995)
4. 《危险关系》(Jackie Brown, 1997)
5. 《杀死比尔:第一卷》(Kill Bill: Vol. 1, 2003)
6. 《杀死比尔:第二卷》(Kill Bill: Vol. 2, 2004)
7. 《罪恶之城》(Sin City, 2005) …
如果你想了解这些电影的更多细节,或者想探索塔伦蒂诺作品的其他方面,请告诉我!
《杀死比尔》的演员还出演了哪些热门电影?

Claude回答:《杀死比尔》的演员还出演了哪些热门电影?
我会查询《杀死比尔:第一卷》和《杀死比尔:第二卷》演员出演的其他知名电影。
查看从movies-neo4j(本地)读取的Neo4j Cypher结果
{}
[{'label': 'Movie', 'attributes': {'budget': 'INTEGER', 'movieId': 'STRING unique indexed', 'tmdbId': 'STRING unique indexed', 'plotEmbedding': 'LIST', 'imdbVotes': 'INTEGER', 'runtime': 'INTEGER', 'posterEmbedding': 'LIST', 'countries': 'LIST', 'imdbId': 'STRING indexed', 'url': 'STRING', 'plot': 'STRING indexed', 'released': 'STRING indexed', 'languages': 'LIST', 'imdbRating': 'FLOAT indexed', 'title': 'STRING indexed', 'poster': 'STRING', 'year': 'INTEGER indexed', 'revenue': 'INTEGER'}, 'relationships': {'IN_GENRE': 'Genre'}}, {'label': 'Genre', 'attributes': {'name': 'STRING unique indexed'}, 'relationships': {}}, {'label': 'User', 'attributes': {'name': 'STRING indexed', 'userId': 'STRING unique indexed'}, 'relationships': {'RATED': 'Movie'}}, {'label': 'Actor', 'attributes': {'born': 'DATE', 'bornIn': 'STRING', 'tmdbId': 'STRING', 'bio': 'STRING', 'died': 'DATE', 'name': 'STRING', 'poster': 'STRING', 'imdbId': 'STRING', 'url': 'STRING'}, 'relationships': {'ACTED_IN': 'Movie', 'DIRECTED': 'Movie'}}, {'label': 'Director', 'attributes': {'born': 'DATE', 'bornIn': 'STRING', 'tmdbId': 'STRING', 'bio': 'STRING', 'died': 'DATE', 'name': 'STRING', 'poster': 'STRING', 'imdbId': 'STRING', 'url': 'STRING'}, 'relationships': {'ACTED_IN': 'Movie', 'DIRECTED': 'Movie'}}, {'label': 'Person', 'attributes': {'born': 'DATE', 'bornIn': 'STRING', 'tmdbId': 'STRING unique indexed', 'bio': 'STRING indexed', 'died': 'DATE', 'name': 'STRING indexed', 'poster': 'STRING', 'imdbId': 'STRING', 'url': 'STRING'}, 'relationships': {'ACTED_IN': 'Movie', 'DIRECTED': 'Movie'}}]
让我按主要演员列举一些知名电影:
乌玛·瑟曼(Uma Thurman)的其他主要电影包括:— 《复仇者联盟》 — 《千钧一发》(Gattaca) — 《蝙蝠侠与罗宾》 — 《悲惨世界》 — 《制片人》 — 《冷酷到底》
刘玉玲(Lucy Liu)出演了:— 《霹雳娇娃》(Charlie’s Angels)和《霹雳娇娃2》(Charlie’s Angels: Full Throttle) — 《上海正午》(Shanghai Noon) — 《幸运数字斯莱文》(Lucky Number Slevin) — 《花木兰2》(Mulan II)
迈克尔·帕克斯(Michael Parks)出演了:— 《獠牙》(Tusk) — 《死亡愿望5:死亡之面》(Death Wish V: The Face of Death)
你想了解这些演员或某些特定电影的更多细节吗?我可以查询关于上映年份、导演或其他演员的信息。
告诉我更多关于《獠牙》的信息,它值得一看吗?使用数据库架构找出评分。

Claude回答:告诉我更多关于《獠牙》的信息,它值得一看吗?使用数据库架构找出评分。
现在,它使用集成中的另一个工具(get-neo4j-schema)来获取数据库架构,这对于确定评分的存储位置和方式非常重要。它返回节点类型、它们的属性、索引情况以及与其他节点的关系。
让我先检查数据库架构,看看关于电影评分的信息存储在哪些地方。
查看从movies-neo4j(本地)获取的Neo4j架构结果
{
`query`: `
MATCH (m:Movie {title: 'Tusk'})
MATCH (m)-[:IN_GENRE]->(g:Genre)
MATCH (d:Person)-[:DIRECTED]->(m)
MATCH (a:Person)-[:ACTED_IN]->(m)
RETURN m.title, m.year, m.imdbRating, m.plot, collect(DISTINCT g.name) as genres,
collect(DISTINCT d.name) as directors, collect(DISTINCT a.name) as actors
`
}
[{'m.title': 'Tusk', 'm.year': 2014, 'm.imdbRating': 5.4, 'm.plot': 'When podcaster Wallace Bryton goes missing in the backwoods of Manitoba while interviewing a mysterious seafarer named Howard Howe, his best friend Teddy and girlfriend Allison team with an ex-cop to look for him.', 'genres': ['Comedy', 'Drama', 'Horror'], 'directors': ['Kevin Smith'], 'actors': ['Michael Parks', 'Haley Joel Osment', 'Genesis Rodriguez', 'Justin Long']}]
现在,查询关于《獠牙》的具体信息,包括其评分、剧情和类型。
查看从movies-neo4j(本地)读取的Neo4j Cypher结果
{
`query`: `
MATCH (a:Person)-[:ACTED_IN]->(kb:Movie)
WHERE kb.title IN ['Kill Bill: Vol. 1', 'Kill Bill: Vol. 2']
MATCH (a)-[:ACTED_IN]->(m:Movie)
WHERE m.title <> 'Kill Bill: Vol. 1' AND m.title <> 'Kill Bill: Vol. 2'
MATCH (m)-[:IN_GENRE]->(g:Genre)
MATCH (d:Person)-[:DIRECTED]->(m)
RETURN DISTINCT m.title, m.year, m.imdbRating, m.plot,
collect(DISTINCT g.name) as genres,
collect(DISTINCT d.name) as directors,
collect(DISTINCT a.name) as actors
ORDER BY m.imdbRating DESC
LIMIT 1
`
}
[{'m.title': 'Gattaca', 'm.year': 1997, 'm.imdbRating': 7.8, 'm.plot': 'A genetically inferior man assumes the identity of a superior one in order to pursue his lifelong dream of space travel.', 'genres': ['Thriller', 'Sci-Fi', 'Drama'], 'directors': ['Andrew Niccol'], 'actors': ['Uma Thurman']}]
根据数据库信息,以下是我可以告诉你关于《獠牙》的内容:
1. 这是一部由凯文·史密斯(Kevin Smith,代表作包括《疯狂店员》、《购物狂》和《爱在心里口难开》)执导的恐怖喜剧剧情片,于2014年9月上映。
2. 剧情讲述了一名播客主持人华莱士·布莱顿(Wallace Bryton)在加拿大马尼托巴采访一名神秘的海员霍华德·豪(Howard Howe)时失踪。他的女友和最好的朋友随后与一名前警察联手寻找他。
3. 这部电影在IMDb上的评分为5.4/10,表明评价褒贬不一。
….
较低的IMDb评分表明这部电影并不适合所有人,但它在喜欢另类恐怖片的观众中形成了一定的粉丝群体。
你想让我在数据库中寻找类似的电影,供你选择吗?
嗯,好吧,从我们获得的《杀死比尔》演员的电影列表中挑选一部最佳电影,并提供一些细节。

Claude回答:嗯,好吧,从我们获得的《杀死比尔》演员的电影列表中挑选一部最佳电影,并提供一些细节。
让我搜索这些电影及其评分,找出评分最高的一部。
{
`query`: `
MATCH (m:Movie {title: 'Gattaca'})
MATCH (p:Person)-[:ACTED_IN]->(m)
RETURN m.runtime, collect(p.name) as cast
`
}
[{'m.runtime': 106, 'cast': ['Xander Berkeley', 'Gore Vidal', 'Uma Thurman', 'Ethan Hawke']}]
在我们之前找到的电影中,《千钧一发》(Gattaca, 1997)以IMDb评分7.8/10脱颖而出。让我获取这部电影的更多细节。
{
`query`: `
MATCH (m:Movie {title: 'Gattaca'})
MATCH (u:User)-[r:RATED]->(m)
RETURN
m.title,
count(r) as number_of_ratings,
round(avg(r.rating)*10)/10 as avg_rating,
min(r.rating) as min_rating,
max(r.rating) as max_rating
`
}
[{'m.title': 'Gattaca', 'number_of_ratings': 84, 'avg_rating': 3.7, 'min_rating': 1.0, 'max_rating': 5.0}]
以下是《千钧一发》的亮点:
1. 剧情:这是一部关于一个基因“劣势”人假冒基因“优势”者身份以追求太空旅行梦想的科幻剧情片。故事探讨了基因歧视、决心和人类潜力等主题。
…..
你是否想让我在数据库中寻找类似于《千钧一发》的电影,供你参考?
《千钧一发》的其他平均、最低、最高用户评分是多少?

Claude回答:《千钧一发》的其他平均、最低、最高用户评分是多少?
让我查看《千钧一发》的用户评分统计数据。
{
`query`: `
MERGE (u:User {userId: 'mesirii', name: 'mesirii'})
MERGE (m:Movie {title: 'Gattaca'})
CREATE (u)-[:RATED {rating: 4.0}]->(m)
RETURN u.name, m.title
`
}
让我查看《千钧一发》的用户评分统计数据。
以下是《千钧一发》的用户评分统计数据:
- 平均用户评分:3.68(满分5分)
- 最低评分:1.0
- 最高评分:5.0
- 评分用户数:84人
平均评分3.68/5(约等于7.4/10)与我们之前看到的IMDb评分7.8/10相符。这部电影获得了可能评分范围内的所有分数(1–5),表明尽管大多数人给予较高评价,但也存在不同意见。数据库中84条评分为我们提供了一个不错的样本量。
好的,我看了《千钧一发》并且很喜欢,还有哪些类似的电影?能否为我创建一个ID为mesirii的用户,并将我的评分8/10存储进去(将其标准化以适应电影的其他评分)?
我们开始进行写入操作,并获得另一个写操作工具的权限检查。这是Claude第一次在Cypher语句中出现小语法错误,并立即修复。由于我的数据库是只读的,它实际上无法写入,但它为我提供了其他可以观看的电影。

我会先帮你添加评分,将8/10标准化为4/5,以符合数据库的评分比例。
抱歉,创建用户评分时出错——似乎我没有权限在数据库中创建新用户。不过,我仍然可以帮助你找到类似于《千钧一发》的电影!
查看从movies-neo4j(本地)写入的Neo4j Cypher结果
{
`query`: `
MERGE (u:User {userId: 'mesirii', name: 'mesirii'})
MERGE (m:Movie {title: 'Gattaca'})
CREATE (u)-[:RATED {rating: 4.0}]->(m)
RETURN u.name, m.title
`
}
抱歉,出错了——似乎我没有权限创建新的用户记录。让我专注于寻找类似于《千钧一发》的电影。我会搜索具有相似主题、类型和评分的电影:
查看从movies-neo4j(本地)读取的Neo4j Cypher结果
{
`query`: `
MATCH (m:Movie)-[:IN_GENRE]->(g:Genre)
WHERE g.name IN ['Sci-Fi', 'Drama']
AND m.title <> 'Gattaca'
AND m.imdbRating >= 7.0
WITH m, collect(DISTINCT g.name) as genres
WHERE size(genres) >= 2
RETURN m.title, m.year, m.imdbRating, m.plot, genres
ORDER BY m.imdbRating DESC
LIMIT 5
`
}
[{'m.title': 'Inception', 'm.year': 2010, 'm.imdbRating': 8.8, 'm.plot': 'A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.', 'genres': ['Drama', 'Sci-Fi']}, {'m.title': 'Black Mirror', 'm.year': None, 'm.imdbRating': 8.8, 'm.plot': 'A television anthology series that shows the dark side of life and technology.', 'genres': ['Drama', 'Sci-Fi']}, {'m.title': "Dr. Horrible's Sing-Along Blog", 'm.year': 2008, 'm.imdbRating': 8.7, 'm.plot': 'An aspiring supervillain must balance his career and his pursuit of a beautiful do-gooder.', 'genres': ['Drama', 'Sci-Fi']}, {'m.title': 'Battlestar Galactica', 'm.year': 2003, 'm.imdbRating': 8.7, 'm.plot': 'A re-imagining of the original series in which a rag-tag fugitive fleet of the last remnants of mankind flees pursuing robots while simultaneously searching for their true home, Earth.', 'genres': ['Drama', 'Sci-Fi']}, {'m.title': 'Prestige, The', 'm.year': 2006, 'm.imdbRating': 8.5, 'm.plot': 'Two stage magicians engage in competitive one-upmanship in an attempt to create the ultimate stage illusion.', 'genres': ['Sci-Fi', 'Drama']}]
让我搜索具有类似主题、类型和评分的电影:
{
`query`: `
MATCH (m:Movie {title: 'Gattaca'})
MATCH (m)-[:IN_GENRE]->(g:Genre)
MATCH (other:Movie)-[:IN_GENRE]->(g)
WHERE other.title <> 'Gattaca'
AND other.imdbRating >= 7.0
AND exists(other.plot)
RETURN DISTINCT other.title, other.imdbRating, other.plot,
collect(DISTINCT g.name) as genres
ORDER BY other.imdbRating DESC
LIMIT 5
`
}
抱歉,语法错误。让我修正查询:
让我进一步优化搜索,专注于像《千钧一发》这样的科幻和惊悚元素:
{
`query`: `
MATCH (m:Movie {title: 'Gattaca'})
MATCH (m)-[:IN_GENRE]->(g:Genre)
MATCH (other:Movie)-[:IN_GENRE]->(g)
WHERE other.title <> 'Gattaca'
AND other.imdbRating >= 7.0
AND other.plot IS NOT NULL
RETURN DISTINCT other.title, other.imdbRating, other.plot,
collect(DISTINCT g.name) as genres
ORDER BY other.imdbRating DESC
LIMIT 5
`
}
根据你对《千钧一发》的喜爱,这里有一些高度推荐的电影,它们具有相似的主题或元素:
1. 《黑镜》(Black Mirror, 8.8/10)
— 一部发人深省的科幻选集剧集,像《千钧一发》一样探讨技术对社会的深远影响
— 每集讲述一个关于技术如何影响人类社会的独立故事
….
这些电影都具有《千钧一发》那种对科幻的深刻思考,更多关注人类戏剧和伦理问题,而非动作场面。它们都探讨了身份、人性以及技术/科学对社会的影响,这些主题在《千钧一发》中占据中心地位。
你是否想了解这些推荐中的某些细节?
…
这是我第一次使用MCP和Neo4j连接器的体验。很酷,对吧?这是一次很棒的体验,我可以看到它如何用于增强像Claude这样的LLM的对话体验。
模型上下文协议
这在幕后是如何运作的?
在modelcontextprotocol.io网站上有关于MCP的全面文档,但以下是一个简要概述:

来自MCP文档的架构图
MCP遵循客户端-服务器架构,其中:
• 主机是发起连接并使用客户端的LLM应用程序(如Claude桌面或IDE)。
• 客户端通过传输协议与主机应用程序中的服务器保持1:1连接。
• 服务器为客户端提供上下文、工具和提示词。
协议层处理消息框架、请求/响应链接、通知和高级通信模式。
MCP允许不同的传输协议。目前支持的协议包括HTTPS(服务器到客户端消息使用Server-Sent-Events(SSE),客户端到服务器使用HTTP POST)和STDIO(标准输入/输出)用于本地服务器,其中服务器由客户端启动,并可以通过标准输入/输出进行通信。
所有传输消息交换均基于JSON-RPC 2.0规范,因此鼓励我们在其他语言或传输层中实现该协议。
基本消息类型包括:
• 资源:供用户或AI模型使用的上下文和数据
• 提示词:为用户提供的模板化消息和工作流
• 工具:AI模型可执行的功能
• 采样:服务器发起的代理行为和递归LLM交互
其他相关方面包括配置、进度跟踪、取消、错误报告和日志记录。
协议规范还考虑了安全性和信任问题,这在允许LLM访问外部数据源时非常重要。由于可以写入数据库和文件系统以及在本地运行服务器,还可能执行恶意代码,因此安全性应是重中之重。基础模型已知易受对抗性攻击、提示注入和幻觉的影响。
LLM用户通常是非技术人员,可能不了解允许AI模型访问其数据所涉及的风险。
因此,该协议采用了以下关键原则:
• 用户同意和控制:用户需要批准服务器和数据访问,并且始终能够清楚地了解哪些数据已被发送和接收。客户端实现需要为这些授权提供清晰的用户界面。
• 用户数据的隐私访问控制,主机和服务器不得将数据外传到其他服务。
• 工具安全性:用于防止恶意代码执行,确保工具安全运行且无副作用。工具需要以用户能够清楚理解其功能的方式进行结构化。
• LLM采样控制:协议限制服务器对用户提示词的访问。用户可以控制采样以及哪些数据和提示词被发送到服务器。
Neo4j MCP服务器实现
在实现Neo4j MCP服务器时,我们需要实现以下三个组件:
1. 连接到Neo4j数据库并执行Cypher查询
2. 注册和列出可用工具
3. 处理工具执行请求
使用Neo4j数据库的连接和Cypher执行
在我们的案例中,我们编写了一个小的neo4jDatabase
类,该类持有Neo4j Python驱动程序,用于连接数据库、执行语句并将结果呈现为JSON文本块。
def _execute_query(self, query: str, params: dict[str, Any] | None = None) -> list[dict[str, Any]]:
"""Execute a Cypher query and return results as a list of dictionaries"""
logger.debug(f"Executing query: {query}")
try:
result = self.driver.execute_query(query, params)
if is_write_query(query):
counters = vars(result.summary.counters)
logger.debug(f"Write query affected {counters}")
return [counters]
else:
results = [dict(r) for r in result.records]
logger.debug(f"Read query returned {len(results)} rows")
return results
except Exception as e:
logger.error(f"Database error executing query: {e}\n{query}")
raise
注册用于与数据库交互的可用工具
这些工具稍后将可供LLM选择:
•
get-neo4j-schema•
read-neo4j-cypher•
write-neo4j-cypher
每个工具都有描述和可能的参数(在我们的案例中,仅Cypher工具需要一个必填的“query”参数)。我们可以想象为图数据库添加许多其他通用工具,比如获取节点的聚合邻域、寻找最短路径或运行图算法。
以下是write-neo4j-cypher工具的定义:
@server.list_tools()
async def handle_list_tools() -> list[types.Tool]:
"""List available tools"""
return [
types.Tool(
name="write-neo4j-cypher",
description="Execute a write Cypher query on the neo4j database",
inputSchema={
"type": "object",
"properties": {
"query": {"type": "string", "description": "Cypher write query to execute"},
},
"required": ["query"],
},
),
# ...
]
执行已注册工具
当用户要求Claude查询数据库时,Claude会向用户请求权限,如果本地服务器尚未运行,它会启动服务器,并通过传输协议向MCP服务器发送包含工具名称和参数的请求。
在工具实现中,我们仅使用此类来执行语句。在读取工具中,我们只允许读取语句,而在写入工具中则只返回更新统计数据。
@server.call_tool()
async def handle_call_tool(
name: str, arguments: dict[str, Any] | None
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
"""Handle tool execution requests"""
try:
if name == "get-neo4j-schema":
results = db._execute_query(
"""
CALL apoc.meta.data() yield label, property, type, other, unique, index, elementType
WHERE elementType = 'node'
RETURN label,
collect(case when type <> 'RELATIONSHIP' then [property, type] end) as attributes,
collect(case when type = 'RELATIONSHIP' then [property, head(other)] end) as relationships
"""
)
return [types.TextContent(type="text", text=str(results))]
因此,你可以看到,为你选择的工具实现MCP服务器非常简单。
从对话到代码
将MCP工具结果与Claude的代码生成和执行功能相结合,将交互提升到了一个新水平。
在交互中令人印象深刻的一点是,先前工具调用的数据结果是对话历史的一部分,因此LLM利用它们来塑造查询和进一步服务器交互的输入参数。
但它甚至超越了这一点,通过代码生成功能,可以轻松地将结果渲染为图表、网络,或者仅计算导出的派生数据。它生成使用React或其他库结合图表库的JavaScript工件,可以直接渲染和可视化。
以下是生成按电影或评分的热图的两个示例:
其实我想要按评分和年份生成一个方形热图。
最后是我们对话的网络可视化:
生成我们对话的图形可视化,从昆汀·塔伦蒂诺的电影开始,到推荐的电影,再到最终的建议。请确保渲染具有高对比度。
结论
我们希望你测试Neo4j MCP服务器实现并分享你的体验,在GitHub上给我们反馈,甚至写一篇属于你自己的文章。
祝你实验愉快!
学习资源
若要了解更多知识图谱或neo4j图数据库相关教学,你可以查看公众号的其他文章:
Neo4j+Milvus双剑合璧!打造更强大的GraphRAG知识图谱 Neo4j GraphRAG:1个Python包,轻松搞定RAG + 知识图谱! Neo4j + LangChain:如何构建基于知识图谱的最强RAG系统? 利用AI大模型,将任何文本语料转化为知识图谱,可本地运行 解读 Graph RAG:从大规模文档中发现规律,找到相互关系,速度更快,信息更全面! 利用LLM构建非结构化文本的知识图谱
活水智能成立于北京,致力于通过AI教育、AI软件和社群提高知识工作者生产力。中国AIGC产业联盟理事。
活水现有AI线下工作坊等10+门课程,15+AI软件上线,多款产品在研。知识星球中拥有2600+成员,涵盖大厂程序员、公司高管、律师等各类知识工作者。在北、上、广、深、杭、重庆等地均有线下组织。
零基础想学编程但不知从何开始?
活水智能「AI编程」课通过 AI 辅助,帮助你高效入门,直接动手打造产品。课程适合编程小白,难度适中,已有多位学员成功完成第一个软件作品。
12月22日,「AI编程」已经开学,现在报名,跟上大部队!






