@infinitedusky/indusk-mcp 1.10.1 → 1.10.3
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/dist/lib/config.d.ts +18 -2
- package/dist/lib/config.js +21 -3
- package/extensions/dash0/skill.md +22 -12
- package/package.json +1 -1
package/dist/lib/config.d.ts
CHANGED
|
@@ -44,12 +44,28 @@ export declare function getConfigPath(projectRoot: string): string;
|
|
|
44
44
|
export declare function readConfig(projectRoot: string): InduskConfig | null;
|
|
45
45
|
export declare function writeConfig(projectRoot: string, config: InduskConfig): void;
|
|
46
46
|
export declare function getPlanningDir(projectRoot: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Sanitize a string into a valid Graphiti group id.
|
|
49
|
+
*
|
|
50
|
+
* Graphiti uses RediSearch under the hood, which treats `-` as a token separator.
|
|
51
|
+
* A query like `chitin-sportsbook` parses as "find chitin, exclude sportsbook" and
|
|
52
|
+
* fails with `Syntax error at offset N near chitin`. Anything that isn't
|
|
53
|
+
* `[A-Za-z0-9_]` gets replaced with `_`. Multiple separators collapse to one.
|
|
54
|
+
*
|
|
55
|
+
* Examples:
|
|
56
|
+
* "chitin-sportsbook" → "chitin_sportsbook"
|
|
57
|
+
* "my.cool.project" → "my_cool_project"
|
|
58
|
+
* "@scope/pkg" → "scope_pkg"
|
|
59
|
+
* "indusk_already_ok" → "indusk_already_ok" (no change)
|
|
60
|
+
*/
|
|
61
|
+
export declare function sanitizeGroupId(raw: string): string;
|
|
47
62
|
/**
|
|
48
63
|
* Get the Graphiti group id for project-specific episodes.
|
|
49
64
|
*
|
|
50
65
|
* Resolution order:
|
|
51
|
-
* 1. .indusk/config.json `graphiti.groupId` if set
|
|
52
|
-
*
|
|
66
|
+
* 1. .indusk/config.json `graphiti.groupId` if set (used as-is, not sanitized —
|
|
67
|
+
* explicit overrides are trusted; if you set a hyphenated id, that's on you)
|
|
68
|
+
* 2. Sanitized project directory basename (`-` → `_`, etc., for RediSearch safety)
|
|
53
69
|
*
|
|
54
70
|
* Use `[getProjectGroupId(root), "shared"]` as the default group_ids list when
|
|
55
71
|
* searching Graphiti — this gives both project-scoped and cross-project knowledge.
|
package/dist/lib/config.js
CHANGED
|
@@ -26,12 +26,30 @@ export function getPlanningDir(projectRoot) {
|
|
|
26
26
|
// Default to new path (will be created by init)
|
|
27
27
|
return newPath;
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Sanitize a string into a valid Graphiti group id.
|
|
31
|
+
*
|
|
32
|
+
* Graphiti uses RediSearch under the hood, which treats `-` as a token separator.
|
|
33
|
+
* A query like `chitin-sportsbook` parses as "find chitin, exclude sportsbook" and
|
|
34
|
+
* fails with `Syntax error at offset N near chitin`. Anything that isn't
|
|
35
|
+
* `[A-Za-z0-9_]` gets replaced with `_`. Multiple separators collapse to one.
|
|
36
|
+
*
|
|
37
|
+
* Examples:
|
|
38
|
+
* "chitin-sportsbook" → "chitin_sportsbook"
|
|
39
|
+
* "my.cool.project" → "my_cool_project"
|
|
40
|
+
* "@scope/pkg" → "scope_pkg"
|
|
41
|
+
* "indusk_already_ok" → "indusk_already_ok" (no change)
|
|
42
|
+
*/
|
|
43
|
+
export function sanitizeGroupId(raw) {
|
|
44
|
+
return raw.replace(/[^A-Za-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
45
|
+
}
|
|
29
46
|
/**
|
|
30
47
|
* Get the Graphiti group id for project-specific episodes.
|
|
31
48
|
*
|
|
32
49
|
* Resolution order:
|
|
33
|
-
* 1. .indusk/config.json `graphiti.groupId` if set
|
|
34
|
-
*
|
|
50
|
+
* 1. .indusk/config.json `graphiti.groupId` if set (used as-is, not sanitized —
|
|
51
|
+
* explicit overrides are trusted; if you set a hyphenated id, that's on you)
|
|
52
|
+
* 2. Sanitized project directory basename (`-` → `_`, etc., for RediSearch safety)
|
|
35
53
|
*
|
|
36
54
|
* Use `[getProjectGroupId(root), "shared"]` as the default group_ids list when
|
|
37
55
|
* searching Graphiti — this gives both project-scoped and cross-project knowledge.
|
|
@@ -40,7 +58,7 @@ export function getProjectGroupId(projectRoot) {
|
|
|
40
58
|
const config = readConfig(projectRoot);
|
|
41
59
|
if (config?.graphiti?.groupId)
|
|
42
60
|
return config.graphiti.groupId;
|
|
43
|
-
return basename(projectRoot);
|
|
61
|
+
return sanitizeGroupId(basename(projectRoot));
|
|
44
62
|
}
|
|
45
63
|
/**
|
|
46
64
|
* Whether the OTel gate should fire for this project.
|
|
@@ -65,14 +65,22 @@ The MCP server provides 23 tools. The key ones for debugging:
|
|
|
65
65
|
- **`getFailedChecks`** / **`getFailedCheckDetails`** — View check failures
|
|
66
66
|
- **`searchKnowledgeBase`** — Search Dash0 documentation
|
|
67
67
|
|
|
68
|
-
### MCP Usage Pattern
|
|
68
|
+
### MCP Usage Pattern — Traces First
|
|
69
|
+
|
|
70
|
+
**Always start with spans.** Logs are correlated with traces, so finding the right trace first helps you find the right logs — not the other way around.
|
|
71
|
+
|
|
69
72
|
```
|
|
70
|
-
1.
|
|
71
|
-
2.
|
|
72
|
-
3.
|
|
73
|
-
4.
|
|
73
|
+
1. getSpans (last 30s, no filters) → scan recent spans for anything matching your investigation
|
|
74
|
+
2. Found a relevant span? → getTraceDetails to see the full request chain
|
|
75
|
+
3. Use trace/span IDs to find correlated logs → getLogRecords with traceId filter
|
|
76
|
+
4. getFullLogRecord → drill into a specific log for all attributes
|
|
74
77
|
```
|
|
75
78
|
|
|
79
|
+
**Why traces first:**
|
|
80
|
+
- Spans show the full request lifecycle — what happened, how long, what called what
|
|
81
|
+
- Logs are attached to spans via trace context — the trace tells you which logs matter
|
|
82
|
+
- Starting with logs means guessing at filters; starting with spans gives you the map
|
|
83
|
+
|
|
76
84
|
## When to Use MCP vs CLI
|
|
77
85
|
|
|
78
86
|
| Task | Use |
|
|
@@ -83,7 +91,7 @@ The MCP server provides 23 tools. The key ones for debugging:
|
|
|
83
91
|
| Get full trace hierarchy | MCP `getTraceDetails` (preferred) |
|
|
84
92
|
| Run PromQL metrics query | Either — MCP for simple, CLI for complex |
|
|
85
93
|
| Deploy dashboard from YAML | CLI (`dash0 apply -f`) |
|
|
86
|
-
| Diagnose a failing service | MCP `
|
|
94
|
+
| Diagnose a failing service | MCP `getSpans` (last 30s) → `getTraceDetails` → `getLogRecords` (by traceId) |
|
|
87
95
|
| CI/CD observability checks | CLI (scriptable, agent mode) |
|
|
88
96
|
| Discover available attributes | MCP `getAttributeKeys` / `getAttributeValues` |
|
|
89
97
|
|
|
@@ -178,14 +186,16 @@ The CLI auto-detects Claude Code sessions and switches to agent mode (JSON outpu
|
|
|
178
186
|
|
|
179
187
|
### During verification
|
|
180
188
|
When a verification step involves checking that a service is working correctly, don't just check the HTTP status — query Dash0 for:
|
|
181
|
-
- Recent
|
|
182
|
-
-
|
|
189
|
+
- **Recent spans first**: use MCP `getSpans` with a short time range (last 30s) to see what the service just did — look for errors, slow spans, or missing expected operations
|
|
190
|
+
- **Then correlated logs**: once you have a trace ID from a relevant span, use `getLogRecords` filtered by that trace ID to see exactly what happened during that request
|
|
191
|
+
- **Only use broad log queries as a fallback** if no spans are present (e.g., the service isn't instrumented yet)
|
|
183
192
|
|
|
184
193
|
### During debugging
|
|
185
194
|
When something fails:
|
|
186
|
-
1.
|
|
187
|
-
2.
|
|
188
|
-
3.
|
|
195
|
+
1. **Get recent spans first** — use MCP `getSpans` with a short time range (last 30s–1m). Don't filter yet — scan the results for spans matching what you're investigating.
|
|
196
|
+
2. **Drill into the trace** — found a relevant span? Use `getTraceDetails` to see the full request chain, timing, errors, and hierarchy.
|
|
197
|
+
3. **Find correlated logs** — use the trace ID from step 2 to query `getLogRecords` with a `traceId` filter. This gives you exactly the logs tied to that request, no guessing.
|
|
198
|
+
4. **Check metrics** — is this a new problem or an existing one? Compare error rates over time.
|
|
189
199
|
|
|
190
200
|
### During retrospective
|
|
191
201
|
Query Dash0 for metrics that show the impact of the plan:
|
|
@@ -201,5 +211,5 @@ Dash0 ingests standard OpenTelemetry data. If your services already export OTLP
|
|
|
201
211
|
|
|
202
212
|
- **CLI `--experimental` required**: All query commands (logs, traces, metrics) require the `--experimental` flag. This will change when these commands become stable.
|
|
203
213
|
- **Default time range is narrow**: Always specify `--from` when querying logs. Without it, you may get empty results.
|
|
204
|
-
- **
|
|
214
|
+
- **CLI has no trace search**: The CLI can only fetch traces by ID (`traces get <id>`), not search for them. Use the MCP `getSpans` tool to search spans — it supports filters and time ranges. The CLI requires you to already have a trace ID.
|
|
205
215
|
- **Profile auth may not load in Claude Code shell**: Run `source ~/.zshrc` before `dash0` commands if auth fails.
|