示例笔记本你可以在 examples 代码库 中找到此示例的 notebook。
前置条件
- 你的系统中需要已安装 Python。
- 你的系统中需要已安装
pip。 - 你需要一个 Anthropic API 密钥,或其他 LLM 提供商的 API 密钥
1
安装库
运行以下命令,安装所需的库:
pip install -q --upgrade pip
pip install -q langchain-mcp-adapters langgraph "langchain[anthropic]"
2
配置凭据
接下来,您需要提供 Anthropic API 密钥:
import os, getpass
os.environ["ANTHROPIC_API_KEY"] = getpass.getpass("Enter Anthropic API Key:")
Response
Enter Anthropic API Key: ········
使用其他 LLM 提供商如果你没有 Anthropic API 密钥,但想使用其他 LLM 提供商,
可以在 Langchain Providers 文档 中找到配置凭据的说明。
3
初始化 MCP 服务器
现在配置 ClickHouse MCP 服务器,使其指向 ClickHouse SQL Playground:
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
server_params = StdioServerParameters(
command="uv",
args=[
"run",
"--with", "mcp-clickhouse",
"--python", "3.13",
"mcp-clickhouse"
],
env={
"CLICKHOUSE_HOST": "sql-clickhouse.clickhouse.com",
"CLICKHOUSE_PORT": "8443",
"CLICKHOUSE_USER": "demo",
"CLICKHOUSE_PASSWORD": "",
"CLICKHOUSE_SECURE": "true"
}
)
4
配置 stream handler
使用 Langchain 和 ClickHouse MCP 服务器时,查询结果通常会
以流式数据的形式返回,而不是一次性返回单个响应。对于大型数据集或
处理起来可能需要一些时间的复杂分析查询,配置
stream handler 非常重要。如果没有妥善处理,这类流式输出
在应用程序中可能会难以使用。为流式输出配置 handler,以便更容易处理:
class UltraCleanStreamHandler:
def __init__(self):
self.buffer = ""
self.in_text_generation = False
self.last_was_tool = False
def handle_chunk(self, chunk):
event = chunk.get("event", "")
if event == "on_chat_model_stream":
data = chunk.get("data", {})
chunk_data = data.get("chunk", {})
# Only handle actual text content, skip tool invocation streams
if hasattr(chunk_data, 'content'):
content = chunk_data.content
if isinstance(content, str) and not content.startswith('{"'):
# Add space after tool completion if needed
if self.last_was_tool:
print(" ", end="", flush=True)
self.last_was_tool = False
print(content, end="", flush=True)
self.in_text_generation = True
elif isinstance(content, list):
for item in content:
if (isinstance(item, dict) and
item.get('type') == 'text' and
'partial_json' not in str(item)):
text = item.get('text', '')
if text and not text.startswith('{"'):
# Add space after tool completion if needed
if self.last_was_tool:
print(" ", end="", flush=True)
self.last_was_tool = False
print(text, end="", flush=True)
self.in_text_generation = True
elif event == "on_tool_start":
if self.in_text_generation:
print(f"\n🔧 {chunk.get('name', 'tool')}", end="", flush=True)
self.in_text_generation = False
elif event == "on_tool_end":
print(" ✅", end="", flush=True)
self.last_was_tool = True
5
调用 agent
最后,调用你的 agent,并问它是谁向 ClickHouse 提交了最多的代码:你应该会看到如下所示的类似响应:
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await load_mcp_tools(session)
agent = create_react_agent("anthropic:claude-sonnet-4-0", tools)
handler = UltraCleanStreamHandler()
async for chunk in agent.astream_events(
{"messages": [{"role": "user", "content": "Who's committed the most code to ClickHouse?"}]},
version="v1"
):
handler.handle_chunk(chunk)
print("\n")
Response
I'll help you find who has committed the most code to ClickHouse by exploring the available databases and tables to locate git commit data.
🔧 list_databases ✅ I can see there's a `git` database which likely contains git commit information. Let me explore the tables in that database:
🔧 list_tables ✅ Perfect! I can see the `clickhouse_commits` table in the git database contains ClickHouse commit data with 80,644 commits. This table has information about each commit including the author, lines added/deleted, files modified, etc. Let me query this table to find who has committed the most code based on different metrics.
🔧 run_select_query ✅ Let me also look at just the lines added to see who has contributed the most new code:
🔧 run_select_query ✅ Based on the ClickHouse git commit data, **Alexey Milovidov** has committed the most code to ClickHouse by several measures:
## Key Statistics:
1. **Most Total Lines Changed**: Alexey Milovidov with **1,696,929 total lines changed** (853,049 added + 843,880 deleted)
2. **Most Lines Added**: Alexey Milovidov with **853,049 lines added**
3. **Most Commits**: Alexey Milovidov with **15,375 commits**
4. **Most Files Changed**: Alexey Milovidov with **73,529 files changed**
## Top Contributors by Lines Added:
1. **Alexey Milovidov**: 853,049 lines added (15,375 commits)
2. **s-kat**: 541,609 lines added (50 commits)
3. **Nikolai Kochetov**: 219,020 lines added (4,218 commits)
4. **alesapin**: 193,566 lines added (4,783 commits)
5. **Vitaly Baranov**: 168,807 lines added (1,152 commits)
Alexey Milovidov is clearly the most prolific contributor to ClickHouse, which makes sense as he is one of the original creators and lead developers of the project. His contribution dwarfs others both in terms of total code volume and number of commits, with nearly 16,000 commits and over 850,000 lines of code added to the project.