affine-mcp-server 1.11.1 → 1.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A Model Context Protocol (MCP) server that integrates with AFFiNE (self‑hosted or cloud). It exposes AFFiNE workspaces and documents to AI assistants over stdio (default) or HTTP (`/mcp`).
4
4
 
5
- [![Version](https://img.shields.io/badge/version-1.11.1-blue)](https://github.com/dawncr0w/affine-mcp-server/releases)
5
+ [![Version](https://img.shields.io/badge/version-1.11.2-blue)](https://github.com/dawncr0w/affine-mcp-server/releases)
6
6
  [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-1.17.2-green)](https://github.com/modelcontextprotocol/typescript-sdk)
7
7
  [![CI](https://github.com/dawncr0w/affine-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/dawncr0w/affine-mcp-server/actions/workflows/ci.yml)
8
8
  [![License](https://img.shields.io/badge/license-MIT-yellow)](LICENSE)
@@ -19,7 +19,7 @@ A Model Context Protocol (MCP) server that integrates with AFFiNE (self‑hosted
19
19
  - Tools: 76 focused tools with WebSocket-based document editing
20
20
  - Status: Active
21
21
 
22
- > New in v1.11.1: Corrected stale `list_docs` count and cursor metadata after `delete_doc` removes a document.
22
+ > New in v1.11.2: Corrected stale deleted-document visibility in `list_docs` after `delete_doc`, completing the `v1.11.1` delete-metadata fix.
23
23
 
24
24
  ## Features
25
25
 
@@ -1986,6 +1986,8 @@ export function registerDocTools(server, gql, defaults) {
1986
1986
  const tagsByDocId = new Map();
1987
1987
  const titlesByDocId = new Map();
1988
1988
  let workspacePageCount = null;
1989
+ let workspacePageIds = null;
1990
+ const deletedDocIds = new Set();
1989
1991
  try {
1990
1992
  const { endpoint, cookie, bearer } = await getCookieAndEndpoint();
1991
1993
  const wsUrl = wsUrlFromGraphQLEndpoint(endpoint);
@@ -1999,6 +2001,7 @@ export function registerDocTools(server, gql, defaults) {
1999
2001
  const meta = wsDoc.getMap("meta");
2000
2002
  const pages = getWorkspacePageEntries(meta);
2001
2003
  workspacePageCount = pages.length;
2004
+ workspacePageIds = new Set(pages.map(page => page.id));
2002
2005
  const { byId } = getWorkspaceTagOptionMaps(meta);
2003
2006
  for (const page of pages) {
2004
2007
  if (page.title) {
@@ -2008,6 +2011,20 @@ export function registerDocTools(server, gql, defaults) {
2008
2011
  tagsByDocId.set(page.id, resolveTagLabels(tagEntries, byId));
2009
2012
  }
2010
2013
  }
2014
+ const graphEdges = Array.isArray(docs?.edges) ? docs.edges : [];
2015
+ if (workspacePageIds && graphEdges.length > workspacePageIds.size) {
2016
+ for (const edge of graphEdges) {
2017
+ const nodeId = edge?.node?.id;
2018
+ if (typeof nodeId !== "string" || workspacePageIds.has(nodeId)) {
2019
+ continue;
2020
+ }
2021
+ const edgeSnapshot = await loadDoc(socket, workspaceId, nodeId);
2022
+ const edgeExists = Boolean(edgeSnapshot.missing || edgeSnapshot.state || edgeSnapshot.timestamp);
2023
+ if (!edgeExists) {
2024
+ deletedDocIds.add(nodeId);
2025
+ }
2026
+ }
2027
+ }
2011
2028
  }
2012
2029
  finally {
2013
2030
  socket.disconnect();
@@ -2032,19 +2049,22 @@ export function registerDocTools(server, gql, defaults) {
2032
2049
  };
2033
2050
  })
2034
2051
  : [];
2035
- // The workspace snapshot reflects deletions before GraphQL count metadata catches up.
2036
- // Clamp downward only so create/index lag does not inflate counts from partial snapshot state.
2052
+ const visibleEdges = deletedDocIds.size > 0
2053
+ ? mergedEdges.filter((edge) => !deletedDocIds.has(edge?.node?.id))
2054
+ : mergedEdges;
2037
2055
  const correctedTotalCount = typeof docs?.totalCount === "number" &&
2038
2056
  typeof workspacePageCount === "number" &&
2057
+ (deletedDocIds.size > 0 ||
2058
+ visibleEdges.length === workspacePageCount) &&
2039
2059
  workspacePageCount < docs.totalCount
2040
2060
  ? workspacePageCount
2041
2061
  : docs?.totalCount;
2042
2062
  const correctedPageInfo = docs?.pageInfo
2043
2063
  ? {
2044
2064
  ...docs.pageInfo,
2045
- endCursor: mergedEdges.length > 0 ? mergedEdges[mergedEdges.length - 1]?.cursor ?? null : null,
2065
+ endCursor: visibleEdges.length > 0 ? visibleEdges[visibleEdges.length - 1]?.cursor ?? null : null,
2046
2066
  hasNextPage: typeof correctedTotalCount === "number" && !parsed.after
2047
- ? (parsed.offset ?? 0) + mergedEdges.length < correctedTotalCount
2067
+ ? (parsed.offset ?? 0) + visibleEdges.length < correctedTotalCount
2048
2068
  : docs.pageInfo.hasNextPage,
2049
2069
  }
2050
2070
  : docs?.pageInfo;
@@ -2052,7 +2072,7 @@ export function registerDocTools(server, gql, defaults) {
2052
2072
  ...docs,
2053
2073
  totalCount: correctedTotalCount,
2054
2074
  pageInfo: correctedPageInfo,
2055
- edges: mergedEdges,
2075
+ edges: visibleEdges,
2056
2076
  };
2057
2077
  return text(mergedDocs);
2058
2078
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "affine-mcp-server",
3
- "version": "1.11.1",
3
+ "version": "1.11.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Model Context Protocol server for AFFiNE - enables AI assistants to interact with AFFiNE workspaces, documents, and collaboration features.",