th-8b7d36: configure Smooth Operator's tools from th + Claude Desktop#251
Merged
Conversation
Closes the loop on epic th-093ce3: you can now not only TALK to the org operator from th/Claude Desktop, but also configure what it's allowed to do from the same place. - `th api smooth-operator tools list|enable|disable` - MCP `operator_tools` (read-only) + `operator_tools_set` - shared client in smooai::smooth_operator (list_operator_tools / set_operator_tool / render_tool_catalog), reused by both surfaces Writes are read-modify-write deliberately: the PUT body is authoritative and the server treats an omitted tool as ENABLED, so a single-entry body would silently re-enable every other tool. We re-read the catalog, flip one, send all. Server side is smooai PR #3380 (admin-gated); until that ships these return a clean 404. Server instructions tell the model to confirm with the user before calling operator_tools_set — it changes what the AI may do for the whole org. 377 tests pass; clippy clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZctFb4oiWoJraHN2db1nX
brentrager
enabled auto-merge (squash)
July 23, 2026 23:20
🦋 Changeset detectedLatest commit: a44370c The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Closes the loop on epic th-093ce3: you can already talk to your org's Smooth Operator from
th/ Claude Desktop (#249) — now you can configure what it's allowed to do from the same place.th api smooth-operator tools list | enable <id> | disable <id>operator_tools(read-only) +operator_tools_set— so "what can my operator do?" and "turn off email.send" work from Claude Desktop / Cursorsmooai::smooth_operator(list_operator_tools/set_operator_tool/render_tool_catalog) reused by both surfacesThe correctness detail that matters
Writes are read-modify-write by design. The PUT body is authoritative and the server treats any tool omitted from it as enabled — so sending a single-entry body would silently re-enable every other tool.
set_operator_toolre-reads the full catalog, flips exactly one entry, and sends all of it.Safety
Org-admin only (enforced server-side by smooai #3380). The server instructions tell the model to confirm with the user before calling
operator_tools_set— it changes what the AI may do for the whole org — and to expect a 403 for non-admins.Verification
operator_toolsreturns a clean, actionable 404 today because its endpoint ships with smooai #3380 (not yet merged/deployed). Client side is correct and ready.enableddefaults to true when absent (an absent org config means everything is on — defaulting false would read as "all off"), and the renderer marks disabled/destructive correctly.🤖 Generated with Claude Code