feat(mcp): automation-rule CRUD tools (#334)#211
Merged
Conversation
Expose automation-rule CRUD over MCP so an agent can build a complete
workflow end to end: list_automations, get_automation, create_automation,
update_automation, delete_automation.
The tools call the SAME endpoints the in-app RuleEditor uses, so
AutomationActionsService.validate() stays the one validator — no parallel
path. Human-readable trigger/action field references, select labels and
qualified space/database refs resolve to ids server-side (against
describe_database); anything not resolvable client-side (connections,
agents, relation targets) is validated by the API, which returns a
structured 422 surfaced as an isError result, never a 500. Reads annotate
every id with a sibling *_name for a faithful round-trip.
Scope: the AutomationsController is @RequiresScope('admin') and
creator-gated, so all five tools are advertised only to an admin-scoped
token — a read- or write-scoped PAT never sees them and can never mutate a
rule. delete_automation requires confirm=true and reports what it removed.
No API/SDK changes: the automation endpoints already existed in the
generated client. Docs + get_started updated with the build-a-workflow flow.
Signed-off-by: ikrasovytskyi <i.krasovytskyi@owox.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
storyos-docs | a4cbb33 | Commit Preview URL Branch Preview URL |
Jul 25 2026, 08:46 PM |
ikrasovytskyi
enabled auto-merge
July 25, 2026 20:46
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.
Exposes automation-rule CRUD over MCP so an agent can build a complete workflow end to end. Closes #334.
Tools added (all admin-scoped)
list_automations— a database's rules: trigger (field/relation names resolved), condition, actions, enabled state, failure streak, and last-run status.get_automation— one rule's full editable definition, human-readable database/field/select names alongside stable ids.create_automation— trigger (record_created/record_updated/record_linked/schedule/webhook_received) + optional condition (aquery_records-style filter) + 1–10 actions (set_values,create_record,add_comment,notify_user,update_linked,send_slack_message,send_webhook,send_email,http_request,run_agent).update_automation— rename, enable/disable, replace trigger/condition/actions; every field optional.delete_automation— requiresconfirm=true; reports the removed rule's name, trigger and action summary.Reuses the in-app validation (no parallel path)
Every tool calls the same endpoints the in-app RuleEditor uses (
AutomationsController→AutomationsService→AutomationActionsService.validate()), so that validator stays the single source of truth. Human-readable trigger/action field references, select labels and qualifiedspace/databaserefs resolve to ids client-side againstdescribe_database; anything not resolvable there (connections, agents, relation targets) is validated by the API. An unresolvable/stale reference returns a structured error (client-side, naming the candidates) or the API's 422 — surfaced as an MCPisErrorresult, never a 500. Reads inject a sibling*_namenext to every id for a faithful round-trip;hookSecret/lastHookPayloadare never surfaced.Scope enforcement
AutomationsControlleris@RequiresScope('admin')and creator-gated, so all five tools are advertised only to an admin-scoped token (mirrored inTOOL_SCOPE). A read- or write-scoped PAT never sees them and therefore can never mutate — or even list — a rule. This mirrors the API's existing enforcement exactly; there is no lower-privilege read path to invent (automations are an admin surface).No API/SDK changes
The automation endpoints already exist in the generated SDK client (list/create/patch/delete), so this is a pure MCP-consumer change — no
openapi.json/SDK drift, no migration. The API has no single-GET automation endpoint, soget_automation/delete_automationread the database's rule list and pick the row out (404-ing clearly on an unknown id).Verified
packages/mcpunit + integration tests (118 passing), incl. newautomations.test.ts:createAutomationSchema(the controller's DTO) — proving the resolved body is API-valid.record_updatedby field name) rule with an action.*_nameannotation.isError, not a throw/500, and no rule created.delete_automationconfirmation gate.pnpm --filter @storyos/mcp lint / typecheck / test / buildall green;pnpm docs:checkgreen (README +get_startedupdated with the build-a-workflow flow).Docker (
docker/mcp.Dockerfile) and the full monorepolint/typecheck/test/buildare left to CI (local disk was space-constrained); no new dependencies were added topackages/mcp, so the image build is unaffected.