trace-mcp 0.1.0 → 1.0.10
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 +267 -172
- package/dist/cli.js +48577 -17626
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +570 -7
- package/dist/index.js +21389 -4742
- package/dist/index.js.map +1 -1
- package/hooks/trace-mcp-guard.sh +142 -0
- package/hooks/trace-mcp-reindex.sh +45 -0
- package/package.json +11 -3
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# trace-mcp-guard v0.1.0
|
|
3
|
+
# trace-mcp PreToolUse guard
|
|
4
|
+
# Blocks Read/Grep/Glob/Bash on source code files → redirects to trace-mcp tools.
|
|
5
|
+
# Allows: non-code files, Read before Edit, safe Bash commands (git, npm, build, test).
|
|
6
|
+
#
|
|
7
|
+
# Install: add to ~/.claude/settings.json or .claude/settings.local.json
|
|
8
|
+
# See README.md for setup instructions.
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
INPUT=$(cat)
|
|
13
|
+
TOOL_NAME="${CLAUDE_TOOL_NAME:-$(echo "$INPUT" | jq -r '.tool_name // empty')}"
|
|
14
|
+
|
|
15
|
+
# Code file extensions to guard
|
|
16
|
+
CODE_EXT_RE='\.(ts|tsx|js|jsx|mjs|cjs|py|pyi|go|rs|java|kt|kts|rb|php|cs|cpp|c|h|hpp|swift|scala|vue|svelte|astro|blade\.php)$'
|
|
17
|
+
|
|
18
|
+
# Non-code extensions — always allow
|
|
19
|
+
NONCODE_EXT_RE='\.(md|json|jsonc|yaml|yml|toml|ini|cfg|env|txt|html|xml|csv|svg|lock|log|sh|bash|zsh|fish|ps1|bat|cmd|dockerfile|dockerignore|gitignore|gitattributes|editorconfig|prettierrc|eslintrc|stylelintrc)$'
|
|
20
|
+
|
|
21
|
+
# Safe bash command prefixes — never block
|
|
22
|
+
SAFE_BASH_RE='^(git |npm |npx |pnpm |yarn |bun |node |deno |cargo |go |make |mvn |gradle |docker |kubectl |helm |terraform |pip |poetry |uv |pytest |vitest |jest |phpunit |composer |artisan |rails |bundle |mix |dotnet |cmake |ninja |meson )'
|
|
23
|
+
|
|
24
|
+
deny() {
|
|
25
|
+
local reason="$1"
|
|
26
|
+
local context="$2"
|
|
27
|
+
cat <<EOF
|
|
28
|
+
{
|
|
29
|
+
"hookSpecificOutput": {
|
|
30
|
+
"hookEventName": "PreToolUse",
|
|
31
|
+
"permissionDecision": "deny",
|
|
32
|
+
"permissionDecisionReason": "$reason",
|
|
33
|
+
"additionalContext": "$context"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
EOF
|
|
37
|
+
exit 0
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Track denied reads — allow on second attempt (agent needs it for Edit)
|
|
41
|
+
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "default"')
|
|
42
|
+
DENY_DIR="/tmp/trace-mcp-guard-${SESSION_ID}"
|
|
43
|
+
mkdir -p "$DENY_DIR" 2>/dev/null
|
|
44
|
+
|
|
45
|
+
# --- Read ---
|
|
46
|
+
if [[ "$TOOL_NAME" == "Read" ]]; then
|
|
47
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
|
48
|
+
|
|
49
|
+
# Allow non-code files
|
|
50
|
+
if echo "$FILE_PATH" | grep -qiE "$NONCODE_EXT_RE"; then
|
|
51
|
+
exit 0
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Allow files outside source dirs (configs in root, etc.)
|
|
55
|
+
BASENAME=$(basename "$FILE_PATH")
|
|
56
|
+
if [[ "$BASENAME" != *.* ]] || echo "$FILE_PATH" | grep -qE '(node_modules|vendor|dist|build|\.git)/'; then
|
|
57
|
+
exit 0
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Block code file reads → redirect to trace-mcp
|
|
61
|
+
if echo "$FILE_PATH" | grep -qiE "$CODE_EXT_RE"; then
|
|
62
|
+
# Allow on second attempt — agent needs full content for Edit
|
|
63
|
+
DENY_MARKER="$DENY_DIR/$(echo "$FILE_PATH" | md5sum | cut -d' ' -f1)"
|
|
64
|
+
if [[ -f "$DENY_MARKER" ]]; then
|
|
65
|
+
rm -f "$DENY_MARKER"
|
|
66
|
+
exit 0
|
|
67
|
+
fi
|
|
68
|
+
touch "$DENY_MARKER"
|
|
69
|
+
|
|
70
|
+
REL_PATH=$(echo "$FILE_PATH" | sed "s|^$(pwd)/||")
|
|
71
|
+
deny \
|
|
72
|
+
"Use trace-mcp for code reading — it returns only what you need, saving tokens." \
|
|
73
|
+
"trace-mcp alternatives for ${REL_PATH}:\\n- get_outline { \\\"path\\\": \\\"${REL_PATH}\\\" } — see file structure (signatures only)\\n- get_symbol { \\\"fqn\\\": \\\"SymbolName\\\" } — read one specific symbol\\n- search { \\\"query\\\": \\\"keyword\\\" } — find symbols by name\\n- get_feature_context { \\\"description\\\": \\\"what you need\\\" } — relevant code for a task\\nIf you need full file content before editing, retry Read — it will be allowed."
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
exit 0
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# --- Grep ---
|
|
80
|
+
if [[ "$TOOL_NAME" == "Grep" ]]; then
|
|
81
|
+
GREP_PATH=$(echo "$INPUT" | jq -r '.tool_input.path // empty')
|
|
82
|
+
GREP_GLOB=$(echo "$INPUT" | jq -r '.tool_input.glob // empty')
|
|
83
|
+
GREP_TYPE=$(echo "$INPUT" | jq -r '.tool_input.type // empty')
|
|
84
|
+
|
|
85
|
+
# Allow grep on non-code file types
|
|
86
|
+
if echo "$GREP_GLOB" | grep -qiE '\.(md|json|ya?ml|toml|env|txt|html|xml|csv|cfg|ini|lock|log)'; then
|
|
87
|
+
exit 0
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Allow grep on non-code type filter
|
|
91
|
+
if [[ "$GREP_TYPE" == "md" || "$GREP_TYPE" == "json" || "$GREP_TYPE" == "yaml" || "$GREP_TYPE" == "toml" || "$GREP_TYPE" == "xml" || "$GREP_TYPE" == "html" || "$GREP_TYPE" == "csv" ]]; then
|
|
92
|
+
exit 0
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Allow grep on config dirs
|
|
96
|
+
if echo "$GREP_PATH" | grep -qE '(node_modules|vendor|dist|build|\.git)'; then
|
|
97
|
+
exit 0
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
PATTERN=$(echo "$INPUT" | jq -r '.tool_input.pattern // empty')
|
|
101
|
+
deny \
|
|
102
|
+
"Use trace-mcp for code search — it understands symbols and relationships." \
|
|
103
|
+
"trace-mcp alternatives for searching \\\"${PATTERN}\\\":\\n- search { \\\"query\\\": \\\"${PATTERN}\\\" } — find symbols by name (supports kind, language, file_pattern filters)\\n- find_usages { \\\"fqn\\\": \\\"SymbolName\\\" } — find all usages (imports, calls, renders)\\n- get_call_graph { \\\"fqn\\\": \\\"FunctionName\\\" } — who calls it + what it calls\\nUse Grep only for non-code files (.md, .json, .yaml, config)."
|
|
104
|
+
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# --- Glob ---
|
|
108
|
+
if [[ "$TOOL_NAME" == "Glob" ]]; then
|
|
109
|
+
GLOB_PATTERN=$(echo "$INPUT" | jq -r '.tool_input.pattern // empty')
|
|
110
|
+
|
|
111
|
+
# Allow glob for non-code patterns
|
|
112
|
+
if echo "$GLOB_PATTERN" | grep -qiE '\.(md|json|ya?ml|toml|env|txt|html|xml|csv|cfg|ini|lock|log)'; then
|
|
113
|
+
exit 0
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
deny \
|
|
117
|
+
"Use trace-mcp for code file discovery — it knows your project structure." \
|
|
118
|
+
"trace-mcp alternatives:\\n- get_project_map { \\\"summary_only\\\": true } — project overview (frameworks, languages, structure)\\n- search { \\\"query\\\": \\\"keyword\\\", \\\"file_pattern\\\": \\\"src/tools/*\\\" } — find symbols in specific paths\\n- get_outline { \\\"path\\\": \\\"path/to/file\\\" } — see what\\'s in a file\\nUse Glob only for non-code file patterns."
|
|
119
|
+
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# --- Bash ---
|
|
123
|
+
if [[ "$TOOL_NAME" == "Bash" ]]; then
|
|
124
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
|
|
125
|
+
|
|
126
|
+
# Allow safe commands
|
|
127
|
+
if echo "$COMMAND" | grep -qE "$SAFE_BASH_RE"; then
|
|
128
|
+
exit 0
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# Block code exploration via bash (grep, find, cat, head, tail on code files)
|
|
132
|
+
if echo "$COMMAND" | grep -qE '(^|\|)\s*(grep|rg|find|cat|head|tail|less|more|awk|sed)\s' && echo "$COMMAND" | grep -qiE "$CODE_EXT_RE"; then
|
|
133
|
+
deny \
|
|
134
|
+
"Use trace-mcp instead of shell commands for code exploration." \
|
|
135
|
+
"trace-mcp has structured tools for this:\\n- search — find symbols by name\\n- get_symbol — read a specific symbol\\n- get_outline — file structure\\n- find_usages — all usages of a symbol\\nUse Bash only for builds, tests, git, and system commands."
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
exit 0
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Allow everything else
|
|
142
|
+
exit 0
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# trace-mcp-reindex v0.1.0
|
|
3
|
+
# trace-mcp PostToolUse auto-reindex hook
|
|
4
|
+
# Triggers incremental reindex after Edit/Write/MultiEdit on code files.
|
|
5
|
+
# Runs `trace-mcp index-file <file>` in the background — non-blocking.
|
|
6
|
+
#
|
|
7
|
+
# Install: add to ~/.claude/settings.json or .claude/settings.local.json under PostToolUse
|
|
8
|
+
# See README.md for setup instructions.
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
INPUT=$(cat)
|
|
13
|
+
TOOL_NAME="${CLAUDE_TOOL_NAME:-$(echo "$INPUT" | jq -r '.tool_name // empty')}"
|
|
14
|
+
|
|
15
|
+
# Only handle edit-like tools
|
|
16
|
+
if [[ "$TOOL_NAME" != "Edit" && "$TOOL_NAME" != "Write" && "$TOOL_NAME" != "MultiEdit" ]]; then
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Code file extensions to reindex
|
|
21
|
+
CODE_EXT_RE='\.(ts|tsx|js|jsx|mjs|cjs|py|pyi|go|rs|java|kt|kts|rb|php|cs|cpp|c|h|hpp|swift|scala|vue|svelte|astro|blade\.php)$'
|
|
22
|
+
|
|
23
|
+
# Non-code extensions — skip silently
|
|
24
|
+
NONCODE_EXT_RE='\.(md|json|jsonc|yaml|yml|toml|ini|cfg|env|txt|html|xml|csv|svg|lock|log|sh|bash|zsh|fish|ps1|bat|cmd|dockerfile|dockerignore|gitignore|gitattributes|editorconfig|prettierrc|eslintrc|stylelintrc)$'
|
|
25
|
+
|
|
26
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
|
27
|
+
|
|
28
|
+
if [[ -z "$FILE_PATH" ]]; then
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Skip non-code files
|
|
33
|
+
if echo "$FILE_PATH" | grep -qiE "$NONCODE_EXT_RE"; then
|
|
34
|
+
exit 0
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Skip if not a recognised code file
|
|
38
|
+
if ! echo "$FILE_PATH" | grep -qiE "$CODE_EXT_RE"; then
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# Reindex in background — non-blocking, silent
|
|
43
|
+
nohup trace-mcp index-file "$FILE_PATH" >/dev/null 2>&1 &
|
|
44
|
+
|
|
45
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trace-mcp",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Framework-
|
|
3
|
+
"version": "1.0.10",
|
|
4
|
+
"description": "Framework-aware code intelligence MCP server — 48+ frameworks, 68 languages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -38,10 +38,12 @@
|
|
|
38
38
|
],
|
|
39
39
|
"files": [
|
|
40
40
|
"dist",
|
|
41
|
+
"hooks",
|
|
41
42
|
"LICENSE",
|
|
42
43
|
"README.md"
|
|
43
44
|
],
|
|
44
45
|
"dependencies": {
|
|
46
|
+
"@clack/prompts": "^1.2.0",
|
|
45
47
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
46
48
|
"@parcel/watcher": "^2.5.6",
|
|
47
49
|
"@vue/compiler-sfc": "^3.5.32",
|
|
@@ -49,16 +51,22 @@
|
|
|
49
51
|
"commander": "^13.1.0",
|
|
50
52
|
"cosmiconfig": "^9.0.0",
|
|
51
53
|
"fast-glob": "^3.3.3",
|
|
54
|
+
"fastest-levenshtein": "^1.0.16",
|
|
52
55
|
"neverthrow": "^8.2.0",
|
|
53
56
|
"oxc-resolver": "^11.19.1",
|
|
54
57
|
"pino": "^9.6.0",
|
|
55
|
-
"tree-sitter": "^0.
|
|
58
|
+
"tree-sitter": "^0.21.1",
|
|
59
|
+
"tree-sitter-c": "^0.23.4",
|
|
60
|
+
"tree-sitter-c-sharp": "^0.23.1",
|
|
61
|
+
"tree-sitter-cpp": "^0.23.4",
|
|
56
62
|
"tree-sitter-go": "^0.23.4",
|
|
57
63
|
"tree-sitter-java": "^0.23.5",
|
|
58
64
|
"tree-sitter-kotlin": "^0.3.8",
|
|
59
65
|
"tree-sitter-php": "^0.22.8",
|
|
60
66
|
"tree-sitter-python": "^0.21.0",
|
|
61
67
|
"tree-sitter-ruby": "^0.23.1",
|
|
68
|
+
"tree-sitter-rust": "^0.23.2",
|
|
69
|
+
"tree-sitter-scala": "^0.23.2",
|
|
62
70
|
"tree-sitter-typescript": "^0.23.2",
|
|
63
71
|
"yaml": "^2.8.3",
|
|
64
72
|
"zod": "^3.24.0"
|