Surgical edit of workflow.context (and workflow.metadata) — the workflow-level analog of update_step. Does NOT reach into steps (use update_step for that). Calling shape (preferred): three explicit verbs { updates, replace, unset } — same merge model as update_step, but on workflow-relative paths...
Risk signalsAdmin/system-level operation
Part of the Agentled server.
Free to start. No card required.
AI agents use update_workflow_context to create or modify resources in Agentled. Write operations carry medium risk because an autonomous agent could trigger bulk unintended modifications. Rate limits prevent a single agent session from making hundreds of changes in rapid succession. Argument validation ensures the agent passes expected values.
Without a policy, an AI agent could call update_workflow_context repeatedly, creating or modifying resources faster than any human could review. PolicyLayer's rate limiting ensures write operations happen at a controlled pace, and argument validation catches malformed or unexpected inputs before they reach Agentled.
Write tools can modify data. A rate limit prevents runaway bulk operations from AI agents.
{
"version": "1",
"default": "deny",
"tools": {
"update_workflow_context": {
"limits": [
{
"counter": "update_workflow_context_rate",
"window": "minute",
"max": 30,
"scope": "grant"
}
]
}
}
} See the full Agentled policy for all 119 tools.
These attack patterns abuse exactly the kind of access update_workflow_context gives an agent. Each links to the full case and the policy that stops it:
Other write tools across the catalogue. The same approach applies to each: rate-limit and validate the arguments.
Surgical edit of workflow.context (and workflow.metadata) — the workflow-level analog of update_step. Does NOT reach into steps (use update_step for that). Calling shape (preferred): three explicit verbs { updates, replace, unset } — same merge model as update_step, but on workflow-relative paths. At least one must be non-empty. - updates — partial workflow patch. Top-level keys are limited to context and metadata. Each is shallow-merged ({ ...stored, ...patch }) so omitting a sibling preserves it. Direct sub-objects under context (e.g. executionInputConfig) are still replaced wholesale by default — use replace[] for explicit deep replacement, unset[] for deletion. - replace: string[] — workflow-relative dot-paths whose values from updates are assigned WHOLESALE, skipping the deep-merge. Path examples: "context.executionInputConfig.fields", "context.inputPages", "metadata.tags". The path's value MUST be present in updates. - unset: string[] — workflow-relative dot-paths to delete. Each must currently exist on the workflow. What lives under context workflow.context holds two things, side by side as siblings: 1. Page schemas — context.inputPages, context.outputPages, context.executionInputConfig. Field definitions, defaults, shortDescriptionFields, etc. 2. User-saved page values — context.<contextKey>, where <contextKey> mirrors a page's contextKey. e.g. context.outreachProfile, context.cadence, context.introductionWorkflow. These are the values a user persists when clicking "Save" on a configuration input page. Page entry shapes (read these BEFORE writing to context.outputPages or context.inputPages) The workflow detail UI crashes on load if a page entry is missing required fields, and validate_workflow now rejects bad shapes with MISSING_OUTPUT_PAGE_FIELD / INVALID_OUTPUT_STEPS_TYPE. - context.outputPages — PipelineOutputPage[]. Authoritative example: get_step_schema({ stepType: "outputPage", shape: "standard" }). - Required: id (string, unique), title (string), pathname (string, URL slug), outputSteps (string[] of step IDs that exist in workflow.steps). - Optional: description, iconName, displayConfig.showExecutionsList (boolean), displayConfig.executionNameTemplate, displayConfig.filterStatuses, displayConfig.defaultFilterStatus, displayConfig.sortField, displayConfig.sortDirection. - context.inputPages — PipelineInputPage[]. Authoritative example: get_step_schema({ stepType: "inputPage", shape: "standard" }). - Required: title, pathname, configuration.contextKey, configuration.fields[]. Saved values land at context.<contextKey> (sibling). Both shapes are dictionaries the workflow author owns, both are read at runtime via {{context.<key>.<field>}}, and both are edited through this tool with the same three-verb model. To pre-fill a config page programmatically: jsonc update_workflow_context({ workflowId, updates: { context: { outreachProfile: { name: "Alberto", signature: "<p>Best, Alberto</p>" } } } }) Sibling context keys are preserved by the one-level deep-merge. Live workflows route to draft. Allowed path scope (both replace and unset) Paths must begin with one of: - context.<anything> — page schemas (context.inputPages, …) or user-saved page values (context.outreachProfile, context.cadence, …). - metadata (exact, or any metadata.* sub-path). Anything else (e.g. steps.*, name, goal, status) is rejected with PATH_OUT_OF_SCOPE. Use update_step for step-level edits and update_workflow for top-level scalars (name, goal, description, style). Diff and warnings The ops shape returns diff: { addedPaths, changedPaths, removedPaths } and warnings[]. If ≥6 fields were silently removed without an explicit unset, a warning fires — that's usually a "you wiped a dictionary" signal. Read it. Errors (400) | Code | When | |---|---| | EMPTY_PAYLOAD | All three of updates/replace/unset are missing or empty. | | INVALID_PATH | Dot-path syntax violation (empty segment, leading/trailing dot, prototype-pollution segment). | | PATH_OUT_OF_SCOPE | Path is not under context.<anything> or metadata (e.g. steps.*, name). | | REPLACE_VALUE_MISSING | A replace[] path has no corresponding value in updates. | | UNSET_PATH_NOT_FOUND | An unset[] path doesn't exist on the workflow. | Draft routing (live workflows) Context edits are routed to a draft snapshot (editingDraft: true). Metadata is NOT part of the snapshot config — metadata edits write directly to the Pipeline row, immediately and on the live workflow. ⚠ Mixed metadata + context in one call: metadata is applied immediately while context goes to the pending draft. discard_draft reverts the pending context changes but does NOT revert metadata. If you need a single atomic checkpoint covering metadata too, call create_snapshot first, or split the call. Compatibility body shape A legacy { contextKey, value } shape is still accepted for one-shot wholesale replacement of a single root context key (inputPages / outputPages / executionInputConfig only — saved-values keys are not reachable through this shape). It does not return diff / warnings and cannot edit metadata. Prefer the three-verb shape above for new code. Recipes jsonc // Add a single field to executionInputConfig.fields without rebuilding the array. // Step 1: get_workflow → read context.executionInputConfig.fields // Step 2: { updates: { context: { executionInputConfig: {...full new value with the appended field...} } }, replace: ["context.executionInputConfig"] } // Replace inputPages wholesale. { updates: { context: { inputPages: [...new pages...] } }, replace: ["context.inputPages"] } // Pre-fill a config page (user-saved values land at context.<contextKey>). // Uses one-level deep-merge under updates.context — sibling saved-values // dictionaries are preserved. { updates: { context: { outreachProfile: { name: "Alberto", signature: "<p>Best, Alberto</p>" } } } } // Wholesale-replace a single saved-values dictionary. { updates: { context: { cadence: { firstNudgeDays: 3, secondNudgeDays: 7 } } }, replace: ["context.cadence"] } // Delete a saved-values dictionary. { unset: ["context.introductionWorkflow"] } // Add a metadata tag. { updates: { metadata: { tags: ["beta"] } } } // Save an operator-facing executive summary for a workflow or workflow group. // Use this when a user asks to save a summary for the workflow, cluster, group, // or home card. Store it in metadata, not as KG text, unless the user explicitly // asks for a reusable knowledge note. For groups, write once to the owner // pipeline: prefer workflowGraph.role === "orchestrator"; otherwise use the // lowest workflowGraph.order pipeline. Keep body short, include concrete metrics // and the reporting period when available, and set author to the active // workspace agent (for example "by AngelHive Assistant"), not the external // coding/tool agent. { updates: { metadata: { executiveSummary: { body: "Startup Outreach sent 46 founder emails for the reporting period, with 28 opens and 9 clicks: a 60.9% open rate, 19.6% click rate, and 32.1% click-to-open rate.", bullets: ["Clicks: 6 UTM Pitch Night, 2 plain Pitch Night, 1 calendar."], generatedAt: "2026-06-03T00:00:00.000Z", author: "by AngelHive Assistant" } } } } // Delete an obsolete metadata key. { unset: ["metadata.legacyFlag"] } // Toggle executionInputConfig.internal: fetch first (get_workflow), merge locally, replace at the // PARENT level. The one-level deep-merge under updates.context wipes nested-object siblings BEFORE // replace[] runs (same merge-order trap as update_step) — so replace at "context.executionInputConfig" // (not ".internal") and pass the full object in updates. { updates: { context: { executionInputConfig: {...full merged executionInputConfig with internal: true...} } }, replace: ["context.executionInputConfig"] } Response: { editingDraft?, context, metadata?, diff?, warnings?, validation }.. It is categorised as a Write tool in the Agentled MCP Server, which means it can create or modify data. Consider rate limits to prevent runaway writes.
Register the Agentled MCP server in PolicyLayer and add a rule for update_workflow_context: allow, deny, rate-limit, or require approval. Point your MCP client at the PolicyLayer proxy URL and the rule is enforced on every call, before it reaches Agentled. Nothing to install.
update_workflow_context is a Write tool with medium risk. Write tools should be rate-limited to prevent accidental bulk modifications.
Yes. Add a rate_limit block to the update_workflow_context rule in your PolicyLayer policy. For example, setting max: 10 and window: 60 limits the tool to 10 calls per minute. Rate limits are tracked per agent session and reset automatically.
Set action: deny in the PolicyLayer policy for update_workflow_context. The AI agent will receive a policy violation error and cannot call the tool. You can also include a reason field to explain why the tool is blocked.
update_workflow_context is provided by the Agentled MCP server (@agentled/mcp-server). PolicyLayer sits as a proxy in front of this server to enforce policies before tool calls reach the server.
Deterministic rules across all 119 Agentled tools. Per-identity grants. Full audit log. Live in minutes. Nothing to install.
Free to start. No card required.
4,600+ MCP servers and 31,000+ tools scanned and risk-classified.