Skip to main content
Glama

append_to_document

Add content to existing documents in Mnemosyne knowledge graphs using TipTap XML, enabling incremental updates without replacing current content.

Instructions

Appends a block to the end of a document. Accepts TipTap XML for any block type. Use this for incremental additions without replacing existing content. For plain text, wrap in text. For structured content, provide full XML like Title or ....

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
graph_idYes
document_idYes
textYes

Implementation Reference

  • The core handler function that implements the append_to_document tool. It authenticates, connects to the Y.js document channel via HocuspocusClient, wraps plain text in paragraph XML if needed, appends the content using DocumentWriter.append_block within a transaction, retrieves the new block ID, and returns success status.
    async def append_to_document_tool( graph_id: str, document_id: str, text: str, context: Context | None = None, ) -> dict: """Append a block to a document. Args: graph_id: The graph containing the document document_id: The document to append to text: TipTap XML content. If it doesn't start with '<', it's wrapped in <paragraph>. """ auth = MCPAuthContext.from_context(context) auth.require_auth() if not graph_id or not graph_id.strip(): raise ValueError("graph_id is required") if not document_id or not document_id.strip(): raise ValueError("document_id is required") if not text: raise ValueError("text is required") try: # Connect to the document channel await hp_client.connect_document(graph_id.strip(), document_id.strip()) # Determine if text is XML or plain text content = text.strip() if not content.startswith("<"): # Plain text - escape and wrap in paragraph import html escaped_text = html.escape(content) content = f"<paragraph>{escaped_text}</paragraph>" new_block_id: str = "" def perform_append(doc: Any) -> None: nonlocal new_block_id writer = DocumentWriter(doc) writer.append_block(content) # Get the last block's ID reader = DocumentReader(doc) count = reader.get_block_count() if count > 0: block = reader.get_block_at(count - 1) if block and hasattr(block, "attributes"): # pycrdt XmlAttributesView.get() doesn't support default arg attrs = block.attributes new_block_id = attrs.get("data-block-id") if "data-block-id" in attrs else "" await hp_client.transact_document( graph_id.strip(), document_id.strip(), perform_append, ) result = { "success": True, "graph_id": graph_id.strip(), "document_id": document_id.strip(), "new_block_id": new_block_id, } return result
  • The @server.tool decorator registers the append_to_document tool on the FastMCP server, defining its name, title, description (which implies the schema via parameters: graph_id, document_id, text), within the register_hocuspocus_tools function.
    @server.tool( name="append_to_document", title="Append Block to Document", description=( "Appends a block to the end of a document. Accepts TipTap XML for any block type. " "Use this for incremental additions without replacing existing content. " "For plain text, wrap in <paragraph>text</paragraph>. For structured content, " "provide full XML like <heading level=\"2\">Title</heading> or <listItem listType=\"bullet\">...</listItem>." ), )
  • Invocation of register_hocuspocus_tools which defines and registers the append_to_document tool (and others) on the standalone MCP server instance.
    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