Skip to main content
Glama

write_document

Replace document content with TipTap XML for real-time UI synchronization in Mnemosyne knowledge graphs. Supports collaborative editing with comments and structured formatting.

Instructions

Replaces document content with TipTap XML. Syncs to UI in real-time.

WARNING: This REPLACES all content. For collaborative editing, prefer append_to_document.

Blocks: paragraph, heading (level="1-3"), bulletList, orderedList, blockquote, codeBlock (language="..."), taskList (taskItem checked="true"), horizontalRule Marks (nestable): strong, em, strike, code, mark (highlight), a (href="..."), footnote (data-footnote-content="..."), commentMark (data-comment-id="...") Example: Text with highlight and a note

Comments: Pass a dict mapping comment IDs to metadata. Comment IDs must match data-comment-id attributes in the content. Example comments: {"comment-1": {"text": "Great point!", "author": "Claude"}}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
graph_idYes
document_idYes
contentYes
commentsNo

Implementation Reference

  • The main handler function that performs the write_document tool logic: authenticates, connects to the document via HocuspocusClient, replaces all content with provided TipTap XML, optionally adds comments, updates the workspace with document title, reads back to confirm, and returns the result.
    async def write_document_tool( graph_id: str, document_id: str, content: str, comments: Optional[Dict[str, Any]] = None, context: Context | None = None, ) -> dict: """Write TipTap XML content to a document.""" auth = MCPAuthContext.from_context(context) auth.require_auth() try: # 1. Write document content and comments await hp_client.connect_document(graph_id, document_id) def write_content_and_comments(doc: Any) -> None: writer = DocumentWriter(doc) writer.replace_all_content(content) # Write comments if provided if comments: for comment_id, comment_data in comments.items(): writer.set_comment( comment_id=comment_id, text=comment_data.get("text", ""), author=comment_data.get("author", "MCP Agent"), author_id=comment_data.get("authorId", "mcp-agent"), resolved=comment_data.get("resolved", False), quoted_text=comment_data.get("quotedText"), ) await hp_client.transact_document( graph_id, document_id, write_content_and_comments, ) # 2. Update workspace navigation so document appears in file tree # Extract title from first heading, fallback to document_id title = extract_title_from_xml(content) or document_id await hp_client.connect_workspace(graph_id) await hp_client.transact_workspace( graph_id, lambda doc: WorkspaceWriter(doc).upsert_document(document_id, title), ) # 3. Read back document content and comments to confirm channel = hp_client.get_document_channel(graph_id, document_id) if channel is None: raise RuntimeError(f"Document channel not found: {graph_id}/{document_id}") reader = DocumentReader(channel.doc) xml_content = reader.to_xml() result_comments = reader.get_all_comments() result = { "success": True, "graph_id": graph_id, "document_id": document_id, "title": title, "content": xml_content, "comments": result_comments, } return result except Exception as e: logger.error( "Failed to write document", extra_context={ "graph_id": graph_id, "document_id": document_id, "error": str(e), }, ) raise RuntimeError(f"Failed to write document: {e}")
  • The @server.tool decorator that registers the write_document tool with FastMCP, specifying name, title, and detailed description serving as input/output schema.
    @server.tool( name="write_document", title="Write Document Content", description="""Replaces document content with TipTap XML. Syncs to UI in real-time. WARNING: This REPLACES all content. For collaborative editing, prefer append_to_document. Blocks: paragraph, heading (level="1-3"), bulletList, orderedList, blockquote, codeBlock (language="..."), taskList (taskItem checked="true"), horizontalRule Marks (nestable): strong, em, strike, code, mark (highlight), a (href="..."), footnote (data-footnote-content="..."), commentMark (data-comment-id="...") Example: <paragraph>Text with <mark>highlight</mark> and a note<footnote data-footnote-content="This is a footnote"/></paragraph> Comments: Pass a dict mapping comment IDs to metadata. Comment IDs must match data-comment-id attributes in the content. Example comments: {"comment-1": {"text": "Great point!", "author": "Claude"}}""", )
  • The call to register_hocuspocus_tools(mcp_server) in the create_standalone_mcp_server function, which triggers the definition and registration of all hocuspocus tools including write_document.
    register_basic_tools(mcp_server) register_graph_ops_tools(mcp_server) register_hocuspocus_tools(mcp_server)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sophia-labs/mnemosyne-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server