toolcraft 0.0.198 → 0.0.199
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/composition.json +3 -3
- package/dist/composition.json +3 -3
- package/node_modules/tiny-http-mcp-server/README.md +2 -2
- package/node_modules/tiny-http-mcp-server/dist/cli.js +7 -1
- package/node_modules/tiny-http-mcp-server/dist/composition.json +1 -1
- package/node_modules/tiny-http-mcp-server/package.json +1 -1
- package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
- package/node_modules/tiny-stdio-mcp-server/dist/server.js +31 -3
- package/node_modules/tiny-stdio-mcp-server/dist/tool-call-admission.d.ts +9 -0
- package/node_modules/tiny-stdio-mcp-server/dist/tool-call-admission.js +51 -0
- package/node_modules/tiny-stdio-mcp-server/dist/types.d.ts +4 -0
- package/node_modules/toolcraft-schema/package.json +1 -1
- package/package.json +2 -2
package/composition.json
CHANGED
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
"name": "tiny-http-mcp-server",
|
|
101
|
-
"version": "0.1.
|
|
101
|
+
"version": "0.1.13",
|
|
102
102
|
"license": "MIT"
|
|
103
103
|
},
|
|
104
104
|
{
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.199",
|
|
117
117
|
"license": "MIT"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "toolcraft-schema",
|
|
126
|
-
"version": "0.0.
|
|
126
|
+
"version": "0.0.199",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
package/dist/composition.json
CHANGED
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
"name": "tiny-http-mcp-server",
|
|
101
|
-
"version": "0.1.
|
|
101
|
+
"version": "0.1.13",
|
|
102
102
|
"license": "MIT"
|
|
103
103
|
},
|
|
104
104
|
{
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.199",
|
|
117
117
|
"license": "MIT"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "toolcraft-schema",
|
|
126
|
-
"version": "0.0.
|
|
126
|
+
"version": "0.0.199",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
|
@@ -436,7 +436,7 @@ Returned `HttpServer` instances support:
|
|
|
436
436
|
| `maxStreamBufferBytes` | `number` | `1048576` | End a GET SSE stream before a live write when its buffered bytes exceed this limit. |
|
|
437
437
|
| `maxSseEventHistory` | `number` | `100` | Number of server-sent events retained for `Last-Event-ID` replay. |
|
|
438
438
|
| `sseKeepAliveMs` | `number` | `30000` | GET SSE keepalive interval in milliseconds. Set to `0` to disable keepalive comments. |
|
|
439
|
-
| `maxConcurrentToolCalls` | `number` |
|
|
439
|
+
| `maxConcurrentToolCalls` | `number` | `4` | Maximum concurrent tool calls across sessions. |
|
|
440
440
|
| `sessionStore` | `SessionStore` | in-memory store | Pluggable session-record storage; SSE streams and replay history remain instance-local. |
|
|
441
441
|
| `requestIdGenerator` | `() => string` | incrementing ids | Generates request ids when `X-Request-Id` is absent. |
|
|
442
442
|
| `observability` | `HttpObservabilityOptions` | none | Emits request, auth, session, stream, and tool lifecycle events. |
|
|
@@ -622,7 +622,7 @@ tiny-http-mcp-server [options]
|
|
|
622
622
|
| `--max-stream-buffer-bytes <bytes>` | `1048576` | End a GET SSE stream before a live notification or keepalive write when buffered bytes exceed this limit. |
|
|
623
623
|
| `--max-sse-event-history <count>` | `100` | Number of SSE events retained for `Last-Event-ID` replay. |
|
|
624
624
|
| `--sse-keep-alive-ms <ms>` | `30000` | GET SSE keepalive interval in milliseconds. Set to `0` to disable keepalive comments. |
|
|
625
|
-
| `--max-concurrent-tool-calls <count>` |
|
|
625
|
+
| `--max-concurrent-tool-calls <count>` | `4` | Maximum concurrent tool calls across sessions. |
|
|
626
626
|
| `--trusted-proxy` | off | Trust `X-Forwarded-Proto` and `X-Forwarded-Host` for metadata challenge URLs. |
|
|
627
627
|
| `--request-timeout-ms <ms>` | Node default | Node HTTP request timeout. |
|
|
628
628
|
| `--headers-timeout-ms <ms>` | Node default | Node HTTP headers timeout. |
|
|
@@ -44,7 +44,9 @@ const HELP_TEXT = [
|
|
|
44
44
|
" --sse-keep-alive-ms <ms>",
|
|
45
45
|
" GET SSE keepalive interval (default: 30000; 0 disables)",
|
|
46
46
|
" --max-concurrent-tool-calls <count>",
|
|
47
|
-
" Maximum concurrent tool calls across sessions",
|
|
47
|
+
" Maximum concurrent tool calls across sessions (default: 4)",
|
|
48
|
+
" --max-queued-tool-calls <count>",
|
|
49
|
+
" Maximum waiting tool calls (default: 64; 0 disables waiting)",
|
|
48
50
|
" --trusted-proxy Trust X-Forwarded-Proto and X-Forwarded-Host",
|
|
49
51
|
" --request-timeout-ms <ms>",
|
|
50
52
|
" Node HTTP request timeout",
|
|
@@ -201,6 +203,7 @@ function parseCliOptions(args) {
|
|
|
201
203
|
"max-sse-event-history": { type: "string" },
|
|
202
204
|
"sse-keep-alive-ms": { type: "string" },
|
|
203
205
|
"max-concurrent-tool-calls": { type: "string" },
|
|
206
|
+
"max-queued-tool-calls": { type: "string" },
|
|
204
207
|
"trusted-proxy": { type: "boolean" },
|
|
205
208
|
"request-timeout-ms": { type: "string" },
|
|
206
209
|
"headers-timeout-ms": { type: "string" },
|
|
@@ -227,6 +230,7 @@ function parseCliOptions(args) {
|
|
|
227
230
|
const maxSseEventHistory = parseOptionalInteger(values["max-sse-event-history"], "--max-sse-event-history", 0);
|
|
228
231
|
const sseKeepAliveMs = parseOptionalInteger(values["sse-keep-alive-ms"], "--sse-keep-alive-ms", 0);
|
|
229
232
|
const maxConcurrentToolCalls = parseOptionalInteger(values["max-concurrent-tool-calls"], "--max-concurrent-tool-calls", 1);
|
|
233
|
+
const maxQueuedToolCalls = parseOptionalInteger(values["max-queued-tool-calls"], "--max-queued-tool-calls", 0);
|
|
230
234
|
const requestTimeoutMs = parseOptionalInteger(values["request-timeout-ms"], "--request-timeout-ms", 0);
|
|
231
235
|
const headersTimeoutMs = parseOptionalInteger(values["headers-timeout-ms"], "--headers-timeout-ms", 0);
|
|
232
236
|
const keepAliveTimeoutMs = parseOptionalInteger(values["keep-alive-timeout-ms"], "--keep-alive-timeout-ms", 0);
|
|
@@ -257,6 +261,7 @@ function parseCliOptions(args) {
|
|
|
257
261
|
...(maxSseEventHistory === undefined ? {} : { maxSseEventHistory }),
|
|
258
262
|
...(sseKeepAliveMs === undefined ? {} : { sseKeepAliveMs }),
|
|
259
263
|
...(maxConcurrentToolCalls === undefined ? {} : { maxConcurrentToolCalls }),
|
|
264
|
+
...(maxQueuedToolCalls === undefined ? {} : { maxQueuedToolCalls }),
|
|
260
265
|
trustedProxy: values["trusted-proxy"] ?? false,
|
|
261
266
|
...(requestTimeoutMs === undefined ? {} : { requestTimeoutMs }),
|
|
262
267
|
...(headersTimeoutMs === undefined ? {} : { headersTimeoutMs }),
|
|
@@ -412,6 +417,7 @@ export async function runCli(args = process.argv.slice(2), dependencies = {}) {
|
|
|
412
417
|
...(options.maxConcurrentToolCalls === undefined
|
|
413
418
|
? {}
|
|
414
419
|
: { maxConcurrentToolCalls: options.maxConcurrentToolCalls }),
|
|
420
|
+
...(options.maxQueuedToolCalls === undefined ? {} : { maxQueuedToolCalls: options.maxQueuedToolCalls }),
|
|
415
421
|
...(options.trustedProxy ? { trustedProxy: true } : {}),
|
|
416
422
|
...(oauth === undefined ? {} : { oauth })
|
|
417
423
|
});
|
|
@@ -4,6 +4,7 @@ import { JSON_RPC_ERROR_CODES, ToolError } from "./types.js";
|
|
|
4
4
|
import { parseMessage, formatSuccessResponse, formatErrorResponse } from "./jsonrpc.js";
|
|
5
5
|
import { parseUriTemplate } from "./uri-template.js";
|
|
6
6
|
import { toContentBlocks } from "./content/convert.js";
|
|
7
|
+
import { ToolCallAdmission } from "./tool-call-admission.js";
|
|
7
8
|
const PROTOCOL_VERSION = "2025-11-25";
|
|
8
9
|
const SUPPORTED_PROTOCOL_VERSIONS = new Set(["2025-03-26", "2025-06-18", PROTOCOL_VERSION]);
|
|
9
10
|
function compileToolSchema(schema) {
|
|
@@ -20,6 +21,17 @@ export function createServer(options) {
|
|
|
20
21
|
(!Number.isInteger(options.toolCallTimeoutMs) || options.toolCallTimeoutMs <= 0)) {
|
|
21
22
|
throw new Error("toolCallTimeoutMs must be a positive integer.");
|
|
22
23
|
}
|
|
24
|
+
const maxConcurrentToolCalls = options.maxConcurrentToolCalls ?? 4;
|
|
25
|
+
const maxQueuedToolCalls = options.maxQueuedToolCalls ?? 64;
|
|
26
|
+
for (const [name, value, minimum] of [
|
|
27
|
+
["maxConcurrentToolCalls", maxConcurrentToolCalls, 1],
|
|
28
|
+
["maxQueuedToolCalls", maxQueuedToolCalls, 0]
|
|
29
|
+
]) {
|
|
30
|
+
if (!Number.isSafeInteger(value) || value < minimum) {
|
|
31
|
+
throw new Error(`${name} must be a safe integer greater than or equal to ${minimum}.`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const toolAdmission = new ToolCallAdmission(maxConcurrentToolCalls, maxQueuedToolCalls);
|
|
23
35
|
const supportNotifications = options.supportNotifications !== false;
|
|
24
36
|
const supportResourceSubscriptions = options.supportResourceSubscriptions !== false;
|
|
25
37
|
const tools = new Map();
|
|
@@ -142,17 +154,33 @@ export function createServer(options) {
|
|
|
142
154
|
}
|
|
143
155
|
try {
|
|
144
156
|
let handlerResult;
|
|
157
|
+
const admissionTimeout = options.toolCallTimeoutMs === undefined ? undefined : new AbortController();
|
|
158
|
+
const admissionSignal = AbortSignal.any([
|
|
159
|
+
lifecycle.abortController.signal,
|
|
160
|
+
...(admissionTimeout === undefined ? [] : [admissionTimeout.signal])
|
|
161
|
+
]);
|
|
162
|
+
const handlerPromise = (async () => {
|
|
163
|
+
const release = await toolAdmission.acquire(admissionSignal);
|
|
164
|
+
try {
|
|
165
|
+
admissionSignal.throwIfAborted();
|
|
166
|
+
return await tool.handler(toolArgs);
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
release();
|
|
170
|
+
}
|
|
171
|
+
})();
|
|
145
172
|
if (options.toolCallTimeoutMs === undefined) {
|
|
146
|
-
handlerResult = await
|
|
173
|
+
handlerResult = await handlerPromise;
|
|
147
174
|
}
|
|
148
175
|
else {
|
|
149
176
|
let timeout;
|
|
150
|
-
const handlerPromise = Promise.resolve().then(() => tool.handler(toolArgs));
|
|
151
177
|
handlerResult = await Promise.race([
|
|
152
178
|
handlerPromise,
|
|
153
179
|
new Promise((_resolve, reject) => {
|
|
154
180
|
timeout = setTimeout(() => {
|
|
155
|
-
|
|
181
|
+
const error = new ToolError(JSON_RPC_ERROR_CODES.INTERNAL_ERROR, `Tool call timed out: ${toolName}`);
|
|
182
|
+
admissionTimeout.abort(error);
|
|
183
|
+
reject(error);
|
|
156
184
|
}, options.toolCallTimeoutMs);
|
|
157
185
|
})
|
|
158
186
|
]).finally(() => {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class ToolCallAdmission {
|
|
2
|
+
private readonly maximumActive;
|
|
3
|
+
private readonly maximumQueued;
|
|
4
|
+
private active;
|
|
5
|
+
private readonly waiting;
|
|
6
|
+
constructor(maximumActive: number, maximumQueued: number);
|
|
7
|
+
acquire(signal: AbortSignal): Promise<() => void>;
|
|
8
|
+
private release;
|
|
9
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ToolError } from "./types.js";
|
|
2
|
+
export class ToolCallAdmission {
|
|
3
|
+
maximumActive;
|
|
4
|
+
maximumQueued;
|
|
5
|
+
active = 0;
|
|
6
|
+
waiting = [];
|
|
7
|
+
constructor(maximumActive, maximumQueued) {
|
|
8
|
+
this.maximumActive = maximumActive;
|
|
9
|
+
this.maximumQueued = maximumQueued;
|
|
10
|
+
}
|
|
11
|
+
acquire(signal) {
|
|
12
|
+
signal.throwIfAborted();
|
|
13
|
+
if (this.active < this.maximumActive) {
|
|
14
|
+
this.active++;
|
|
15
|
+
return Promise.resolve(this.release());
|
|
16
|
+
}
|
|
17
|
+
if (this.waiting.length >= this.maximumQueued) {
|
|
18
|
+
throw new ToolError(-32000, "Too many queued tool calls");
|
|
19
|
+
}
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const waiting = {
|
|
22
|
+
signal,
|
|
23
|
+
resolve,
|
|
24
|
+
abort: () => {
|
|
25
|
+
const index = this.waiting.indexOf(waiting);
|
|
26
|
+
if (index !== -1)
|
|
27
|
+
this.waiting.splice(index, 1);
|
|
28
|
+
reject(signal.reason);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
this.waiting.push(waiting);
|
|
32
|
+
signal.addEventListener("abort", waiting.abort, { once: true });
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
release() {
|
|
36
|
+
let released = false;
|
|
37
|
+
return () => {
|
|
38
|
+
if (released)
|
|
39
|
+
return;
|
|
40
|
+
released = true;
|
|
41
|
+
const next = this.waiting.shift();
|
|
42
|
+
if (next === undefined) {
|
|
43
|
+
this.active--;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
next.signal.removeEventListener("abort", next.abort);
|
|
47
|
+
next.resolve(this.release());
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -209,6 +209,10 @@ export interface ServerOptions {
|
|
|
209
209
|
name: string;
|
|
210
210
|
version: string;
|
|
211
211
|
toolCallTimeoutMs?: number;
|
|
212
|
+
/** Shared active tool-handler capacity across sessions; defaults to four. */
|
|
213
|
+
maxConcurrentToolCalls?: number;
|
|
214
|
+
/** Maximum tool calls waiting for capacity; defaults to 64. Zero disables waiting. */
|
|
215
|
+
maxQueuedToolCalls?: number;
|
|
212
216
|
validateToolArguments?: boolean;
|
|
213
217
|
supportNotifications?: boolean;
|
|
214
218
|
supportResourceSubscriptions?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.199",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"yaml"
|
|
159
159
|
],
|
|
160
160
|
"optionalDependencies": {
|
|
161
|
-
"toolcraft-schema": "0.0.
|
|
161
|
+
"toolcraft-schema": "0.0.199",
|
|
162
162
|
"toolcraft-design": "*",
|
|
163
163
|
"@poe-code/frontmatter": "*",
|
|
164
164
|
"@poe-code/agent-mcp-config": "*",
|