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.
@@ -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": "0.1.0",
4
- "description": "Framework-Aware Code Intelligence for Laravel/Vue/Inertia/Nuxt",
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.22.4",
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"