update_paragraph
[MAINTENANCE] f978e588 — ID-addressable docx WRITE (the write counterpart of the get_element_by_id / paraId read primitive). Targets ONE paragraph in a stored .docx by its w14:paraId (the 'p{index}' fallback Word writes for an unlabelled paragraph) — NEVER by text match — rewrites its runs, saves...
This record as markdown: /tools/io-github-ajc3xc-meridian/update-paragraph.md
What update_paragraph does on Meridian
AI agents use update_paragraph to create or update resources in Meridian, usually the action step of a workflow, after the agent has gathered context. Every call changes real data in your Meridian environment.
| Parameter | Type | Required | Description |
|---|---|---|---|
doc | string | Yes | The stored document's source (the path/URL you ingested it under via ingest_document, which registers a docx/latex document in the doc-structure store). |
runs | array | — | List of runs — each a plain string or a {text, bold?, italic?, underline?} object. Provide this OR new_text, not both. |
para_id | string | Yes | The target paragraph's w14:paraId (or 'p{index}' fallback), as reported by the read side. |
new_text | string | — | New paragraph text as a single unformatted run. Provide this OR runs, not both. |
project_id | string | — | |
session_id | string | — | f7ee1ba7 — calling session id. When provided, scoped-region claim enforcement activates: the write is rejected if another session claims the target para_id or h |
wave_run_id | string | — | 5988a5bb — the wave identifier scoping this draft's meridian.db.docx_merge manifest. Must be given together with draft_output_path and session_id. |
project_name | string | — | Project name — an alternative to project_id; resolved to the id internally. project_id wins if both are given. |
draft_output_path | string | — | 5988a5bb — opt-in wave-scoped draft mode: write to this isolated path instead of the canonical `doc`. Must be given together with wave_run_id and session_id; mu |
expected_content_hash | string | — | 5988a5bb — opt-in fail-closed precondition: the write is rejected BEFORE touching the file if this doesn't match the source's CURRENT on-disk content hash. Omit |
Parameters from the server's own tool schema.
Why update_paragraph is rated Medium
This tool creates or modifies data reversibly by updating paragraph content within a .docx document and saving it. While it modifies stored state, the changes are reversible (the original document can be re-modified or restored), making it Write rather than Destructive.
From the tool's definition Tool description explicitly states 'WRITE' and describes 'rewrites its runs, saves the .docx in place, and re-syncs the doc_elements index row'. The operation modifies and persists content in a stored document.
Risk signalsHigh parameter count (10 properties)
Attacks that exploit this kind of access
The rule that runs update_paragraph safely
PolicyLayer is an MCP gateway: it sits between your AI agents and Meridian, and checks every tool call against a rule you set before the call runs. Nothing changes on the server itself. For update_paragraph, this is the rule to start with:
update_paragraph stays usable, but capped: an agent stuck in a loop can't make hundreds of changes a minute. Everything else on the server is denied unless you say otherwise.
The button opens the PolicyLayer dashboard: create your workspace, connect Meridian, apply this rule, and every update_paragraph call is checked against it from then on.
Questions about update_paragraph
[MAINTENANCE] f978e588 — ID-addressable docx WRITE (the write counterpart of the get_element_by_id / paraId read primitive). Targets ONE paragraph in a stored .docx by its w14:paraId (the 'p{index}' fallback Word writes for an unlabelled paragraph) — NEVER by text match — rewrites its runs, saves the .docx in place, and re-syncs the doc_elements index row so it matches the new text. The document must already be stored in the doc-structure store via ingest_document (which registers a docx/latex document's structure here). Pass the SAME source/path you ingested under as doc. Provide EXACTLY ONE of: new_text (a plain string — one unformatted run) OR runs (a list of runs, each a bare string or {text, bold?, italic?, underline?} — basic run formatting is applied; the paragraph's original run formatting is replaced, not merged; its paragraph style/numbering is preserved). Returns {document_id, para_id, new_text, elements_resynced, source_path}. elements_resynced is 0 for a plain body paragraph (only headings are persisted as elements) — that is expected, not a failure. Errors (never a silent no-op) when the doc/source/para_id doesn't resolve. f7ee1ba7 — pass session_id to enable scoped-region claim enforcement: if another session has claimed the target para_id (or holds a whole-file lock), the write is REJECTED with error='docx_region_conflict'. Use claim_docx_region to acquire your region before writing. 5988a5bb — mandatory post-write verification now re-reads the file from disk and confirms the target paragraph's text actually landed before this ever reports success; on a rare verification failure the write is best-effort restored from backup and an error is returned instead. Response also now includes pre_counts/post_counts (the media/style/equation/relationship structural manifest from before and after the write). Three further OPT-IN parameters (each omitted by default, byte-identical behavior when omitted): expected_content_hash — a fail-closed precondition: if the source file's current on-disk content hash doesn't match, the write is REJECTED before anything is touched (get the current hash from a prior get_document_structure/get_structure staleness check). draft_output_path + wave_run_id (both-or-neither, with session_id also required) — writes to an ISOLATED draft path instead of the canonical file, claiming the paragraph as this wave's anchor via the real docx-merge manifest so a conflicting concurrent draft on the same paragraph is rejected; response carries draft_path/wave_run_id/ is_draft instead of elements_resynced (the canonical index is not touched until a merge). Persistent-state disclosure: on hosted Meridian, supplied text and project/session metadata are sent to and stored in Meridian's service; self-hosted deployments keep them in the configured local SQLite/Postgres database. This data is visible in the dashboard/API and later project context or handoffs. Delete individual tasks, notes, or decisions where supported, or delete the project/account using the documented controls. Do not include secrets. It is categorised as a Write tool in the Meridian MCP Server, which means it can create or modify data. Consider rate limits to prevent runaway writes.
update_paragraph accepts 10 parameters: doc, runs, para_id, new_text, project_id, session_id, wave_run_id, project_name, draft_output_path, expected_content_hash. Required: doc, para_id. The full parameter table on this page comes from the server's own tool schema.
Register the Meridian MCP server in PolicyLayer and add a rule for update_paragraph: 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 Meridian. Nothing to install.
update_paragraph 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_paragraph 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_paragraph. 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_paragraph is provided by the Meridian MCP server (@meridianmcp/mcp). PolicyLayer sits as a proxy in front of this server to enforce policies before tool calls reach the server.
More on Meridian, and thousands of servers like it.
This server
Across the catalogue