◉CLAUDE LABJP
●2.1.302 — Fork subagents are now on by default in claude -p, the Agent SDK and the desktop app. Turn them off with CLAUDE_CODE_FORK_SUBAGENT=0 (10/16)●2.1.301 — Unattended retries now stop on their own when a usage limit is hit instead of waiting (10/15). Latest is 2.1.303 (10/18)●SONNET 4.5 — Retires on the Claude API on 11/30, 41 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…●2.1.302 — Fork subagents are now on by default in claude -p, the Agent SDK and the desktop app. Turn them off with CLAUDE_CODE_FORK_SUBAGENT=0 (10/16)●2.1.301 — Unattended retries now stop on their own when a usage limit is hit instead of waiting (10/15). Latest is 2.1.303 (10/18)●SONNET 4.5 — Retires on the Claude API on 11/30, 41 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…
Articles/Cowork
◈ Cowork/2026-10-20Intermediate

I Sorted 32 Connector Tool Names Into Read, Write and Delete — Four Wouldn't Sort by Name

I wrote a small script that sorts the tool names of my Cowork connectors into read, write and delete by verb. The first pass left nine undecided, the fix left four, and here is how I now set approvals.

Cowork51ConnectorsPermissions9MCP57Approvals

I counted the connector tool names in my working environment the other day. Four connections — documents, memory, scheduling and design — added up to 32 tools.

Before deciding which ones to let through automatically and which to put behind an approval, I wanted to know how far the names alone could take me. As an indie developer using Cowork between app work, I don't have the patience to read every tool name and ask "is this read-only, or can it write?" each time.

The result first: sorting by verb left 9 of 32 undecided on the first pass, and 4 were still undecided after the fix.

What the official permission screen actually separates

Before sorting, I checked how Claude's help article "Use connectors to extend Claude's capabilities" (read on 2026-10-20) describes tool permissions. The relevant section sits under Team and Enterprise.

ItemWhat the article says
WhereCustomize > Connectors, pick the connector, open "Tool permissions"
GroupingBy type, such as read-only tools and write/delete tools
StatesAlways allow / Needs approval / Blocked
Who sets itOwners; applies org-wide and individual users cannot override it
EffectOnly narrows access; never grants more than the source system permits

One thing stood out: the official split is two groups, read versus write/delete. Writing and deleting share one box.

I could not confirm from the article whether individual Pro or Max users see the same screen. If you don't, the approval prompts at connection time and at run time are what you have.

First pass: sorting by the first word left nine

I started naively, looking at the leading verb of each tool name. get and list mean read, create and send mean write, delete means delete.

import re, sys
from collections import defaultdict
 
READ = {"get","list","read","query","search","find","fetch","describe","export","download","whoami"}
WRITE = {"create","update","add","set","send","write","upload","append","edit","post","run","start","fire","batch"}
DELETE = {"delete","remove","drop","cancel","stop","clear","reset","kill"}
 
def split_name(full):
    # e.g. mcp__Claude_Docs__delete -> ("Claude_Docs", "delete")
    parts = full.split("__")
    if len(parts) >= 3 and parts[0] == "mcp":
        return parts[1], parts[-1]
    return "(unknown)", full
 
def classify(tool):
    words = re.split(r"[_\-]+", tool.lower())
    verb = words[0]                      # first pass: look at the first word only
    if verb in DELETE or any(w in DELETE for w in words): return "delete"
    if verb in WRITE: return "write"
    if verb in READ: return "read"
    return "check"                       # when unsure, a human looks
 
groups = defaultdict(lambda: defaultdict(list))
for line in sys.stdin:
    line = line.strip()
    if line:
        server, tool = split_name(line)
        groups[server][classify(tool)].append(tool)
 
for server in sorted(groups):
    g = groups[server]
    print(f"{server}: read={len(g['read'])} write={len(g['write'])} delete={len(g['delete'])} check={len(g['check'])}")
    for t in g["check"]:
        print(f"   needs a look -> {t}")

Put one tool name per line in names.txt, in the form mcp__server__tool, and run python3 -I sort_tools.py < names.txt.

All five memory tools landed in "needs a look". The cause was naming: memory_read and memory_list start with a namespace word, so the verb sits in second place. A first-word check could tell neither the two readers nor the three writers apart.

Second pass: look at every word, lean toward the heavier verdict

I changed one function. It now inspects every word, and when several categories match, it takes the heavier one in the order delete, write, read.

def classify(tool):
    words = re.split(r"[_\-]+", tool.lower())
    # priority: delete > write > read. When in doubt, lean heavy
    if any(w in DELETE for w in words): return "delete"
    if any(w in WRITE for w in words): return "write"
    if any(w in READ for w in words): return "read"
    return "check"

Same 32 names, grouped by connection:

ConnectionReadWriteDeleteNeeds a look
Documents3311 (guide)
Memory2211 (memory_str_replace)
Scheduling1410
Design5412 (use_figma, generate_diagram)
Total111344

Nine became four. But adding words to the dictionary won't clear the rest, for a reason worth spelling out.

The four that remained weren't verbs

guide looks like it only returns instructions, but the name can't promise that. use_figma is "use", which says nothing about reading or writing. generate_diagram leaves open where the result ends up.

memory_str_replace is plainly a rewrite once you read it, but I hadn't put replace in the dictionary, so the script passed on it. That one is a gap in my list, and adding the word fixes it.

So the four are two kinds: those a bigger dictionary resolves, and those whose answer lives outside the name.

Let names decide what names can decide, treat the rest as heavy, and don't loosen approval until you've read what the tool does. That is the line this exercise drew for me.

Turning the sort into approval settings

Mapped onto the official Always allow / Needs approval / Blocked states, this is the proposal I would start from.

Sorted asProposed settingWhy
ReadAlways allowIt can only read what the source service already shows you, so you can start loose and watch
WriteNeeds approvalWhether it can be undone differs tool by tool
DeleteNeeds approval or BlockedDecide in advance when an irreversible action is allowed
Needs a lookNeeds approvalStay on the heavy side until you've read what it does

Open reads first, then writes behind approval — it is the same order I use for folders, which I wrote up in Write Access Came Third: The Order I Hand Folders to Cowork.

Where a verb dictionary breaks

The dictionary is a hypothesis. Even within these 32 names, a few are suspect. I filed export under read, yet it may create a file at the destination. download_assets also counts as read while it writes to local disk.

I filed batch under write. It runs several operations together, so a delete inside it would never show in the name.

So I use the sorted result to narrow down candidates for lighter approval, and make the final call by reading each tool's description. For watching a connector whose tool list changes over time, see The Night a Connector Grew Write Tools, Your Unattended Job Could Quietly Send Something.

One next step

Take the next connector you plan to add, paste its tool names into names.txt, and run the script once. Read the descriptions only for the ones it flags. That alone settles about half of where approvals should sit.

For me, two of the four leftovers were faster to settle by reading the description than by extending the dictionary. I'll keep adjusting where the machine decides and where I look myself.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

◈ Cowork2026-09-23
Write Access Came Third: The Order I Hand Folders to Cowork
When I connect a folder to Cowork I open it in three steps: read-only, a place where new files may appear, then write access. Here is the line I drew with a client's asset folder, and the three things I settle before connecting.
◈ Cowork2026-09-18
How I decide between Cowork and Claude Code: by where approvals land
Cowork and Claude Code run the same Claude, so I stopped comparing features and started sorting work by one question: can a human approval interrupt this step, or not? Here is the line I draw and the code I keep on the unattended side.
◈ Cowork2026-03-09
Canva × Claude in Practice — Saving Generated Candidates, Picking a design_type, Committing Edits
The parts of the Canva AI connector that actually trip people up in Claude: why generated designs are not saved yet, how to pick a design_type, why editing is a transaction, and what to check before exporting.