@aexhq/tools-mcp 0.3.5 → 0.4.0
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 +8 -1
- package/dist/index.mjs +17 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -19,10 +19,17 @@ const tools = await mcpTools({
|
|
|
19
19
|
// await client.close();
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
The client SDK owns transport and protocol negotiation. `connectMcp` disables automatic interactive fulfilment; specify the protocol revision your server supports.
|
|
22
|
+
The client SDK owns transport and protocol negotiation. `connectMcp` disables automatic interactive fulfilment; specify the protocol revision your server supports. For Tool requests it also disables the MCP SDK's independent timer: Brain's original deadline and cancellation signal own invocation lifetime, including unlimited deadlines. Discovery still uses the SDK's normal timeout. A connected client can be supplied directly for finite deadlines of at most 2,147,483,647 ms; use `connectMcp` for longer or unlimited calls. Unsupported timer ranges fail before dispatch instead of shortening the deadline.
|
|
23
|
+
|
|
24
|
+
The bridge uses a fixed discovered Tool definition on every call, so an SDK cache refresh cannot change the session's schemas or trigger the header-mismatch resend path. Discovery uses the SDK's bounded pagination. Later list changes do not add or replace placed Tools; authorize a new session for changed definitions.
|
|
23
25
|
|
|
24
26
|
## Results and failures
|
|
25
27
|
|
|
28
|
+
The bridge uses Brain SDK 0.28 and explicitly finishes each invocation after committing its
|
|
29
|
+
evidence and normalized result. Return alone does not complete a Brain Tool. A missing deadline
|
|
30
|
+
means no invocation timer; keep the application's host connection and MCP client alive until
|
|
31
|
+
completion or cancellation.
|
|
32
|
+
|
|
26
33
|
MCP images and embedded image/PDF resources require a caller-supplied
|
|
27
34
|
`publishMedia({ bytes, mediaType, index }, context)` callback on `mcpTools`. Return an HTTPS URL
|
|
28
35
|
reachable by the model provider. `context` supplies the session ID, invocation sequence, deadline
|
package/dist/index.mjs
CHANGED
|
@@ -26,8 +26,13 @@ function toolOutput(content, media = []) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
// src/index.mjs
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
var SignalClient = class extends Client {
|
|
30
|
+
_setupTimeout(messageId, timeout, ...options) {
|
|
31
|
+
if (timeout !== Infinity) super._setupTimeout(messageId, timeout, ...options);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
async function connectMcp(transport, { name = "aex-mcp", version = "0.4.0", ...options } = {}) {
|
|
35
|
+
const client = new SignalClient({ name, version }, { ...options, inputRequired: { autoFulfill: false } });
|
|
31
36
|
try {
|
|
32
37
|
await client.connect(transport);
|
|
33
38
|
} catch (error) {
|
|
@@ -60,11 +65,15 @@ async function mcpTools({ client, names, env, prefix = "", project, publishMedia
|
|
|
60
65
|
input,
|
|
61
66
|
run: async (arguments_, context) => {
|
|
62
67
|
context.signal.throwIfAborted();
|
|
68
|
+
const timeout = client instanceof SignalClient ? Infinity : context.deadline === void 0 ? Infinity : Math.max(1, context.deadline.getTime() - Date.now());
|
|
69
|
+
if (!(client instanceof SignalClient) && timeout > 2147483647) {
|
|
70
|
+
throw new TypeError("use connectMcp for unlimited or long Tool deadlines; the MCP SDK timer cannot represent them");
|
|
71
|
+
}
|
|
63
72
|
let response;
|
|
64
73
|
try {
|
|
65
74
|
response = await client.callTool({ name: definition.name, arguments: arguments_ }, {
|
|
66
75
|
signal: context.signal,
|
|
67
|
-
timeout
|
|
76
|
+
timeout,
|
|
68
77
|
toolDefinition: definition,
|
|
69
78
|
allowInputRequired: true
|
|
70
79
|
});
|
|
@@ -80,7 +89,7 @@ async function mcpTools({ client, names, env, prefix = "", project, publishMedia
|
|
|
80
89
|
message,
|
|
81
90
|
details: details.data
|
|
82
91
|
});
|
|
83
|
-
return outcome;
|
|
92
|
+
return context.finish(outcome);
|
|
84
93
|
}
|
|
85
94
|
const media = [];
|
|
86
95
|
const content = [];
|
|
@@ -98,19 +107,19 @@ async function mcpTools({ client, names, env, prefix = "", project, publishMedia
|
|
|
98
107
|
} catch (error) {
|
|
99
108
|
if (context.signal.aborted) throw error;
|
|
100
109
|
await context.emit("mcp_media_failed", { tool: definition.name, published: media });
|
|
101
|
-
return failure("mcp_media_failed", String(error.message), { published: media });
|
|
110
|
+
return context.finish(failure("mcp_media_failed", String(error.message), { published: media }));
|
|
102
111
|
}
|
|
103
112
|
const retained = { ...response, content, ...media.length ? { media } : {} };
|
|
104
113
|
const evidenceSequence = await context.emit("mcp_result", { tool: definition.name, result: retained });
|
|
105
114
|
if (response.resultType && response.resultType !== "complete") {
|
|
106
|
-
return failure("mcp_unsupported_result", `MCP ${definition.name} requires unsupported continuation (${response.resultType}); evidence ${evidenceSequence}`, retained);
|
|
115
|
+
return context.finish(failure("mcp_unsupported_result", `MCP ${definition.name} requires unsupported continuation (${response.resultType}); evidence ${evidenceSequence}`, retained));
|
|
107
116
|
}
|
|
108
117
|
if (response.isError) {
|
|
109
118
|
const message = content.filter((block) => block.type === "text").map((block) => block.text).join("\n");
|
|
110
|
-
return failure("mcp_tool_error", `MCP ${definition.name}: ${message || "Tool failed"}; evidence ${evidenceSequence}`, retained);
|
|
119
|
+
return context.finish(failure("mcp_tool_error", `MCP ${definition.name}: ${message || "Tool failed"}; evidence ${evidenceSequence}`, retained));
|
|
111
120
|
}
|
|
112
121
|
const presented = { content, ...response.structuredContent === void 0 ? {} : { structuredContent: response.structuredContent }, evidenceSequence };
|
|
113
|
-
return toolOutput(project ? await project(presented, definition.name) : presented, media);
|
|
122
|
+
return context.finish(toolOutput(project ? await project(presented, definition.name) : presented, media));
|
|
114
123
|
}
|
|
115
124
|
})({ env });
|
|
116
125
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aexhq/tools-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Selected MCP Tools in a Brain application host",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
"exports": { ".": { "types": "./index.d.ts", "import": "./dist/index.mjs" }, "./package.json": "./package.json" },
|
|
11
11
|
"files": ["dist", "index.d.ts", "README.md"],
|
|
12
12
|
"scripts": { "build": "node ../../tools/build-environment.mjs", "test": "npm run build && node --test test/*.test.mjs", "test:journeys": "node --test test/journeys.mjs", "prepack": "npm run build" },
|
|
13
|
-
"dependencies": { "@aexhq/brain": "0.
|
|
13
|
+
"dependencies": { "@aexhq/brain": "0.28.0", "@modelcontextprotocol/client": "2.0.0", "zod": "4.4.3" },
|
|
14
14
|
"devDependencies": { "@modelcontextprotocol/server": "2.0.0" }
|
|
15
15
|
}
|