Targeted Code and Instruction Edits
Read selected lines and apply exact-text changes through existing Copilot and MCP tools, with revision protection.
Use targeted edits when changing a few lines of Python or a section of workflow instructions. Existing read and update tools support them; you do not need a separate resource or patch tool.
Supported resources
| Resource | Read tool | Update tool | Text field |
|---|---|---|---|
| Python action | get_action_details (actionType: "python") | update_python_action | code |
| Condition provider | get_condition_provider | update_condition_provider | code |
| Event handler | get_event_handler | update_event_handler | code |
| Recurring job | get_recurring_job | update_recurring_job | code |
| Shared module | get_python_module | update_python_module | code |
| HTTP endpoint | get_http_endpoint | update_http_endpoint | code |
| Sidebar widget | get_sidebar_widget_details | update_sidebar_widget | code |
| Sidebar widget action | get_sidebar_widget_action | update_sidebar_widget_action | code |
| Product-sync parser | get_product_sync_parser | upsert_product_sync_parser | code |
| Workflow variant | get_workflow | update_workflow_variant | botInstructions |
| Comment workflow | get_comment_workflow | update_comment_workflow | botInstructions, dmBotInstructions |
| Review workflow | get_review_workflow | update_review_workflow | botInstructions |
| Custom Python prompt section | get_bot_config | update_bot_config | systemPromptSectionCode |
This interface edits text fields, not arbitrary JSON paths. Nested review email steps and legacy review-category configurations are not covered.
Read all text, selected lines, or search matches
Omit selection arguments to read the full content. To read selected Python lines:
{
"organizationId": "your-organization-id",
"actionId": "your-action-id",
"actionType": "python",
"codeSelection": { "startLine": 100, "endLine": 160 }
}Line numbers are 1-based and inclusive. Omit startLine to begin at line 1 or endLine to read through the end. Out-of-range or reversed ranges fail.
To search literal text with context:
{
"organizationId": "your-organization-id",
"actionId": "your-action-id",
"actionType": "python",
"codeSelection": { "find": "def execute_action", "contextLines": 10 }
}Search and line ranges cannot be combined. Search is literal and case-sensitive; default context is five lines. Search results identify all match counts and return context for at most the first 50 matches. Nearby windows are merged, and omitted matches are explicitly marked as truncated. A missing search match returns zero matches, not an arbitrary excerpt.
A selected read returns its text in code, with line boundaries in codeRead.excerpts, the total line count in codeRead.totalLines, and an opaque codeRevision for the complete code field. Copy that revision into the update call. Full reads also return the revision. Do not calculate revision tokens yourself.
For workflow instructions, use botInstructionsSelection and copy botInstructionsRevision. On get_workflow, also provide variantId when selecting or searching instructions. This returns only that variant; omitting both arguments retains the full workflow read. The variant must belong to the requested workflow.
Make exact-text edits
Call the resource's existing update tool. For example, update_python_action:
{
"organizationId": "your-organization-id",
"actionId": "your-action-id",
"expectedCodeRevision": "revision-from-the-read-response",
"codeEdits": [
{
"oldText": "return status == \"returned\"",
"newText": "return status in {\"returned\", \"return_to_sender\"}"
}
]
}Each oldText must match exactly once, including whitespace, indentation and newline characters. If there are multiple matches, include more surrounding text to identify the intended occurrence. If there are no matches, read the current content and copy the text exactly. The tool never silently picks the first occurrence or replaces every occurrence.
Edits apply in array order, so a later edit sees the result of earlier edits. The whole call succeeds together or nothing is saved. Empty newText deletes the matched text. To insert text, replace an existing anchor with that anchor plus the addition. Empty oldText is invalid.
For workflow variants, use botInstructionsEdits and expectedBotInstructionsRevision. Comment DM instructions use dmBotInstructionsEdits and expectedDmBotInstructionsRevision. The custom Python prompt section uses systemPromptSectionCodeEdits and expectedSystemPromptSectionCodeRevision.
For update_http_endpoint, editing arguments belong inside its existing endpoint object. For update_review_workflow, they belong inside updates. Resource IDs and organizationId stay at their existing locations.
Full replacements remain available
Use fullCode to deliberately replace the entire script. It requires expectedCodeRevision from the read tool. For instructions use fullBotInstructions; for DM instructions use fullDmBotInstructions. Custom prompt code uses fullSystemPromptSectionCode. Each uses the corresponding expected revision.
For each text field, provide only one mode: full replacement or edits. Both are optional because settings-only updates, such as renaming or disabling a resource, do not change its text. An expected revision without a corresponding text change is invalid.
The existing code, botInstructions, dmBotInstructions, and systemPromptSectionCode arguments remain deprecated full-replacement aliases for existing clients. Old calls without revisions retain their existing behavior; prefer the explicit full fields or edits with revision protection. Do not combine an alias with the new replacement or edits argument for the same field.
Create tools still accept full content. To create the first product-sync parser, use the existing upsert_product_sync_parser call with code. Its new full/edit interface requires an existing parser; it cannot patch an absent resource or a hidden legacy provider mapping.
Verify and recover
The server locks the resource in a database transaction before checking its revision and saving. If its text changed since the read, the entire update is rejected. Read it again, reassess the change, and retry with the new token. Repeated retries using the same stale token will not work.
Successful updates through the new interface return textChanges, keyed by the edited field. Each entry contains the saved revision, a before/after diff, and diffTruncated. The response omits the resource's large text fields. Diff output is bounded; when it is truncated or computation exceeds its limit, use a selected read to inspect the saved section.
Existing field constraints, resource permissions, approval behavior and version-history paths still apply. Updating code does not automatically execute it. Run the resource's existing test tool when you need to verify behavior, remembering that test execution can have real side effects.