internkim
Tools

Tools

What the agent can call, what each call costs, and when it stops to ask you first.

Everything internkim does happens through a tool call. You ask in plain language in the messenger; the agent decides which tools answer it and calls them under your identity. There is no command syntax to learn.

Asking in practice

You writeWhat runsWhat you get back
"give Example Park a task to draft the quarterly report, due Friday"task_addthe created task, with owner and due date
"what am I supposed to do this week?"task_listyour open items this week
"how many days of leave have I got left?"leave_balanceyour remaining days for this year
"move Thursday's design review to four"event_list, then event_updatethe moved event
"DM Sample Lee that the deck is finished"message_senda draft, sent after you approve it
"in last week's announcement, fix the date and nothing else"message_search, then message_updatethe corrected span in your earlier message
"find out what changed in the new tax bill"web_searchranked public-web results, summarized

Mutating tools take hints (taskHint, eventHint, personHint): the title, name, or ID you actually know, resolved server-side to one canonical record. A fragment is enough — "Park" reaches Example Park without the agent looking anybody up first. An ambiguous hint never guesses: the call fails with a candidate list to choose from, and choosing is what person_list is for.

Two families

Capability tools touch shared records and the world outside: tasks, the calendar, messages, channels, the public web, the browser. The catalog holds 150 of them under protocol 0.4.0. Each one names who answers it: the task, calendar, people, leave and attendance tools run on the central plane against the record, the browser and model tools run only beside the agent, and the rest are carried to the company's computer. On the host the agent calls them over MCP through the relay, the same catalog the HTTP API serves. The catalog lists every one.

Workspace tools touch your files and the terminal: read, write, edit, run a command, deliver a finished file. They are built into the agent host (blueclaw) and execute as your own Linux user, so POSIX permissions bound what they can reach (Boundaries). See Files and the terminal.

What a side-effect class means

Every tool descriptor carries a sideEffectClass. It states what kind of mark running the tool leaves, and the approval gate reads it. The tool's name never decides.

ClassThe mark it leavesExamples
readnonetask_list, message_search, leave_balance
workspace_writea company record created or changedtask_add, event_update, write
external_writestate on the messenger changedmessage_update
external_senda message reaches peoplemessage_send
connecta session to something opensbrowser_open
destructivesomething irreversibletask_delete, message_delete

When the agent stops and asks

Whether a call pauses for your approval is descriptor metadata (requiresApproval), checked by the approval gate in .dependency/blueclaw/internal/approvalgate before the call executes. The catalog marks every tool the flag is set on, so read it there rather than from a list written by hand. Among workspace tools, file_delete is gated, and bash gates itself per call: the agent sets approvalRequired on a command it judges consequential.

One exemption: a message_send that lands in the conversation the agent is answering does not need a second yes. That is currentThread and currentChannel, a channel named by the current channel's ID, and a directMessage with no recipient asked from the requester's own direct conversation. A direct message to anyone else, or to the requester from a channel, still asks.

A held call is persisted to the task ledger as approval.hold_opened, so an approval survives a daemon restart. Approving replays the recorded call verbatim; declining tells the model to stop, and it is instructed never to retry a declined call.

Tools that come and go

Each descriptor carries an availability state (ok, not_connected, not_ready, not_allowed). Browser tools run in a browser on the company's computer, one per requester with its own profile. Tools from configured MCP servers join the same registry and meet the same gate. GET /api/v1/tools answers the base set your token reaches; ?live=true asks the company's computer what it can run right now.

How tools are named

A tool's name is the only part of it a model sees before deciding to call it, so the tools internkim owns follow one shape, and tools/verify-tool-naming fails a change that breaks it:

<namespace>_<subject>_<verb>        crm_opportunity_move
<namespace>_<verb>                  task_add

The namespace matches the descriptor's namespace. The subject is dropped when the namespace already names it, which is why event_add and crm_contact_add are both right. The verb comes last.

VerbMeansInstead of
addbring a new record into beingcreate, register, save
listseveral records, filteredindex, fetch
getone record, or one settings blockread, show
updatechange the named fields of a recordedit, modify, patch
deleteremove a recordremove, destroy
searchseveral records, ranked by a queryfind, lookup

Another verb is allowed only when the act is none of these and the domain has its own word for it: crm_opportunity_move moves a deal between stages, and person_invite sends an invitation. set is kept for a settings block written whole, where update would suggest that unnamed fields survive.

Every word in a name appears in the tool's own description, so the word a model learns from the description reaches the tool. Parameters are camelCase and spelled out, and a few carry a fixed meaning everywhere: <thing>Hint is a natural reference resolved server-side, limit caps the answer, query is what a search ranks against, scope says whose records a call reads, startsAt and endsAt are RFC 3339 instants, date is a YYYY-MM-DD day in the company's zone, and reason is why a record was written by hand.

The agent's kernel tools (bash, read, write, edit, plan, equip) are exempt. They carry the names other coding agents use, so a model recognizes them on its first turn. Tools from outside MCP servers keep their own names.

Where this is implemented

LayerWhereWhat it owns
descriptor sourceweb/src/lib/server/public-api/catalog/every field of every capability tool
descriptor shape.dependency/blueclaw/protocol/src/capability.tswhat a descriptor may say, and nothing about which tools exist
generated catalogpkg/capabilityprotocol/generated/capability-tools.jsonthe embedded, hash-validated copy Go code reads
descriptor groupinginternal/capabilities/protocol.gowhich descriptors each provider registers
config renderingtools/render-company-runtimereads capabilities.toolDescriptors out of the installed capabilityd into blueclaw's runtime.json
agent binding.dependency/blueclaw/internal/agentruntime/capability_tool_provider.govalidates descriptors, binds them into the model's tool set
approval gate.dependency/blueclaw/internal/approvalgate/turn_gate.goholds gated calls for a human
executioninternal/capabilityd/*_tool.gothe operation behind each namespace

Changing a tool means editing the TypeScript descriptor, running make generate-protocol, and shipping capabilityd and the blueclaw payload in the same release; blueclaw refuses a descriptor set whose protocol identity hash does not match its own, and a host picks up the new set when its package renders the runtime document again.

On this page