# Clone the repo instead of installing directly
-weight: 500;">git clone https://github.com/author/mcp-server
cd mcp-server # Check recent commit history — is it actively maintained?
-weight: 500;">git log --oneline -10 # Check who has push access — is it a single developer or an org?
# Look at GitHub → Settings → Collaborators (if you have access)
# Clone the repo instead of installing directly
-weight: 500;">git clone https://github.com/author/mcp-server
cd mcp-server # Check recent commit history — is it actively maintained?
-weight: 500;">git log --oneline -10 # Check who has push access — is it a single developer or an org?
# Look at GitHub → Settings → Collaborators (if you have access)
# Clone the repo instead of installing directly
-weight: 500;">git clone https://github.com/author/mcp-server
cd mcp-server # Check recent commit history — is it actively maintained?
-weight: 500;">git log --oneline -10 # Check who has push access — is it a single developer or an org?
# Look at GitHub → Settings → Collaborators (if you have access)
# Search for shell execution patterns
grep -r "exec\|spawn\|execFile\|execSync\|spawnSync\|child_process" src/ --include="*.ts" --include="*.js" # Search for eval (rarely legitimate)
grep -r "eval" src/ --include="*.ts" --include="*.js"
# Search for shell execution patterns
grep -r "exec\|spawn\|execFile\|execSync\|spawnSync\|child_process" src/ --include="*.ts" --include="*.js" # Search for eval (rarely legitimate)
grep -r "eval" src/ --include="*.ts" --include="*.js"
# Search for shell execution patterns
grep -r "exec\|spawn\|execFile\|execSync\|spawnSync\|child_process" src/ --include="*.ts" --include="*.js" # Search for eval (rarely legitimate)
grep -r "eval" src/ --include="*.ts" --include="*.js"
execFile('-weight: 500;">git', ['log', '--author', username]) // Input is separate argument
execFile('-weight: 500;">git', ['log', '--author', username]) // Input is separate argument
execFile('-weight: 500;">git', ['log', '--author', username]) // Input is separate argument
exec(`-weight: 500;">git log --author="${username}"`) // String interpolation
exec(`-weight: 500;">git log --author="${username}"`) // String interpolation
exec(`-weight: 500;">git log --author="${username}"`) // String interpolation
# Find file read/write operations
grep -r "readFile\|writeFile\|readdir\|unlink\|rm\|rmdir" src/ --include="*.ts" --include="*.js" # Check if paths are validated
grep -r "path\.resolve\|path\.normalize\|path\.join" src/ --include="*.ts" --include="*.js"
# Find file read/write operations
grep -r "readFile\|writeFile\|readdir\|unlink\|rm\|rmdir" src/ --include="*.ts" --include="*.js" # Check if paths are validated
grep -r "path\.resolve\|path\.normalize\|path\.join" src/ --include="*.ts" --include="*.js"
# Find file read/write operations
grep -r "readFile\|writeFile\|readdir\|unlink\|rm\|rmdir" src/ --include="*.ts" --include="*.js" # Check if paths are validated
grep -r "path\.resolve\|path\.normalize\|path\.join" src/ --include="*.ts" --include="*.js"
// Good — path is resolved and checked
const resolved = path.resolve(userPath);
if (!resolved.startsWith(ALLOWED_DIR)) throw new Error('Path traversal detected'); // Bad — raw user path used directly
fs.readFile(userPath)
// Good — path is resolved and checked
const resolved = path.resolve(userPath);
if (!resolved.startsWith(ALLOWED_DIR)) throw new Error('Path traversal detected'); // Bad — raw user path used directly
fs.readFile(userPath)
// Good — path is resolved and checked
const resolved = path.resolve(userPath);
if (!resolved.startsWith(ALLOWED_DIR)) throw new Error('Path traversal detected'); // Bad — raw user path used directly
fs.readFile(userPath)
# Check current source
grep -r "api_key\|apikey\|api-key\|secret\|password\|token" src/ -i --include="*.ts" --include="*.js" # Check -weight: 500;">git history (credentials may have been added and removed)
-weight: 500;">git log -p | grep -E '(api_key|apikey|secret|password|token)\s*[=:]\s*["'][a-zA-Z0-9]{10,}'
# Check current source
grep -r "api_key\|apikey\|api-key\|secret\|password\|token" src/ -i --include="*.ts" --include="*.js" # Check -weight: 500;">git history (credentials may have been added and removed)
-weight: 500;">git log -p | grep -E '(api_key|apikey|secret|password|token)\s*[=:]\s*["'][a-zA-Z0-9]{10,}'
# Check current source
grep -r "api_key\|apikey\|api-key\|secret\|password\|token" src/ -i --include="*.ts" --include="*.js" # Check -weight: 500;">git history (credentials may have been added and removed)
-weight: 500;">git log -p | grep -E '(api_key|apikey|secret|password|token)\s*[=:]\s*["'][a-zA-Z0-9]{10,}'
# Find HTTP/HTTPS calls
grep -r "fetch\|axios\|got\|request\|http\." src/ --include="*.ts" --include="*.js"
# Find HTTP/HTTPS calls
grep -r "fetch\|axios\|got\|request\|http\." src/ --include="*.ts" --include="*.js"
# Find HTTP/HTTPS calls
grep -r "fetch\|axios\|got\|request\|http\." src/ --include="*.ts" --include="*.js"
// What tools are defined?
// Do the descriptions accurately reflect what they do?
// Are there any "hidden" tools with misleading descriptions?
// What tools are defined?
// Do the descriptions accurately reflect what they do?
// Are there any "hidden" tools with misleading descriptions?
// What tools are defined?
// Do the descriptions accurately reflect what they do?
// Are there any "hidden" tools with misleading descriptions? - Last commit was 6+ months ago
- Single anonymous developer
- No license file
- No README explaining what the server does - Is user input passed directly into any of these functions?
- Is input sanitized before use?
- Are argument arrays used instead of string concatenation? - What external URLs does the server call?
- Are URLs hardcoded (safer) or user-controlled (riskier)?
- Does any data from your Claude session get sent externally? - Run in a Docker container with no volume mounts
- Use a dedicated VM or sandbox environment
- Review in a separate Claude Code session with limited file access