trace-mcp 1.2.1 → 1.4.1

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,177 @@
1
+ @echo off
2
+ REM trace-mcp-guard v0.2.0
3
+ REM trace-mcp PreToolUse guard (Windows)
4
+ REM Blocks Read/Grep/Glob/Bash on source code files - redirects to trace-mcp tools.
5
+ REM Allows: non-code files, Read before Edit, safe Bash commands (git, npm, build, test).
6
+ REM
7
+ REM Install: add to ~\.claude\settings.json or .claude\settings.local.json
8
+ REM See README.md for setup instructions.
9
+
10
+ setlocal enabledelayedexpansion
11
+
12
+ REM Read JSON from stdin into a temp file
13
+ set "TMPINPUT=%TEMP%\trace-mcp-guard-input-%RANDOM%.json"
14
+ more > "%TMPINPUT%"
15
+
16
+ REM Get tool name from env or parse from JSON
17
+ if defined CLAUDE_TOOL_NAME (
18
+ set "TOOL_NAME=%CLAUDE_TOOL_NAME%"
19
+ ) else (
20
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).tool_name"`) do set "TOOL_NAME=%%i"
21
+ )
22
+
23
+ if "%TOOL_NAME%"=="" goto :allow
24
+
25
+ REM --- Read ---
26
+ if /i not "%TOOL_NAME%"=="Read" goto :check_grep
27
+
28
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).tool_input.file_path"`) do set "FILE_PATH=%%i"
29
+
30
+ REM Block .env files
31
+ echo "%FILE_PATH%" | findstr /i /r "\.env" >nul 2>&1
32
+ if %errorlevel%==0 (
33
+ set "REL_PATH=%FILE_PATH%"
34
+ call :deny "Use get_env_vars for .env files - it masks sensitive values (passwords, API keys, tokens)." "trace-mcp alternatives: get_env_vars to list keys + types without exposing secrets."
35
+ goto :cleanup
36
+ )
37
+
38
+ REM Allow non-code files
39
+ echo "%FILE_PATH%" | findstr /i /r "\.md$ \.json$ \.jsonc$ \.yaml$ \.yml$ \.toml$ \.ini$ \.cfg$ \.txt$ \.html$ \.xml$ \.csv$ \.svg$ \.lock$ \.log$ \.sh$ \.bash$ \.zsh$ \.fish$ \.ps1$ \.bat$ \.cmd$" >nul 2>&1
40
+ if %errorlevel%==0 goto :allow
41
+
42
+ REM Allow files in non-source dirs
43
+ echo "%FILE_PATH%" | findstr /i /r "node_modules\\ vendor\\ dist\\ build\\ \.git\\" >nul 2>&1
44
+ if %errorlevel%==0 goto :allow
45
+
46
+ REM Block code file reads - redirect to trace-mcp
47
+ echo "%FILE_PATH%" | findstr /i /r "\.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$" >nul 2>&1
48
+ if not %errorlevel%==0 goto :allow
49
+
50
+ REM Allow on second attempt (agent needs full content for Edit)
51
+ set "SESSION_ID=default"
52
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "try { (Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).session_id } catch { 'default' }"`) do set "SESSION_ID=%%i"
53
+ set "DENY_DIR=%TEMP%\trace-mcp-guard-%SESSION_ID%"
54
+ if not exist "%DENY_DIR%" mkdir "%DENY_DIR%" 2>nul
55
+
56
+ REM Create a hash of the file path for the marker
57
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "[System.BitConverter]::ToString([System.Security.Cryptography.MD5]::Create().ComputeHash([System.Text.Encoding]::UTF8.GetBytes('%FILE_PATH%'))).Replace('-','')"`) do set "MARKER_HASH=%%i"
58
+ set "DENY_MARKER=%DENY_DIR%\%MARKER_HASH%"
59
+
60
+ if exist "%DENY_MARKER%" (
61
+ del "%DENY_MARKER%" 2>nul
62
+ goto :allow
63
+ )
64
+ echo.> "%DENY_MARKER%"
65
+
66
+ call :deny "Use trace-mcp for code reading - it returns only what you need, saving tokens." "trace-mcp alternatives: get_outline, get_symbol, search, get_feature_context. If you need full file content before editing, retry Read - it will be allowed."
67
+ goto :cleanup
68
+
69
+ :check_grep
70
+ REM --- Grep ---
71
+ if /i not "%TOOL_NAME%"=="Grep" goto :check_glob
72
+
73
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).tool_input.path"`) do set "GREP_PATH=%%i"
74
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).tool_input.glob"`) do set "GREP_GLOB=%%i"
75
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).tool_input.type"`) do set "GREP_TYPE=%%i"
76
+
77
+ REM Block grep on .env files
78
+ echo "%GREP_GLOB%" | findstr /i /r "\.env" >nul 2>&1
79
+ if %errorlevel%==0 (
80
+ call :deny "Use get_env_vars for .env files - it masks sensitive values." "trace-mcp alternatives: get_env_vars with pattern filter."
81
+ goto :cleanup
82
+ )
83
+ echo "%GREP_PATH%" | findstr /i /r "\.env" >nul 2>&1
84
+ if %errorlevel%==0 (
85
+ call :deny "Use get_env_vars for .env files - it masks sensitive values." "trace-mcp alternatives: get_env_vars with pattern filter."
86
+ goto :cleanup
87
+ )
88
+
89
+ REM Allow grep on non-code file types
90
+ echo "%GREP_GLOB%" | findstr /i /r "\.md \.json \.ya*ml \.toml \.txt \.html \.xml \.csv \.cfg \.ini \.lock \.log" >nul 2>&1
91
+ if %errorlevel%==0 goto :allow
92
+
93
+ REM Allow grep on non-code type filter
94
+ if /i "%GREP_TYPE%"=="md" goto :allow
95
+ if /i "%GREP_TYPE%"=="json" goto :allow
96
+ if /i "%GREP_TYPE%"=="yaml" goto :allow
97
+ if /i "%GREP_TYPE%"=="toml" goto :allow
98
+ if /i "%GREP_TYPE%"=="xml" goto :allow
99
+ if /i "%GREP_TYPE%"=="html" goto :allow
100
+ if /i "%GREP_TYPE%"=="csv" goto :allow
101
+
102
+ REM Allow grep on config dirs
103
+ echo "%GREP_PATH%" | findstr /i /r "node_modules vendor dist build \.git" >nul 2>&1
104
+ if %errorlevel%==0 goto :allow
105
+
106
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).tool_input.pattern"`) do set "PATTERN=%%i"
107
+ call :deny "Use trace-mcp for code search - it understands symbols and relationships." "trace-mcp alternatives: search, find_usages, get_call_graph. Use Grep only for non-code files (.md, .json, .yaml, config)."
108
+ goto :cleanup
109
+
110
+ :check_glob
111
+ REM --- Glob ---
112
+ if /i not "%TOOL_NAME%"=="Glob" goto :check_bash
113
+
114
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).tool_input.pattern"`) do set "GLOB_PATTERN=%%i"
115
+
116
+ REM Block glob on .env patterns
117
+ echo "%GLOB_PATTERN%" | findstr /i /r "\.env" >nul 2>&1
118
+ if %errorlevel%==0 (
119
+ call :deny "Use get_env_vars for .env files - it masks sensitive values." "trace-mcp alternatives: get_env_vars to list all env vars across all .env files."
120
+ goto :cleanup
121
+ )
122
+
123
+ REM Allow glob for non-code patterns
124
+ echo "%GLOB_PATTERN%" | findstr /i /r "\.md \.json \.ya*ml \.toml \.txt \.html \.xml \.csv \.cfg \.ini \.lock \.log" >nul 2>&1
125
+ if %errorlevel%==0 goto :allow
126
+
127
+ call :deny "Use trace-mcp for code file discovery - it knows your project structure." "trace-mcp alternatives: get_project_map, search with file_pattern, get_outline. Use Glob only for non-code file patterns."
128
+ goto :cleanup
129
+
130
+ :check_bash
131
+ REM --- Bash ---
132
+ if /i not "%TOOL_NAME%"=="Bash" goto :allow
133
+
134
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).tool_input.command"`) do set "COMMAND=%%i"
135
+
136
+ REM Allow safe commands
137
+ echo "%COMMAND%" | findstr /i /r /c:"^git " /c:"^npm " /c:"^npx " /c:"^pnpm " /c:"^yarn " /c:"^bun " /c:"^node " /c:"^deno " /c:"^cargo " /c:"^go " /c:"^make " /c:"^mvn " /c:"^gradle " /c:"^docker " /c:"^kubectl " /c:"^helm " /c:"^terraform " /c:"^pip " /c:"^poetry " /c:"^uv " /c:"^pytest " /c:"^vitest " /c:"^jest " /c:"^phpunit " /c:"^composer " /c:"^artisan " /c:"^rails " /c:"^bundle " /c:"^mix " /c:"^dotnet " /c:"^cmake " >nul 2>&1
138
+ if %errorlevel%==0 goto :allow
139
+
140
+ REM Block code exploration via bash
141
+ set "HAS_EXPLORE=0"
142
+ echo "%COMMAND%" | findstr /i /r "grep rg find cat head tail less more awk sed" >nul 2>&1
143
+ if %errorlevel%==0 set "HAS_EXPLORE=1"
144
+
145
+ set "HAS_CODE=0"
146
+ echo "%COMMAND%" | findstr /i /r "\.ts \.tsx \.js \.jsx \.py \.go \.rs \.java \.rb \.php \.cs \.cpp \.c \.h \.swift \.scala \.vue \.svelte" >nul 2>&1
147
+ if %errorlevel%==0 set "HAS_CODE=1"
148
+
149
+ if "%HAS_EXPLORE%"=="1" if "%HAS_CODE%"=="1" (
150
+ call :deny "Use trace-mcp instead of shell commands for code exploration." "trace-mcp has structured tools: search, get_symbol, get_outline, find_usages. Use Bash only for builds, tests, git, and system commands."
151
+ goto :cleanup
152
+ )
153
+
154
+ goto :allow
155
+
156
+ REM --- Helpers ---
157
+
158
+ :deny
159
+ set "REASON=%~1"
160
+ set "CONTEXT=%~2"
161
+ echo {
162
+ echo "hookSpecificOutput": {
163
+ echo "hookEventName": "PreToolUse",
164
+ echo "permissionDecision": "deny",
165
+ echo "permissionDecisionReason": "%REASON%",
166
+ echo "additionalContext": "%CONTEXT%"
167
+ echo }
168
+ echo }
169
+ goto :eof
170
+
171
+ :allow
172
+ del "%TMPINPUT%" 2>nul
173
+ exit /b 0
174
+
175
+ :cleanup
176
+ del "%TMPINPUT%" 2>nul
177
+ exit /b 0
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # trace-mcp-guard v0.1.0
2
+ # trace-mcp-guard v0.2.0
3
3
  # trace-mcp PreToolUse guard
4
4
  # Blocks Read/Grep/Glob/Bash on source code files → redirects to trace-mcp tools.
5
5
  # Allows: non-code files, Read before Edit, safe Bash commands (git, npm, build, test).
@@ -16,7 +16,10 @@ TOOL_NAME="${CLAUDE_TOOL_NAME:-$(echo "$INPUT" | jq -r '.tool_name // empty')}"
16
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
17
 
18
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)$'
19
+ NONCODE_EXT_RE='\.(md|json|jsonc|yaml|yml|toml|ini|cfg|txt|html|xml|csv|svg|lock|log|sh|bash|zsh|fish|ps1|bat|cmd|dockerfile|dockerignore|gitignore|gitattributes|editorconfig|prettierrc|eslintrc|stylelintrc)$'
20
+
21
+ # .env files — always route through trace-mcp to prevent secret leakage
22
+ ENV_FILE_RE='\.env(\.[a-zA-Z0-9._-]+)?$'
20
23
 
21
24
  # Safe bash command prefixes — never block
22
25
  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 )'
@@ -46,6 +49,14 @@ mkdir -p "$DENY_DIR" 2>/dev/null
46
49
  if [[ "$TOOL_NAME" == "Read" ]]; then
47
50
  FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
48
51
 
52
+ # Block .env files — prevent secret leakage to AI model context
53
+ if echo "$FILE_PATH" | grep -qiE "$ENV_FILE_RE"; then
54
+ REL_PATH=$(echo "$FILE_PATH" | sed "s|^$(pwd)/||")
55
+ deny \
56
+ "Use get_env_vars for .env files — it masks sensitive values (passwords, API keys, tokens)." \
57
+ "trace-mcp alternatives for ${REL_PATH}:\\n- get_env_vars { \\\"file\\\": \\\"${REL_PATH}\\\" } — list keys + types without exposing secrets\\n- get_env_vars { \\\"pattern\\\": \\\"DB_\\\" } — filter by key prefix\\nNever read .env files directly — secrets will leak into AI model context."
58
+ fi
59
+
49
60
  # Allow non-code files
50
61
  if echo "$FILE_PATH" | grep -qiE "$NONCODE_EXT_RE"; then
51
62
  exit 0
@@ -82,8 +93,15 @@ if [[ "$TOOL_NAME" == "Grep" ]]; then
82
93
  GREP_GLOB=$(echo "$INPUT" | jq -r '.tool_input.glob // empty')
83
94
  GREP_TYPE=$(echo "$INPUT" | jq -r '.tool_input.type // empty')
84
95
 
96
+ # Block grep on .env files — prevent secret leakage
97
+ if echo "$GREP_GLOB" | grep -qiE '\.env' || echo "$GREP_PATH" | grep -qiE "$ENV_FILE_RE"; then
98
+ deny \
99
+ "Use get_env_vars for .env files — it masks sensitive values." \
100
+ "trace-mcp alternatives:\\n- get_env_vars { \\\"pattern\\\": \\\"search_term\\\" } — find env vars by key pattern without exposing values"
101
+ fi
102
+
85
103
  # 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
104
+ if echo "$GREP_GLOB" | grep -qiE '\.(md|json|ya?ml|toml|txt|html|xml|csv|cfg|ini|lock|log)'; then
87
105
  exit 0
88
106
  fi
89
107
 
@@ -108,8 +126,15 @@ fi
108
126
  if [[ "$TOOL_NAME" == "Glob" ]]; then
109
127
  GLOB_PATTERN=$(echo "$INPUT" | jq -r '.tool_input.pattern // empty')
110
128
 
129
+ # Block glob on .env patterns
130
+ if echo "$GLOB_PATTERN" | grep -qiE '\.env'; then
131
+ deny \
132
+ "Use get_env_vars for .env files — it masks sensitive values." \
133
+ "trace-mcp alternatives:\\n- get_env_vars {} — list all env vars across all .env files"
134
+ fi
135
+
111
136
  # 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
137
+ if echo "$GLOB_PATTERN" | grep -qiE '\.(md|json|ya?ml|toml|txt|html|xml|csv|cfg|ini|lock|log)'; then
113
138
  exit 0
114
139
  fi
115
140
 
@@ -0,0 +1,43 @@
1
+ @echo off
2
+ REM trace-mcp-reindex v0.1.0
3
+ REM trace-mcp PostToolUse auto-reindex hook (Windows)
4
+ REM Triggers incremental reindex after Edit/Write/MultiEdit on code files.
5
+ REM Runs trace-mcp index-file in the background - non-blocking.
6
+ REM
7
+ REM Install: add to ~\.claude\settings.json or .claude\settings.local.json under PostToolUse
8
+ REM See README.md for setup instructions.
9
+
10
+ setlocal enabledelayedexpansion
11
+
12
+ REM Read JSON from stdin into a temp file
13
+ set "TMPINPUT=%TEMP%\trace-mcp-reindex-input-%RANDOM%.json"
14
+ more > "%TMPINPUT%"
15
+
16
+ REM Get tool name from env or parse from JSON
17
+ if defined CLAUDE_TOOL_NAME (
18
+ set "TOOL_NAME=%CLAUDE_TOOL_NAME%"
19
+ ) else (
20
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).tool_name"`) do set "TOOL_NAME=%%i"
21
+ )
22
+
23
+ REM Only handle edit-like tools
24
+ if /i not "%TOOL_NAME%"=="Edit" if /i not "%TOOL_NAME%"=="Write" if /i not "%TOOL_NAME%"=="MultiEdit" goto :done
25
+
26
+ for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%TMPINPUT%' -Raw | ConvertFrom-Json).tool_input.file_path"`) do set "FILE_PATH=%%i"
27
+
28
+ if "%FILE_PATH%"=="" goto :done
29
+
30
+ REM Skip non-code files
31
+ echo "%FILE_PATH%" | findstr /i /r "\.md$ \.json$ \.jsonc$ \.yaml$ \.yml$ \.toml$ \.ini$ \.cfg$ \.env \.txt$ \.html$ \.xml$ \.csv$ \.svg$ \.lock$ \.log$ \.sh$ \.bash$ \.zsh$ \.fish$ \.ps1$ \.bat$ \.cmd$" >nul 2>&1
32
+ if %errorlevel%==0 goto :done
33
+
34
+ REM Skip if not a recognised code file
35
+ echo "%FILE_PATH%" | findstr /i /r "\.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$" >nul 2>&1
36
+ if not %errorlevel%==0 goto :done
37
+
38
+ REM Reindex in background - non-blocking, silent
39
+ start /b "" cmd /c "trace-mcp index-file "%FILE_PATH%" >nul 2>&1"
40
+
41
+ :done
42
+ del "%TMPINPUT%" 2>nul
43
+ exit /b 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trace-mcp",
3
- "version": "1.2.1",
3
+ "version": "1.4.1",
4
4
  "description": "Framework-aware code intelligence MCP server — 48+ frameworks, 68 languages",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",