cubeapm-mcp 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/dist/index.js +160 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/cubeapm-mcp)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://lobehub.com/mcp/technicalrhino-cubeapm-mcp)
|
|
5
6
|
|
|
6
7
|
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for [CubeAPM](https://cubeapm.com) - enabling AI assistants like Claude to query your observability data including traces, metrics, and logs.
|
|
7
8
|
|
|
@@ -180,6 +181,30 @@ You can now ask Claude questions like:
|
|
|
180
181
|
|------|-------------|
|
|
181
182
|
| `ingest_metrics_prometheus` | Send metrics in Prometheus text exposition format |
|
|
182
183
|
|
|
184
|
+
## Prompts
|
|
185
|
+
|
|
186
|
+
Pre-defined templates for common observability tasks:
|
|
187
|
+
|
|
188
|
+
| Prompt | Description |
|
|
189
|
+
|--------|-------------|
|
|
190
|
+
| `investigate-service` | Comprehensive service investigation - checks errors, latency, and traces |
|
|
191
|
+
| `check-latency` | Get P50, P95, P99 latency percentiles for a service |
|
|
192
|
+
| `find-slow-traces` | Find slowest traces to identify performance bottlenecks |
|
|
193
|
+
|
|
194
|
+
**Usage Example:**
|
|
195
|
+
```
|
|
196
|
+
Use the investigate-service prompt for Kratos-Prod
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Resources
|
|
200
|
+
|
|
201
|
+
Readable resources exposing CubeAPM data and configuration:
|
|
202
|
+
|
|
203
|
+
| Resource URI | Description |
|
|
204
|
+
|--------------|-------------|
|
|
205
|
+
| `cubeapm://config` | Current CubeAPM connection configuration |
|
|
206
|
+
| `cubeapm://query-patterns` | Query patterns and naming conventions reference |
|
|
207
|
+
|
|
183
208
|
## CubeAPM Query Patterns
|
|
184
209
|
|
|
185
210
|
### Metrics Naming Conventions
|
package/dist/index.js
CHANGED
|
@@ -319,6 +319,166 @@ server.tool("ingest_metrics_prometheus", "Send metrics to CubeAPM in Prometheus
|
|
|
319
319
|
],
|
|
320
320
|
};
|
|
321
321
|
});
|
|
322
|
+
// ============================================
|
|
323
|
+
// PROMPTS - Pre-defined templates for common tasks
|
|
324
|
+
// ============================================
|
|
325
|
+
server.prompt("investigate-service", "Investigate issues with a specific service - checks errors, latency, and recent traces", {
|
|
326
|
+
service: z.string().describe("The service name to investigate (case-sensitive)"),
|
|
327
|
+
timeRange: z.string().optional().default("1h").describe("Time range to look back (e.g., 1h, 6h, 24h)"),
|
|
328
|
+
}, async ({ service, timeRange }) => {
|
|
329
|
+
return {
|
|
330
|
+
messages: [
|
|
331
|
+
{
|
|
332
|
+
role: "user",
|
|
333
|
+
content: {
|
|
334
|
+
type: "text",
|
|
335
|
+
text: `Please investigate the ${service} service for the last ${timeRange}:
|
|
336
|
+
|
|
337
|
+
1. First, check the error rate using metrics:
|
|
338
|
+
- Query: sum(increase(cube_apm_calls_total{service="${service}", status_code="ERROR"}[${timeRange}])) / sum(increase(cube_apm_calls_total{service="${service}"}[${timeRange}])) * 100
|
|
339
|
+
|
|
340
|
+
2. Check P95 latency:
|
|
341
|
+
- Query: histogram_quantiles("phi", 0.95, sum by (vmrange) (increase(cube_apm_latency_bucket{service="${service}", span_kind="server"}[5m])))
|
|
342
|
+
|
|
343
|
+
3. Search for error traces:
|
|
344
|
+
- Use search_traces with service="${service}", query="status_code=ERROR"
|
|
345
|
+
|
|
346
|
+
4. Check recent logs if available:
|
|
347
|
+
- Query logs with {service_name="${service}"} or discover labels first with *
|
|
348
|
+
|
|
349
|
+
Summarize any issues found and provide recommendations.`,
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
],
|
|
353
|
+
};
|
|
354
|
+
});
|
|
355
|
+
server.prompt("check-latency", "Check P50, P95, and P99 latency percentiles for a service", {
|
|
356
|
+
service: z.string().describe("The service name (case-sensitive)"),
|
|
357
|
+
}, async ({ service }) => {
|
|
358
|
+
return {
|
|
359
|
+
messages: [
|
|
360
|
+
{
|
|
361
|
+
role: "user",
|
|
362
|
+
content: {
|
|
363
|
+
type: "text",
|
|
364
|
+
text: `Check the latency percentiles for ${service} service:
|
|
365
|
+
|
|
366
|
+
Use query_metrics_instant with these queries:
|
|
367
|
+
|
|
368
|
+
1. P50 (median):
|
|
369
|
+
histogram_quantiles("phi", 0.5, sum by (vmrange, service) (increase(cube_apm_latency_bucket{service="${service}", span_kind="server"}[5m])))
|
|
370
|
+
|
|
371
|
+
2. P95:
|
|
372
|
+
histogram_quantiles("phi", 0.95, sum by (vmrange, service) (increase(cube_apm_latency_bucket{service="${service}", span_kind="server"}[5m])))
|
|
373
|
+
|
|
374
|
+
3. P99:
|
|
375
|
+
histogram_quantiles("phi", 0.99, sum by (vmrange, service) (increase(cube_apm_latency_bucket{service="${service}", span_kind="server"}[5m])))
|
|
376
|
+
|
|
377
|
+
Note: Latency values are in SECONDS (multiply by 1000 for milliseconds).
|
|
378
|
+
|
|
379
|
+
Present the results in a clear table format.`,
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
};
|
|
384
|
+
});
|
|
385
|
+
server.prompt("find-slow-traces", "Find the slowest traces for a service to identify performance bottlenecks", {
|
|
386
|
+
service: z.string().describe("The service name (case-sensitive)"),
|
|
387
|
+
minDuration: z.string().optional().default("1s").describe("Minimum duration to filter (e.g., 500ms, 1s, 2s)"),
|
|
388
|
+
}, async ({ service, minDuration }) => {
|
|
389
|
+
return {
|
|
390
|
+
messages: [
|
|
391
|
+
{
|
|
392
|
+
role: "user",
|
|
393
|
+
content: {
|
|
394
|
+
type: "text",
|
|
395
|
+
text: `Find slow traces for ${service} service (minimum duration: ${minDuration}):
|
|
396
|
+
|
|
397
|
+
1. Search for traces using search_traces with:
|
|
398
|
+
- service: "${service}"
|
|
399
|
+
- sortBy: "duration"
|
|
400
|
+
- spanKind: "server"
|
|
401
|
+
- limit: 10
|
|
402
|
+
|
|
403
|
+
2. For the slowest trace found, use get_trace to fetch the full trace details
|
|
404
|
+
|
|
405
|
+
3. Analyze the trace waterfall to identify:
|
|
406
|
+
- Which span took the longest
|
|
407
|
+
- Any external dependencies causing delays
|
|
408
|
+
- Database queries or API calls that are slow
|
|
409
|
+
|
|
410
|
+
Provide a summary of performance bottlenecks and recommendations.`,
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
],
|
|
414
|
+
};
|
|
415
|
+
});
|
|
416
|
+
// ============================================
|
|
417
|
+
// RESOURCES - Expose CubeAPM data as readable resources
|
|
418
|
+
// ============================================
|
|
419
|
+
server.resource("config", "cubeapm://config", {
|
|
420
|
+
description: "Current CubeAPM connection configuration",
|
|
421
|
+
mimeType: "application/json",
|
|
422
|
+
}, async () => {
|
|
423
|
+
return {
|
|
424
|
+
contents: [
|
|
425
|
+
{
|
|
426
|
+
uri: "cubeapm://config",
|
|
427
|
+
mimeType: "application/json",
|
|
428
|
+
text: JSON.stringify({
|
|
429
|
+
queryUrl: queryBaseUrl,
|
|
430
|
+
ingestUrl: ingestBaseUrl,
|
|
431
|
+
usingFullUrl: !!CUBEAPM_URL,
|
|
432
|
+
host: CUBEAPM_HOST,
|
|
433
|
+
queryPort: CUBEAPM_QUERY_PORT,
|
|
434
|
+
ingestPort: CUBEAPM_INGEST_PORT,
|
|
435
|
+
}, null, 2),
|
|
436
|
+
},
|
|
437
|
+
],
|
|
438
|
+
};
|
|
439
|
+
});
|
|
440
|
+
server.resource("query-patterns", "cubeapm://query-patterns", {
|
|
441
|
+
description: "CubeAPM-specific query patterns and naming conventions",
|
|
442
|
+
mimeType: "text/markdown",
|
|
443
|
+
}, async () => {
|
|
444
|
+
return {
|
|
445
|
+
contents: [
|
|
446
|
+
{
|
|
447
|
+
uri: "cubeapm://query-patterns",
|
|
448
|
+
mimeType: "text/markdown",
|
|
449
|
+
text: `# CubeAPM Query Patterns
|
|
450
|
+
|
|
451
|
+
## Metrics Naming Conventions
|
|
452
|
+
- Prefix: \`cube_apm_*\` (e.g., cube_apm_calls_total, cube_apm_latency_bucket)
|
|
453
|
+
- Service label: \`service\` (NOT "server" or "service_name")
|
|
454
|
+
- Common labels: env, service, span_kind, status_code, http_code
|
|
455
|
+
|
|
456
|
+
## Histogram Queries (Percentiles)
|
|
457
|
+
CubeAPM uses VictoriaMetrics-style histograms with \`vmrange\` label:
|
|
458
|
+
|
|
459
|
+
\`\`\`promql
|
|
460
|
+
# P95 Latency
|
|
461
|
+
histogram_quantiles("phi", 0.95, sum by (vmrange, service) (
|
|
462
|
+
increase(cube_apm_latency_bucket{service="MyService", span_kind="server"}[5m])
|
|
463
|
+
))
|
|
464
|
+
\`\`\`
|
|
465
|
+
|
|
466
|
+
Note: Latency values are in SECONDS (0.05 = 50ms)
|
|
467
|
+
|
|
468
|
+
## Logs (LogsQL)
|
|
469
|
+
- Use \`*\` to discover available labels
|
|
470
|
+
- Lambda logs: \`{faas.name="my-function"}\`
|
|
471
|
+
- Service logs: \`{service_name="my-service"}\`
|
|
472
|
+
|
|
473
|
+
## Traces
|
|
474
|
+
- query, env, service are REQUIRED parameters
|
|
475
|
+
- Use \`sortBy=duration\` to find slow traces
|
|
476
|
+
- Filter by spanKind: server, client, consumer, producer
|
|
477
|
+
`,
|
|
478
|
+
},
|
|
479
|
+
],
|
|
480
|
+
};
|
|
481
|
+
});
|
|
322
482
|
// Start the server
|
|
323
483
|
async function main() {
|
|
324
484
|
const transport = new StdioServerTransport();
|
package/package.json
CHANGED