AFFiNE MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| AFFINE_EMAIL | No | Email address for AFFiNE authentication (self-hosted deployments). | |
| MCP_TRANSPORT | No | Transport mode for the server: 'stdio' (default) or 'http'. | stdio |
| AFFINE_BASE_URL | No | Base URL of the AFFiNE instance. Example: https://your-affine-instance.com | |
| AFFINE_PASSWORD | No | Password for AFFiNE authentication (self-hosted deployments). | |
| AFFINE_API_TOKEN | No | Compatible GraphQL bearer token for older deployments that still accept it. | |
| AFFINE_GRAPHQL_PATH | No | Custom GraphQL endpoint path for self-hosted AFFiNE instances. | |
| AFFINE_TOOL_PROFILE | No | Tool exposure profile: 'read_only', 'core', 'authoring', or 'full' (default). | full |
| AFFINE_MCP_AUTH_MODE | No | Authentication mode for the MCP HTTP endpoint. For example, 'bearer'. | |
| AFFINE_DISABLED_TOOLS | No | Comma-separated list of individual tool names to disable. | |
| AFFINE_MCP_HTTP_TOKEN | No | Bearer token required when AFFINE_MCP_AUTH_MODE is set to 'bearer'. | |
| AFFINE_DISABLED_GROUPS | No | Comma-separated list of tool groups to disable, e.g., 'docs.database,destructive'. | |
| AFFINE_OAUTH_ALLOW_SERVICE_WRITES | No | Set to 'true' to allow write operations when using OAuth mode. Defaults to read-only. | false |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| prompts | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_workspacesA | List available AFFiNE workspaces with best-effort profile metadata and direct URLs |
| get_workspaceA | Get workspace details with best-effort profile metadata and a direct URL |
| create_workspaceA | Create a new workspace with initial document (accessible in UI) |
| update_workspaceC | Update workspace settings |
| delete_workspaceA | Delete a workspace permanently and report success only when AFFiNE confirms the mutation. |
| list_docsA | List documents in a workspace (GraphQL), falling back to bounded workspace metadata when GraphQL document access is denied. Each doc includes an inTrash flag; fallback summary, public, and defaultRole values are null. GraphQL and fallback cursors are not interchangeable; restart pagination without after if a cursor is rejected. |
| search_docsA | Fast search for documents by title using workspace metadata. Much faster than exporting each doc. Returns docId, title, direct URL, and inTrash for each match. |
| find_doc_by_titleA | Resolve docs by exact title. Returns ALL matches up to |
| list_tagsA | List all workspace-level tags and the number of documents attached to each tag. Use this before tag mutation when the exact tag name or id is unknown. |
| list_docs_by_tagA | List documents that contain the requested tag. This is read-only and each result includes title metadata and an inTrash flag. |
| create_tagA | Create a workspace-level tag entry for future reuse. This does not attach the tag to a document; use add_tag_to_doc for that. |
| add_tag_to_docA | Attach a workspace tag to a document, creating the workspace tag option if needed. This updates workspace metadata and attempts to sync the document's own metadata. |
| remove_tag_from_docA | Detach a tag from one document without deleting the workspace-level tag. Use delete_tag only when the tag should be removed from every document. |
| delete_tagA | Delete a workspace-level tag and remove it from every document that references it. Accepts a tag id or name; an ambiguous name is rejected with the candidate ids. |
| get_docA | Read GraphQL metadata for one document, such as title, summary, public state, roles, and timestamps. Use read_doc when you need block content. |
| read_docA | Read document block content via WebSocket snapshot (blocks + plain text). Set includeMarkdown: true to also get the rendered markdown — useful when you need to read content without a separate export_doc_markdown call. |
| get_capabilitiesA | Return machine-readable capability flags for this MCP server, including block, database, collaboration, and export support. |
| analyze_doc_fidelityA | Inspect a document for markdown export fidelity risk, including unsupported AFFiNE block flavours and risky content paths. |
| move_docA | Move a doc in the AFFiNE sidebar. The destination link is validated and added before the optional source link is removed, cycles are rejected, and partial outcomes are reported explicitly. |
| publish_docA | Make a document publicly accessible through AFFiNE public sharing. This changes sharing state; use revoke_doc to disable public access later. |
| revoke_docA | Disable public sharing for a document without deleting the document. Use delete_doc only when the document itself should be removed. |
| create_docA | Create a new AFFiNE document with optional content. If parentDocId is provided, the new doc is linked into the sidebar tree immediately. If folderId is provided, the doc is placed inside that folder in the sidebar. |
| create_semantic_pageB | Create an AFFiNE-native page with intentional section structure and native block composition. |
| append_semantic_sectionB | Append a semantic section to an existing AFFiNE document by heading title and native block composition. |
| append_blockA | Append document blocks with canonical types and legacy aliases (supports placement + strict validation). |
| export_doc_markdownC | Export AFFiNE document content to markdown. |
| export_with_fidelity_reportA | Export document markdown together with a structured fidelity report that highlights markdown loss risk and unsupported AFFiNE-native content. |
| create_doc_from_markdownA | Create a new AFFiNE document and import markdown content. Use parentDocId to automatically embed the new doc into a parent, making it visible in the sidebar instead of being an orphan. |
| append_markdownB | Append markdown content to an existing AFFiNE document. |
| replace_doc_with_markdownB | Replace the main note content of a document with markdown content. |
| delete_docA | Delete a document, wait for the AFFiNE WebSocket outcome, and report workspace-metadata and content deletion separately. This is destructive; use revoke_doc when you only need to remove public access. |
| list_workspace_treeA | Returns the full document hierarchy as a tree (roots → children → grandchildren). Use depth to limit nesting (default: 3). Note: loads all docs — may be slow on large workspaces. Each node includes an inTrash flag. |
| get_orphan_docsA | Find all documents that have no parent (not linked from any other doc via embed_linked_doc / embed_synced_doc blocks or inline LinkedPage references). Useful for workspace hygiene. Note: scans all docs — O(n). Each doc includes an inTrash flag. |
| list_childrenA | List the direct children of a document in the sidebar (embed_linked_doc / embed_synced_doc blocks and inline LinkedPage references). Returns docId, title, URL, and inTrash for each child. |
| update_doc_titleA | Rename a document — updates both the sidebar title (workspace metadata) and the doc's internal page block title. |
| inspect_template_structureA | Inspect a template doc's native structure, tags, and fallback risk before instantiation. |
| instantiate_template_nativeA | Instantiate a template using native AFFiNE block cloning when supported, falling back to markdown materialization only when necessary. |
| add_database_rowA | Add a row to an AFFiNE database block. Provide cell values mapped by column name or column ID. Title column text is stored on the row paragraph block. Select columns auto-create options by label. |
| delete_database_rowB | Delete a row from an AFFiNE database block. |
| read_database_cellsA | Read row titles and database cell values from an AFFiNE database block. |
| read_database_columnsA | Read schema metadata for an AFFiNE database block, including columns, select options, and view column mappings. Useful for empty databases before any rows exist. |
| update_database_rowA | Batch update multiple cells on an existing AFFiNE database row. Include |
| compose_database_from_intentA | Create a useful AFFiNE database/data-view from declarative intent. Supports task_board and issue_tracker presets with starter schema, kanban view, and optional starter rows. |
| add_database_columnA | Add a column to an existing AFFiNE database block. Supports rich-text, select, multi-select, number, checkbox, link, date types. |
| add_surface_elementA | Add a shape, connector, text, or group to the AFFiNE edgeless canvas surface. Shapes support rect/ellipse/diamond/triangle with fill, stroke, and text. Connectors draw arrows between shapes (by id) or between absolute points. Use for building diagrams programmatically. Style fields that don't apply to the chosen element type are reported in the response 'ignored' list (mirrors update_surface_element). |
| list_surface_elementsA | List all shape/connector/text/group elements on the AFFiNE edgeless canvas surface. Returns raw xywh strings plus parsed {x,y,width,height} bounds, with Y.Text fields serialized to plain strings. Optional filters by element type or id. |
| update_surface_elementA | Partially update a surface element by id. x/y/width/height merge with the element's current xywh (move without resizing, or vice versa). text/label/title replace their Y.Text wholesale. Fields that don't apply to the element's type are reported in the response 'ignored' list. |
| delete_surface_elementA | Delete a surface element by id. Set pruneConnectors=true to also delete any connectors whose source or target referenced the deleted element. |
| update_frame_childrenA | Replace a frame block's contents wholesale. Accepts ids of surface elements (shapes/connectors/groups) AND edgeless blocks (notes/frames/edgeless-text) — all go into BlockSuite's prop:childElementIds map, matching what the editor writes when you drag members into a frame. Dragging the frame drags every owned member. Ids that don't resolve come back under 'missing'. By default the frame is resized to fit its new contents (plus padding + title band); set resizeToFit=false to leave xywh untouched. Pass |
| update_edgeless_blockA | Partially update a note/frame/edgeless-text block by id. x/y/width/height merge with current prop:xywh (move without resizing, or vice versa). background replaces prop:background (AFFiNE token or |
| delete_blockA | Delete a block by id. Removes descendants and unlinks from the parent's sys:children by default; set deleteChildren=false to keep descendants orphaned (for re-parenting), or pruneConnectors=true to also drop surface connectors referencing any deleted id. Refuses affine:page — use delete_doc for whole docs. |
| get_edgeless_canvasA | Read the full edgeless canvas: all edgeless-positioned blocks (notes, frames, edgeless-text) with their xywh, plus all surface elements (shapes, connectors, text, groups). Includes aggregate bounding box and per-type element counts. Use this when you need to understand canvas layout end-to-end before placing new elements. |
| list_commentsA | List paginated comments for a document, including nested replies and resolution state. Use this before update_comment, delete_comment, or resolve_comment when you need the existing comment ids. |
| create_commentA | Create a new comment on an existing document. This writes collaboration state; use update_comment when editing an existing comment instead. |
| update_commentA | Replace the content of an existing comment. This preserves the comment thread; use create_comment for a new thread. |
| delete_commentA | Delete an existing comment by id. This is destructive for that comment; use resolve_comment when you only want to mark a thread resolved. |
| resolve_commentA | Set a comment thread's resolved state without changing its content. Use delete_comment only when the comment should be removed. |
| list_historiesA | List doc histories (timestamps) for a doc. |
| list_collectionsA | List AFFiNE sidebar collections and their rules. Use this read-only tool before updating, deleting, or adding documents to a collection. |
| get_collectionA | Read one AFFiNE sidebar collection by id, including rules and allow-list. Use list_collections first when the id is unknown. |
| create_collectionA | Create a new AFFiNE sidebar collection with optional rules. This writes workspace sidebar metadata but does not create documents. |
| update_collection_rulesA | Replace an AFFiNE collection's rules and rebuild its allow-list from current workspace documents. This can change which docs appear in the collection. |
| update_collectionA | Rename an existing AFFiNE sidebar collection without changing its rules or allow-list. |
| delete_collectionA | Delete an AFFiNE sidebar collection. This removes the collection metadata but does not delete the documents it referenced. |
| add_doc_to_collectionA | Add an existing document id to an AFFiNE collection allow-list. Use update_collection_rules instead when membership should be rule-driven. |
| remove_doc_from_collectionA | Remove a document id from an AFFiNE collection allow-list. This does not delete the document or change collection rules. |
| list_organize_nodesA | Experimental: list AFFiNE sidebar organize folder and link nodes from the folders workspace DB. Use this before moving or deleting organize nodes. |
| create_folderA | Experimental: create an AFFiNE organize folder node in the sidebar tree. This only changes sidebar organization, not document content. |
| create_workspace_blueprintA | Create a simple AFFiNE organize folder blueprint with one root folder and optional child folders. This is a convenience wrapper around create_folder. |
| rename_folderA | Experimental: rename an AFFiNE organize folder node. This changes sidebar metadata only and does not rename documents inside the folder. |
| delete_folderA | Experimental: delete an AFFiNE organize folder and every nested folder or link node. This is destructive for sidebar organization but does not delete target documents, tags, or collections. |
| move_organize_nodeA | Experimental: move an AFFiNE organize folder or link node to another folder or root. This preserves the target document, tag, or collection and changes only sidebar placement. |
| add_organize_linkA | Experimental: add a doc, tag, or collection link under an AFFiNE organize folder. Use move_organize_node for an existing link node instead of creating a duplicate link. |
| delete_organize_linkA | Experimental: delete an AFFiNE organize doc, tag, or collection link node. This removes only the sidebar link, not the target resource. |
| list_doc_propertiesB | List the workspace custom-property definitions and a document's current values for them. |
| create_custom_propertyA | Create a workspace-wide custom property definition (text, number, checkbox, or date). Returns its propertyId. |
| delete_custom_propertyA | Soft-delete a workspace custom property definition (by propertyId or name). Existing values are hidden. |
| set_doc_propertyB | Set a document's custom property value (property by id or name). Value is validated against the property type (text/number/checkbox/date). |
| clear_doc_propertyA | Remove a custom property value from a document (property by id or name). |
| update_doc_iconA | Set or clear the sidebar icon (the Notion-style emoji slot) on a document. Pass an emoji string, a full icon object, or null to remove it. |
| update_folder_iconA | Set or clear the sidebar icon on an organize folder. Pass an emoji string, a full icon object, or null to remove it. Experimental. |
| get_doc_iconA | Read the current sidebar icon of a document. Returns null when none is set. |
| get_folder_iconA | Read the current sidebar icon of an organize folder. Returns null when none is set. Experimental. |
| current_userA | Return the currently authenticated AFFiNE user profile. Use this read-only check to verify credentials before workspace or document operations. |
| update_profileA | Update current user's profile information. |
| update_settingsC | Update user settings and preferences. |
| sign_inA | Sign in to AFFiNE using email and password; sets session cookies for subsequent calls. |
| upload_blobA | Upload a file or blob into AFFiNE workspace storage and return its blob key. This creates stored content but does not attach it to a document by itself. |
| delete_blobA | Delete a blob from AFFiNE workspace storage. Set permanently only when the blob should bypass recoverable deletion. |
| cleanup_blobsA | Permanently release blobs that were already marked deleted in a workspace. This is destructive cleanup and should be used only after confirming deleted blobs are no longer needed. |
| list_notificationsA | List one server page of current-user AFFiNE notifications in a stable envelope. The response preserves each edge cursor, server pageInfo, and serverTotalCount. unreadOnly is a client-side filter over only the fetched page; it does not change server counts or pageInfo. |
| read_all_notificationsA | Ask AFFiNE to mark every current-user notification as read. Inspect applied/status in the response; a false server result is reported as not_applied, not as success. |
| get_affine_promptA | Retrieve official AFFiNE LLM prompt specs, system prompts, visual style guide, and rendered templates from the backend catalog. |
| create_dashboard_docA | Create an AFFiNE document containing a rich interactive HTML/CSS dashboard widget styled with AFFiNE color tokens and design system layout. |
| create_mindmap_canvasA | Generate a structured markdown nested list mindmap for AFFiNE edgeless canvas. |
| create_presentation_slidesA | Generate a structured ND-JSON presentation slide deck outline and insert it into an AFFiNE document. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| make_it_real | Build an interactive, working single-file HTML/CSS/JS dashboard prototype from wireframes or notes. |
| code_artifact | Generate a standalone visual HTML component artifact adhering strictly to AFFiNE's color system. |
| mindmap_generate | Analyze and expand input into a structured nested markdown mindmap for AFFiNE edgeless canvas. |
| slides_outline | Generate an ND-JSON presentation slide deck outline with cover, content slides, and image keywords. |
| chat_affine_ai | Official persona system prompt for AFFiNE AI assistant. |
| explain_content | Deconstruct written content to reveal core message, underlying structure, and key insights. |
| explain_code | Provide a comprehensive, clear, and insightful analysis of any code snippet. |
| summarize_meeting | Extract a structured JSON meeting summary with attendees, key points, action items, and decisions. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/irfanhak123/affine-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server