@deepseek-ai/dsh-mcp-client 0.1.5-alpha.1 → 0.1.5-alpha.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.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/mcp/mcp-client/README.md
5
- README.md: 112f477556d1b8ee2788c9b96251b6969c617f62
6
- README.zh.md: e642c7e130510cd717342a2e879c26396c77d55d
5
+ README.md: de646256888f1c271ad94a4c863338dfb02551e6
6
+ README.zh.md: 2c71060ec309e823ff3456207881e27ab9aca553
package/README.md CHANGED
@@ -76,6 +76,7 @@ The model sees each tool under a stable server-qualified name: `mcp__<serverName
76
76
  - Two servers publishing the same tool name (for example `search`) coexist under their own namespaces.
77
77
  - Two entries using the same server name: the later one fails to load with a clear error.
78
78
  - A server that lists the same tool twice gets its tool list rejected as invalid, and the previous tool set stays active.
79
+ - A repeated non-empty `tools/list` continuation cursor rejects that update immediately, including cycles through empty pages; the previous tool set stays active and later updates can still succeed.
79
80
  - An update that conflicts with an already-registered tool name is rejected entirely — you never get a partial tool set from that server.
80
81
 
81
82
  ### Calling tools and reading results
package/README.zh.md CHANGED
@@ -76,6 +76,7 @@ kind: "package-reference"
76
76
  - 发布相同工具名称(例如 `search`)的两个服务器会在各自的 namespace 下共存。
77
77
  - 两条配置项使用相同的服务器名称时,后加载的一条会在加载时以明确错误失败。
78
78
  - 服务器在工具列表中两次列出同一工具时,其工具列表会被作为无效列表拒绝,上一组工具保持可用。
79
+ - `tools/list` 返回重复的非空续传游标时会立即拒绝本次更新,包括经过空页的循环;上一组工具保持可用,后续更新仍可成功。
79
80
  - 工具更新与已有工具名称冲突时,该更新会被整体拒绝——绝不会得到该服务器的部分工具集。
80
81
 
81
82
  ### 调用工具与读取结果
package/lib/index.js CHANGED
@@ -131,8 +131,8 @@ function publicToolName(serverName, rawName) {
131
131
  *
132
132
  * 1. Fetch: drain uncached `tools/list` pagination and build the full next
133
133
  * generation of `ToolDefinition`s under public names. Any failure here
134
- * (network error, duplicate raw name in the server's list) rejects and
135
- * leaves the previous generation registered untouched.
134
+ * (network error, duplicate raw name, repeated continuation cursor) rejects
135
+ * and leaves the previous generation registered untouched.
136
136
  * 2. Swap: dispose the previous generation, register the new one. A registry
137
137
  * conflict here can only mean a foreign registration squats on this
138
138
  * server's `mcp__<serverName>__` namespace — the partial generation is
@@ -150,6 +150,7 @@ function publicToolName(serverName, rawName) {
150
150
  */
151
151
  async function syncTools(client, ctx, opts, previous) {
152
152
  const definitions = /* @__PURE__ */ new Map();
153
+ const seenCursors = /* @__PURE__ */ new Set();
153
154
  let cursor;
154
155
  do {
155
156
  const response = await listToolsUncached(client, cursor);
@@ -159,6 +160,10 @@ async function syncTools(client, ctx, opts, previous) {
159
160
  definitions.set(publicName, createDefinition(client, ctx, publicName, tool.name, tool.description ?? "", tool.inputSchema, supportedOutputSchema(tool.outputSchema), tool.execution?.taskSupport === "required", opts));
160
161
  }
161
162
  cursor = response.nextCursor;
163
+ if (cursor) {
164
+ if (seenCursors.has(cursor)) throw new Error(`mcp-client(${opts.serverName}): server repeated a tools/list continuation cursor — invalid tool list`);
165
+ seenCursors.add(cursor);
166
+ }
162
167
  } while (cursor);
163
168
  for (const dispose of previous.values()) dispose();
164
169
  const disposers = /* @__PURE__ */ new Map();
@@ -50,8 +50,8 @@ export declare function publicToolName(serverName: string, rawName: string): str
50
50
  *
51
51
  * 1. Fetch: drain uncached `tools/list` pagination and build the full next
52
52
  * generation of `ToolDefinition`s under public names. Any failure here
53
- * (network error, duplicate raw name in the server's list) rejects and
54
- * leaves the previous generation registered untouched.
53
+ * (network error, duplicate raw name, repeated continuation cursor) rejects
54
+ * and leaves the previous generation registered untouched.
55
55
  * 2. Swap: dispose the previous generation, register the new one. A registry
56
56
  * conflict here can only mean a foreign registration squats on this
57
57
  * server's `mcp__<serverName>__` namespace — the partial generation is
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-mcp-client",
3
3
  "description": "MCP client bridge: connects to MCP servers and registers their tools on ctx.tools",
4
- "version": "0.1.5-alpha.1",
4
+ "version": "0.1.5-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,13 +27,13 @@
27
27
  ],
28
28
  "license": "MIT",
29
29
  "peerDependencies": {
30
- "@deepseek-ai/dsh-llm": "^0.1.5-alpha.1",
31
- "@deepseek-ai/dsh-scope": "^0.1.5-alpha.1",
32
- "@deepseek-ai/dsh-subprocess": "^0.1.5-alpha.1",
33
- "@deepseek-ai/dsh-timeout": "^0.1.5-alpha.1",
34
- "@deepseek-ai/dsh-tools": "^0.1.5-alpha.1",
35
- "@deepseek-ai/cordis": "^4.0.2",
36
- "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.1"
30
+ "@deepseek-ai/dsh-llm": "^0.1.5-alpha.2",
31
+ "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.2",
32
+ "@deepseek-ai/dsh-scope": "^0.1.5-alpha.2",
33
+ "@deepseek-ai/dsh-subprocess": "^0.1.5-alpha.2",
34
+ "@deepseek-ai/dsh-tools": "^0.1.5-alpha.2",
35
+ "@deepseek-ai/dsh-timeout": "^0.1.5-alpha.2",
36
+ "@deepseek-ai/cordis": "^4.0.2"
37
37
  },
38
38
  "dependencies": {
39
39
  "@modelcontextprotocol/sdk": "^1.12.0",
@@ -43,14 +43,14 @@
43
43
  "devDependencies": {
44
44
  "@modelcontextprotocol/server-everything": "^2026.7.4",
45
45
  "@modelcontextprotocol/server-filesystem": "^2026.7.4",
46
- "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.1",
47
- "@deepseek-ai/dsh-attachment-local": "^0.1.5-alpha.1",
48
- "@deepseek-ai/dsh-llm": "^0.1.5-alpha.1",
49
- "@deepseek-ai/dsh-scope": "^0.1.5-alpha.1",
50
- "@deepseek-ai/dsh-subprocess": "^0.1.5-alpha.1",
51
- "@deepseek-ai/dsh-tools": "^0.1.5-alpha.1",
52
- "@deepseek-ai/dsh-timeout": "^0.1.5-alpha.1",
46
+ "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.2",
47
+ "@deepseek-ai/dsh-attachment-local": "^0.1.5-alpha.2",
48
+ "@deepseek-ai/dsh-llm": "^0.1.5-alpha.2",
49
+ "@deepseek-ai/dsh-scope": "^0.1.5-alpha.2",
50
+ "@deepseek-ai/dsh-subprocess": "^0.1.5-alpha.2",
51
+ "@deepseek-ai/dsh-timeout": "^0.1.5-alpha.2",
52
+ "@deepseek-ai/dsh-tools": "^0.1.5-alpha.2",
53
53
  "@deepseek-ai/cordis": "^4.0.2",
54
- "@deepseek-ai/dsh-http-proxy": "^0.1.5-alpha.1"
54
+ "@deepseek-ai/dsh-http-proxy": "^0.1.5-alpha.2"
55
55
  }
56
56
  }