内容
# pyroscope-mcp
一款只读的 [模型上下文协议](https://modelcontextprotocol.io/)(MCP)服务器,适用于 [Grafana Pyroscope](https://grafana.com/oss/pyroscope/)。允许 AI 助手直接从任何与 MCP 兼容的客户端查询连续性能数据 — 火焰图、热点函数、内存分配、标签发现。
> **注意:** 该服务器仅支持查询。性能数据摄入应由您的应用程序性能分析工具(Pyroscope SDK、代理或导出器)处理。
## 工具列表
| 工具 | 描述 |
|------|-------------|
| `pyroscope_render_profile` | 火焰图 + 时间线数据,来自 `/pyroscope/render` |
| `pyroscope_label_names` | 列出时间范围内的所有标签名称 |
| `pyroscope_label_values` | 列出给定标签的值(例如 `service_name`) |
| `pyroscope_profile_types` | 列出可用的性能数据类型(cpu、内存、goroutines…) |
| `pyroscope_series` | 为选择器获取匹配的标签集 |
| `pyroscope_connect_query` | 原始访问任意 `/querier.v1.QuerierService/*` 端点 |
## 前置条件
- Node.js 20+
- 运行中的 Pyroscope 实例(本地、自行托管或 Grafana Cloud)
## 安装配置
```bash
git clone https://github.com/your-org/pyroscope-mcp
cd pyroscope-mcp
npm install
npm run build
```
## 配置
所有设置均通过环境变量提供:
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `PYROSCOPE_BASE_URL` | `http://localhost:4040` | Pyroscope 服务器 URL |
| `PYROSCOPE_AUTH_TOKEN` | — | Bearer token(Grafana Cloud 或 Azure AD) |
| `PYROSCOPE_TENANT_ID` | — | 多租户组织 ID(`X-Scope-OrgID` 头部) |
| `PYROSCOPE_TIMEOUT_MS` | `30000` | 请求超时毫秒数 |
复制 `.env.example` 到 `.env` 并填写您的值:
```bash
cp .env.example .env
```
---
## 添加到 MCP 客户端
### VS Code(GitHub Copilot)
在工作区中创建或编辑 `.vscode/mcp.json`:
```json
{
"servers": {
"pyroscope": {
"type": "stdio",
"command": "node",
"args": ["${workspaceFolder}/dist/index.js"],
"env": {
"PYROSCOPE_BASE_URL": "http://localhost:4040"
}
}
}
}
```
然后在 VS Code 中打开 **MCP: List Servers** 命令(`Cmd+Shift+P`)并启动服务器。Copilot Chat 将自动发现这些工具。
对于全局(用户级)配置而不是每个工作区,请在 VS Code 的 `settings.json` 中的 `"mcp"` 下添加相同的块:
```json
{
"mcp": {
"servers": {
"pyroscope": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/pyroscope-mcp/dist/index.js"],
"env": {
"PYROSCOPE_BASE_URL": "http://localhost:4040"
}
}
}
}
}
```
---
### Claude Desktop
编辑 `~/Library/Application Support/Claude/claude_desktop_config.json`(macOS)或 `%APPDATA%\Claude\claude_desktop_config.json`(Windows):
```json
{
"mcpServers": {
"pyroscope": {
"command": "node",
"args": ["/absolute/path/to/pyroscope-mcp/dist/index.js"],
"env": {
"PYROSCOPE_BASE_URL": "http://localhost:4040",
"PYROSCOPE_AUTH_TOKEN": ""
}
}
}
}
```
重启 Claude Desktop。当服务器激活时,聊天输入中会出现一个锤子图标。
在 **Windows** 上,包装命令:
```json
{
"mcpServers": {
"pyroscope": {
"command": "cmd",
"args": ["/c", "node", "C:\\path\\to\\pyroscope-mcp\\dist\\index.js"],
"env": {
"PYROSCOPE_BASE_URL": "http://localhost:4040"
}
}
}
}
```
---
### Cursor
打开 **Cursor Settings → MCP** 并添加新的服务器条目,或编辑 `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"pyroscope": {
"command": "node",
"args": ["/absolute/path/to/pyroscope-mcp/dist/index.js"],
"env": {
"PYROSCOPE_BASE_URL": "http://localhost:4040"
}
}
}
}
```
重新加载 Cursor。Composer 代理上下文中会自动出现这些工具。
---
### Zed
添加到您的 Zed `settings.json`(通过 **Zed → Settings** 打开):
```json
{
"context_servers": {
"pyroscope": {
"command": {
"path": "node",
"args": ["/absolute/path/to/pyroscope-mcp/dist/index.js"],
"env": {
"PYROSCOPE_BASE_URL": "http://localhost:4040"
}
}
}
}
}
```
---
### 任意 MCP 兼容客户端(通用 stdio 配置)
```json
{
"mcpServers": {
"pyroscope": {
"command": "node",
"args": ["/absolute/path/to/pyroscope-mcp/dist/index.js"],
"env": {
"PYROSCOPE_BASE_URL": "http://localhost:4040",
"PYROSCOPE_AUTH_TOKEN": "your-bearer-token-if-needed",
"PYROSCOPE_TENANT_ID": "your-org-id-if-needed"
}
}
}
}
```
---
## 连接后示例提示
- *"列出过去一小时内发送性能数据的所有服务。"*
- *"显示 `media-agent` 在过去 30 分钟内的最热 CPU 函数。"*
- *" `api-gateway` 的内存分配热点是什么?"*
- *"比较 `worker-service` 和 `data-pipeline` 之间的 CPU 使用情况。"*
- *" `checkout-api` 有哪些可用的性能数据类型?"*
---
## 备注
- 对于多租户 Pyroscope,请设置 `PYROSCOPE_TENANT_ID` 或通过工具调用传递 `tenantId`。
- `pyroscope_connect_query` 提供对高级端点的原始访问:
- `/querier.v1.QuerierService/SelectMergeStacktraces`
- `/querier.v1.QuerierService/SelectSeries`
- `/querier.v1.QuerierService/Diff`
- 对于 Grafana Cloud Pyroscope,请将 `PYROSCOPE_BASE_URL` 设置为您的堆栈 URL,并将 `PYROSCOPE_AUTH_TOKEN` 设置为服务帐户令牌。
---
## 查询烟雾测试
1. 在本地启动 Pyroscope:
```bash
docker run -d --name pyroscope -p 4040:4040 grafana/pyroscope:latest
```
2. 查询过去一小时的标签名称:
```bash
NOW_MS=$(($(date +%s)*1000))
START_MS=$((NOW_MS-3600000))
curl -sS -H 'Content-Type: application/json' \
-d "{\"start\":$START_MS,\"end\":$NOW_MS}" \
http://localhost:4040/querier.v1.QuerierService/LabelNames
```
3. 查询过去一小时的服务名称:
```bash
NOW_MS=$(($(date +%s)*1000))
START_MS=$((NOW_MS-3600000))
curl -sS -H 'Content-Type: application/json' \
-d "{\"name\":\"service_name\",\"start\":$START_MS,\"end\":$NOW_MS}" \
http://localhost:4040/querier.v1.QuerierService/LabelValues
```