feat: OnlyOffice office MCP tools (edit/generate/convert/export) + attachment images - EXO-88456#342
Open
bmestrallet wants to merge 5 commits into
Open
Conversation
…-88354 Add the security-critical shared service primitive used by the office MCP tools to CREATE and MODIFY native docx/xlsx/pptx via the ONLYOFFICE Document Builder: - runDocBuilderScript(scriptBody, assets, outputFormat, outputName, userId): stages the script + referenced assets in an in-memory, single-use, expiring registry and serves them to the Document Server through the EXISTING host-restricted (canDownloadBy) and JWT-guarded (validateToken) /onlyoffice/editor/content/{userId}/{key} endpoint, at URLs built from exo.base.url. The DS auto-signs the script fetch (Authorization header); in-script asset URLs carry a signed ?token= query param. Maps error codes to LLM-directed IllegalStateException. - saveNewVersion: writes Builder output back onto an existing node (MODIFY). - getContent short-circuits to the staged-asset registry (single-use). - content REST endpoint accepts the token via ?token= query param. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace create_office_document with a symmetric family of operations-based office tools that both CREATE (no document_id) and MODIFY (document_id given, saved as a new version) native office files via the ONLYOFFICE Document Builder, plus template-fill and conversion: - edit_spreadsheet (xlsx): set_cells, set_formula, add_chart, add_sheet - edit_presentation (pptx): add_slide, set_slide, add_image - edit_document (docx): add_heading, add_paragraph, add_table, add_image, replace_text, and a single set_html (routed to the HTML->docx conversion API, preserving the former create_office_document capability) - generate_document: template + {{placeholder}} search/replace merge - convert_document: format -> format via convertNodeContent - kept: export_document_as_pdf, get_document_editor_link Each edit_* tool builds a lean, format-specific Document Builder script (CreateFile or OpenFile -> apply operations -> SaveFile), gathers assets (existing file, images resolved from a URL via the SSRF-guarded UploadToolUtils or a DMS document_id), runs the shared runDocBuilderScript primitive, and stores a new file or a new version. The nested operations array is accepted as a JSON string (parsed server-side) because the MCP binder does not reliably bind nested arrays. All acts as the current user (ACL enforced via a user JCR session). ai-tool-definitions.json updated (create_office_document removed); -parameters flag and **/*.json resource include kept. 19 Mockito unit tests cover create/modify/failed-build/validation and the generated script for every tool. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lder generator - EXO-88354 The add_table generator emitted Api.CreateTable(colCount, rowCount) but the Document Server's Api.CreateTable is (nRows, nCols). A table with N rows was built with too few rows, so GetRow(r) for later rows threw a Row-index-out-of- bounds error (docbuilder ExitCode error:-80). Swapped to CreateTable(rowCount, colCount), verified against a live Document Server docbuilder endpoint. Validated every generator operation (spreadsheet set_cells/set_formula/ add_chart/add_sheet, presentation add_slide/set_slide/add_image, document add_heading/add_paragraph/add_table/add_image/replace_text, and the CreateFile vs OpenFile paths) against the live DS: all produce valid OOXML with the expected content. add_table was the only bug. Added golden-string regression tests pinning the exact emitted Document Builder script (add_table rows-first + last-cell addressing, set_cells GetRangeByNumber row/col order, add_chart 10-arg signature, add_slide, and the OpenFile modify path), with a class note that true API-correctness requires the manual DS check. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ability) - EXO-88354 - edit_spreadsheet: re-activate the primary data sheet before save so xlsx->PDF export renders it (DS exports only the active sheet). - edit_presentation: set explicit black text fill (shapes default to the light-1/white theme colour) and reuse the default slide 0 on create so slides show their text and there is no leading blank slide. - saveNewVersion (MCP modify): bind a SessionProvider when the thread has none (fixes the DocumentUpdateActivityListener NPE), and evict the cached editor Config after the write so reopening shows the new content, not a stale DS-cached copy. checkout before createVersion so current advances. - ai-tool-definitions.json: rename edit_* folder param to parent_folder_id. - Add saveNewVersion regression tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…cument add_image - EXO-88354 EVA forwards a chat-attached image by injecting the top-level string params attachment_object_type + attachment_object_id into any tool that declares both in its schema. Since the office tools carry images inside the opaque operations JSON string (which EVA cannot reach into), declare those two params at the tool level on edit_presentation and edit_document; the server applies the attachment to add_image ops that lack an explicit url/document_id. - OnlyofficeMcpTool: inject AttachmentService + FileService; add tool-level attachmentObjectType/attachmentObjectId, plumb through runEdit -> appendPresentationOps/appendDocumentOps -> resolveImageBytes. Resolution precedence: op url -> op document_id -> per-op attachment_object_* -> tool-level attachment_object_*. Attachment bytes resolved via the shared UploadToolUtils.resolveImage, ACL-enforced as the current user. - ai-tool-definitions.json: declare the two params on edit_presentation/ edit_document so EVA auto-fills them; edit_spreadsheet unchanged (no image op). Verified against the live Document Server: the attached PNG embeds byte-identical into ppt/media and word/media and renders in the exported PDF. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3dfad0e to
c33dd1f
Compare
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
Adds OnlyOffice office-document MCP tools for the EVA AI agent, driven by the OnlyOffice Document Builder:
edit_document,edit_spreadsheet,edit_presentation(create or modify),generate_document(from template),convert_document,export_document_as_pdf,get_document_editor_linkOnlyofficeApplication) so the kernel-only add-on exposes the@Service ... McpToolPluginbeans, plusai-tool-definitions.json.Fixes folded in
add_sheetleft blank).SessionProviderwhen the thread has none (fixes theDocumentUpdateActivityListenerNPE); checkout beforecreateVersion; evict the cached editor Config after the write so a reopen shows the new content.Api.CreateTableargument order.EVA chat-attachment images
edit_presentation/edit_documentdeclare top-levelattachment_object_type/attachment_object_id(EVA injects these for an image-capable tool);add_imageops without an expliciturl/document_idembed the attached image, resolved via the sharedUploadToolUtils.resolveImage(ACL-enforced as the user).Dependency / CI
Depends on mcp-server #13 (
UploadToolUtils, EXO-88348) — this branch's pom consumesmcp-server-tools:*-ai-contribution-SNAPSHOT. CI will be red until #13 merges and a consuming version is published.Known follow-up
Refining the attachment path: fall back to the chat attachment when a model-invented
urlfails to resolve, and tighten the editor-cache invalidation for the attachment-modify case.Board: EXO-88354.
🤖 Generated with Claude Code