Tutorial

How to Audit MCP Tool Permissions in Your IDE

Review and lock down MCP tool permissions so your IDE agent only accesses approved APIs. Step-by-step audit for Cursor, VS Code, Windsurf.

MCP tools give your IDE agent access to external APIs, databases, and services. An unaudited configuration can expose API keys, allow unintended writes, or rack up charges. This tutorial walks through auditing which MCP tools are connected, classifying them by risk level, checking for plaintext API keys, and monitoring usage.

Prerequisites

  • An IDE with MCP support (Cursor, VS Code, Windsurf)
  • At least one MCP server configured
  • Basic understanding of MCP

Walkthrough

Step 1: List all configured MCP servers

Read IDE config files to see connected servers.

Python
import json, os

def list_mcp():
    for path in ['.mcp.json', os.path.expanduser('~/.cursor/mcp.json')]:
        if os.path.exists(path):
            config = json.load(open(path))
            servers = config.get('mcpServers', config.get('servers', {}))
            print(f'\n{path}:')
            for name, srv in servers.items():
                url = srv.get('url', srv.get('command', '?'))
                print(f'  {name}: {url}')
                for k in srv.get('env', {}):
                    safe = '***' if any(s in k.lower() for s in ['key', 'secret', 'token']) else srv['env'][k]
                    print(f'    {k}: {safe}')

list_mcp()

Step 2: Classify tools by risk

Categorize each tool as read-only, write, or destructive.

Python
def classify(tool_name):
    t = tool_name.lower()
    if any(w in t for w in ['delete', 'remove', 'drop']): return 'HIGH'
    if any(w in t for w in ['create', 'update', 'send', 'write']): return 'MEDIUM'
    if any(w in t for w in ['search', 'get', 'list', 'fetch', 'read']): return 'LOW'
    return 'REVIEW'

for tool in ['scavio_search', 'gmail_send_email', 'db_delete_record', 'list_files']:
    print(f'  [{classify(tool):6}] {tool}')

Step 3: Check for plaintext API keys

Verify keys use env vars, not raw values.

Python
def audit_keys(path='.mcp.json'):
    config = json.load(open(path))
    issues = []
    for name, srv in config.get('mcpServers', {}).items():
        for k, v in srv.get('env', {}).items():
            if any(s in k.lower() for s in ['key', 'secret', 'token']):
                if not v.startswith('$') and len(v) > 10:
                    issues.append(f'{name}.{k}: plaintext key detected')
    if issues:
        for i in issues: print(f'  WARNING: {i}')
    else:
        print('  No plaintext keys found.')

audit_keys()

Step 4: Monitor MCP usage

Track which tools your agent calls.

Python
from collections import Counter

class MCPMonitor:
    def __init__(self): self.calls = Counter()
    def log(self, tool): self.calls[tool] += 1
    def report(self):
        for tool, count in self.calls.most_common():
            print(f'  {tool:30} {count:4} calls [{classify(tool)}]')

m = MCPMonitor()
m.log('scavio_search'); m.log('scavio_search'); m.log('gmail_send_email')
m.report()

Python Example

Python
import json, os
def audit(path='.mcp.json'):
    if not os.path.exists(path): print('Not found'); return
    for name, srv in json.load(open(path)).get('mcpServers', {}).items():
        url = srv.get('url', srv.get('command', '?'))
        print(f'{name}: {url}')
        for k, v in srv.get('env', {}).items():
            print(f'  {k}: {"***" if "key" in k.lower() else v}')
audit()

JavaScript Example

JavaScript
const fs = require('fs');
function audit(path = '.mcp.json') {
  if (!fs.existsSync(path)) return console.log('Not found');
  const config = JSON.parse(fs.readFileSync(path, 'utf8'));
  for (const [name, srv] of Object.entries(config.mcpServers || {})) {
    console.log(`${name}: ${srv.url || srv.command || '?'}`);
    for (const [k, v] of Object.entries(srv.env || {}))
      console.log(`  ${k}: ${/key|secret|token/i.test(k) ? '***' : v}`);
  }
}
audit();

Expected Output

JSON
.mcp.json:
  scavio: https://mcp.scavio.dev/mcp
    SCAVIO_API_KEY: ***
  [LOW   ] scavio_search
  [MEDIUM] gmail_send_email
  [HIGH  ] db_delete_record
  No plaintext keys found.

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

An IDE with MCP support (Cursor, VS Code, Windsurf). At least one MCP server configured. Basic understanding of MCP. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Review and lock down MCP tool permissions so your IDE agent only accesses approved APIs. Step-by-step audit for Cursor, VS Code, Windsurf.