Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add skills/mayank-io/mstack/clean-permissionsnpx skills add mayank-io/mstack --skill clean-permissionsgit clone --depth 1 https://github.com/mayank-io/mstackWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00055 | $0.01969 |
| Opus 5 | $0.00028 | $0.00984 |
| Sonnet 5 | $0.00011 | $0.00394 |
| Haiku 4.5 | $0.00006 | $0.00197 |
Grade A, and why
clean-permissions scanned grade A with 2 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Reads agent configuration directorieslowAgent snooping
.claude/, .codex/, .gemini/ hold keys, settings and other credentials a mod has no legitimate need for.
Remove cruft from `~/.claude/settings.json` permissions allow list. Three categories of junk accumulate over time: Downgraded: this mod is about security review, or the phrase is quoted, so it is likely naming the pattern rather than instructing it.
Makes network callslowCapability
Not a fault in itself. Listed so you know the mod talks to something, and to what.
r'^Bash\(/usr/bin/curl ', How it starts
The opening of the file, as written. The whole thing — 208 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Clean Permissions Allow List
Remove cruft from ~/.claude/settings.json permissions allow list. Three categories of junk accumulate over time:
- One-off command pastes — full multi-line scripts, hardcoded IDs/paths/dates that got auto-approved during sessions
- Redundant entries — specific entries subsumed by a broader wildcard already in the list (e.g.
WebFetch(domain:example.com)whenWebFetch(domain:*)exists) - Dead references — MCP tools for servers that have been removed or disabled
Step 1: Read current state
Read ~/.claude/settings.json and extract the permissions.allow array. Report the current count.
Step 2: Run the cleanup script
Run this Python script via Bash to identify and remove cruft. The script is non-destructive until the user confirms — it prints a plan first.
IMPORTANT: Always run this script exactly. Do not improvise the cleanup logic.
import json, os, re, sys
with open(os.path.expanduser('~/.claude/settings.json')) as f:
settings = json.load(f)
allow = settings['permissions']['allow']
before = len(allow)
print(f"Current entries: {before}")
# === Build wildcard index for redundancy detection ===
#
# Permission format semantics:
# Bash(COMMAND_PREFIX:*) — matches any Bash command starting with COMMAND_PREFIX
# mcp__SERVER__* — matches any MCP tool on that server
# WebFetch(domain:*) — matches any domain
#
# So Bash(gh pr:*) covers Bash(gh pr create:*) because "gh pr create"
# starts with "gh pr". We extract the command prefix for semantic matching.
bash_wildcards = [] # list of command prefixes from Bash(CMD:*) entries
mcp_wildcards = [] # list of prefixes from mcp__X__* entries
has_webfetch_star = False
for e in allow:
# Bash(gh pr:*) -> command prefix "gh pr"
m = re.match(r'^Bash\((.+?):\*\)$', e)
if m:
bash_wildcards.append(m.group(1))
continue
# mcp__playwright__* -> prefix "mcp__playwright__"
if e.endswith('__*') and e.startswith('mcp__'):
mcp_wildcards.append(e[:-1]) # "mcp__playwright__"
continue
# WebFetch(domain:*)
if e == 'WebFetch(domain:*)':
has_webfetch_star = True
continue
# === Detect one-off pastes (category 3) ===
oneoff_patterns = [
r'^Bash\(for id in ',
r'^Bash\(do echo ',
r'^Bash\(do\)$',
r'^Bash\(done\)$',
r'^Bash\(fi\)$',
r'^Bash\(# ',
r'^Bash\(echo === ',
r'^Bash\(echo .+?:\*\)$',
r'^Bash\(export (PATH|GOPATH)=',
r'^Bash\(/usr/bin/curl ',
r'^Bash\(/opt/homebrew/bin/jq ',
]
cat3_oneoff = set()
for e in allow:
# Multi-line bash -c scripts (NOT the wildcard Bash(bash -c:*))
if e.startswith("Bash(bash -c '") and e != "Bash(bash -c:*)":
cat3_oneoff.add(e)
continue
for pat in oneoff_patterns:
if re.match(pat, e):
cat3_oneoff.add(e)
break
# === Detect redundant entries (category 2) ===
cat2_redundant = set()
for e in allow:
if e in cat3_oneoff:
continue
# Check Bash entries: Bash(CMD:*) is redundant if a shorter CMD prefix exists
m = re.match(r'^Bash\((.+?):\*\)$', e)
if m:
cmd = m.group(1)
for wc_cmd in bash_wildcards:
if cmd != wc_cmd and cmd.startswith(wc_cmd):
cat2_redundant.add(e)
break
continue
# Check non-wildcard Bash entries: Bash(FULL_CMD) covered by Bash(PREFIX:*)
m2 = re.match(r'^Bash\((.+?)\)$', e)
if m2 and not e.endswith(':*)'):
cmd = m2.group(1)
for wc_cmd in bash_wildcards:
if cmd.startswith(wc_cmd):
cat2_redundant.add(e)
break
continue
# Check MCP entries: individual tool covered by server wildcard
if e.startswith('mcp__') and not e.endswith('__*'):
for wc_prefix in mcp_wildcards:
if e.startswith(wc_prefix):
cat2_redundant.add(e)
break
continue
# Check WebFetch: specific domain redundant with WebFetch(domain:*)
if has_webfetch_star and e.startswith('WebFetch(domain:') and e != 'WebFetch(domain:*)':
cat2_redundant.add(e)
continue
# === Detect dead MCP refs (category 1) ===
# Known plugin-provided MCP prefixes that don't need a mcpServers entry
plugin_mcp = {'context7', 'playwright', 'plugin_playwright_playwright',
'plugin_context7_context7', 'plugin_serena_serena'}
mcp_servers = settings.get('mcpServers', {})
active_servers = {k for k, v in mcp_servers.items() if not v.get('disabled', False)}
cat1_dead = set()
for e in allow:
if e in cat2_redundant or e in cat3_oneoff:
continue
m = re.match(r'^mcp__(.+?)__', e)
if m:
server = m.group(1)
if server not in active_servers and server not in plugin_mcp:
cat1_dead.add(e)
# === Consolidate individual mcp__plugin_* to wildcards ===
plugin_groups = {}
for e in cat2_redundant:
m = re.match(r'^(mcp__plugin_\w+__)', e)
if m:
plugin_groups.setdefault(m.group(1), []).append(e)
new_wildcards = []
for prefix, entries in plugin_groups.items():
wc = prefix + '*'
if wc not in allow:
new_wildcards.append(wc)
# === Report ===
remove_set = cat1_dead | cat2_redundant | cat3_oneoff
print(f"\n--- Category 1: Dead MCP ({len(cat1_dead)}) ---")
for e in sorted(cat1_dead):
print(f" {e}")
print(f"\n--- Category 2: Redundant ({len(cat2_redundant)}) ---")
for e in sorted(cat2_redundant):
print(f" {e}")
print(f"\n--- Category 3: One-off pastes ({len(cat3_oneoff)}) ---")
for e in sorted(cat3_oneoff):
print(f" {e[:80]}{'...' if len(e) > 80 else ''}")
if new_wildcards:
print(f"\n--- New wildcards to add ({len(new_wildcards)}) ---")
for w in new_wildcards:
print(f" {w}")
after = before - len(remove_set) + len(new_wildcards)
print(f"\nBefore: {before} | Removing: {len(remove_set)} | Adding: {len(new_wildcards)} | After: {after}")
if '--apply' not in sys.argv:
print("\nDry run. Pass --apply to write changes.")
sys.exit(0)
# === Apply ===
cleaned = [e for e in allow if e not in remove_set]
cleaned.extend(new_wildcards)
settings['permissions']['allow'] = cleaned
with open(os.path.expanduser('~/.claude/settings.json'), 'w') as f:
json.dump(settings, f, indent=2)
f.write('\n')
print(f"Written. Final count: {len(cleaned)}")
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2d ago First seen · 208 lines · 55 tokens per session scan A 0ccf6269f481
clean-permissions is a skill published in the GitHub repository mayank-io/mstack (5 stars, last pushed 8d ago), licensed MIT. It adds 55 tokens to every session and 1,969 once invoked, about $0.0003 per session on Opus 5. A static security scan graded it A with 2 findings (reads agent configuration directories, makes network calls). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other skills, from other repositories
systematic-debugging
Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.
chat-pet-sprite-creation
Use when creating or changing VS Code chat pet sprite art, sprite sheets, state animations, eye treatments, Stable/Insiders variants, or pet transitions under src/vs/workbench/contrib/chat/browser/widget/media/chatPet.
cpu-profile-analysis
Analyze V8/Chrome CPU profiles (.cpuprofile) and DevTools trace files (Trace-.json). Use when: profiling performance, investigating slow functions, comparing code paths, finding bottlenecks, analyzing timeToRequest, understanding call trees from sampling profiler data, analyzing layout/paint/rendering, investigating…
agent-host-chat-contributions
Build and review cross-cutting agent-host chat behavior through lifecycle contributions. Use when adding turn lifecycle side effects, prompt or context injection, restored-history transformation, protocol-action observation, or when reviewing changes that add code to AgentSideEffects or AgentService.
auto-perf-optimize
Run agent-driven VS Code performance or memory investigations. Use when asked to launch Code OSS, automate a VS Code scenario, run the Chat memory smoke runner, capture renderer heap snapshots, take workflow screenshots, compare run summaries, or drive a repeatable scenario before heap-snapshot analysis.