toolcraft 0.0.144 → 0.0.146
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 +2 -2
- package/dist/composition.json +2 -2
- package/dist/http-hosted-oauth.js +31 -13
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/mcp.js +14 -6
- package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
- package/node_modules/toolcraft-schema/package.json +1 -1
- package/package.json +2 -2
package/composition.json
CHANGED
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.146",
|
|
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.146",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
package/dist/composition.json
CHANGED
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.146",
|
|
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.146",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
|
@@ -111,18 +111,30 @@ function loginField(field) {
|
|
|
111
111
|
type: field === "password" || field === "apiKey" ? "password" : field === "email" ? "email" : "text"
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
|
-
function renderLogin(providerName, fields, transaction, csrfToken, error) {
|
|
114
|
+
function renderLogin(providerName, fields, transaction, csrfToken, error, submittedValues = {}) {
|
|
115
|
+
const scriptNonce = randomBytes(18).toString("base64");
|
|
115
116
|
const controls = fields
|
|
116
117
|
.map((field) => {
|
|
117
118
|
const name = escapeHtml(field.name);
|
|
118
|
-
|
|
119
|
+
const type = field.type ?? "text";
|
|
120
|
+
const autocomplete = type === "email" ? "username" : field.name === "password" ? "current-password" : "off";
|
|
121
|
+
const value = type === "email" ? submittedValues[field.name] ?? "" : "";
|
|
122
|
+
return `<label>${escapeHtml(field.label ?? field.name)}<input name="${name}" type="${type}" required autocomplete="${autocomplete}"${value.length === 0 ? "" : ` value="${escapeHtml(value)}"`}></label>`;
|
|
119
123
|
})
|
|
120
124
|
.join("");
|
|
121
|
-
|
|
125
|
+
const idleLabel = `Connect ${providerName}`;
|
|
126
|
+
const html = `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Connect ${escapeHtml(providerName)}</title><style>body{font:16px system-ui;max-width:28rem;margin:10vh auto;padding:1rem;color:#171717}form{display:grid;gap:1rem}label{display:grid;gap:.35rem}input,button{font:inherit;padding:.7rem}button{cursor:pointer}button:disabled{cursor:wait;opacity:.7}.status{margin:0;color:#525252}.error{color:#b42318}</style></head><body><h1>Connect ${escapeHtml(providerName)}</h1>${error === undefined ? "" : `<p class="error" role="alert">${escapeHtml(error)}</p>`}<form id="oauth-connect-form" method="post" action="/oauth/connect"><input type="hidden" name="transaction" value="${escapeHtml(transaction.id)}"><input type="hidden" name="csrf" value="${escapeHtml(csrfToken)}">${controls}<button id="oauth-connect-button" type="submit" data-idle-label="${escapeHtml(idleLabel)}">${escapeHtml(idleLabel)}</button><p id="oauth-connect-status" class="status" role="status" aria-live="polite" hidden>Signing in… This may take a moment.</p></form><script nonce="${scriptNonce}">(()=>{const form=document.getElementById("oauth-connect-form");const button=document.getElementById("oauth-connect-button");const status=document.getElementById("oauth-connect-status");if(!(form instanceof HTMLFormElement)||!(button instanceof HTMLButtonElement)||!(status instanceof HTMLElement))return;const reset=()=>{form.removeAttribute("aria-busy");button.disabled=false;button.textContent=button.dataset.idleLabel||"Connect";status.hidden=true};form.addEventListener("submit",()=>{form.setAttribute("aria-busy","true");button.disabled=true;button.textContent="Connecting…";status.hidden=false});addEventListener("pageshow",reset)})();</script></body></html>`;
|
|
127
|
+
return {
|
|
128
|
+
contentSecurityPolicy: loginContentSecurityPolicy(transaction, scriptNonce),
|
|
129
|
+
html
|
|
130
|
+
};
|
|
122
131
|
}
|
|
123
|
-
function loginContentSecurityPolicy(transaction) {
|
|
132
|
+
function loginContentSecurityPolicy(transaction, scriptNonce) {
|
|
124
133
|
const callbackOrigin = new URL(transaction.redirectUri).origin;
|
|
125
|
-
return `default-src 'none'; style-src 'unsafe-inline'; form-action 'self' ${callbackOrigin}; base-uri 'none'; frame-ancestors 'none'`;
|
|
134
|
+
return `default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-${scriptNonce}'; form-action 'self' ${callbackOrigin}; base-uri 'none'; frame-ancestors 'none'`;
|
|
135
|
+
}
|
|
136
|
+
function renderExpiredConnection() {
|
|
137
|
+
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Connection expired</title><style>body{font:16px system-ui;max-width:28rem;margin:10vh auto;padding:1rem;color:#171717}p{line-height:1.5}</style></head><body><h1>Connection expired</h1><p>This sign-in link has expired or was already used.</p><p>Close this tab, return to the app that started the connection, and click Connect again.</p></body></html>`;
|
|
126
138
|
}
|
|
127
139
|
function interactionCookieName(transactionId) {
|
|
128
140
|
const suffix = createHash("sha256").update(transactionId).digest("base64url").slice(0, 22);
|
|
@@ -186,11 +198,12 @@ export async function prepareHostedOAuthRuntime(config) {
|
|
|
186
198
|
const security = createAuthorizationInteractionSecurity({
|
|
187
199
|
cookieName: interactionCookieName(transaction.id)
|
|
188
200
|
});
|
|
189
|
-
|
|
201
|
+
const login = renderLogin(displayName, fields, transaction, security.csrfToken);
|
|
202
|
+
return new Response(login.html, {
|
|
190
203
|
status: 200,
|
|
191
204
|
headers: {
|
|
192
205
|
"content-type": "text/html; charset=utf-8",
|
|
193
|
-
"content-security-policy":
|
|
206
|
+
"content-security-policy": login.contentSecurityPolicy,
|
|
194
207
|
"cache-control": "no-store",
|
|
195
208
|
"referrer-policy": "no-referrer",
|
|
196
209
|
"x-content-type-options": "nosniff",
|
|
@@ -273,10 +286,13 @@ export async function prepareHostedOAuthRuntime(config) {
|
|
|
273
286
|
}) ||
|
|
274
287
|
transaction.expiresAt <= Date.now()) {
|
|
275
288
|
response.writeHead(400, {
|
|
276
|
-
"content-type": "text/
|
|
277
|
-
"
|
|
289
|
+
"content-type": "text/html; charset=utf-8",
|
|
290
|
+
"content-security-policy": "default-src 'none'; style-src 'unsafe-inline'; base-uri 'none'; frame-ancestors 'none'",
|
|
291
|
+
"cache-control": "no-store",
|
|
292
|
+
"referrer-policy": "no-referrer",
|
|
293
|
+
"x-content-type-options": "nosniff"
|
|
278
294
|
});
|
|
279
|
-
response.end(
|
|
295
|
+
response.end(renderExpiredConnection());
|
|
280
296
|
return true;
|
|
281
297
|
}
|
|
282
298
|
const controller = new AbortController();
|
|
@@ -312,13 +328,15 @@ export async function prepareHostedOAuthRuntime(config) {
|
|
|
312
328
|
const safeError = error instanceof HostedOAuthLoginError
|
|
313
329
|
? error.message
|
|
314
330
|
: "Sign-in failed. Please try again.";
|
|
331
|
+
const login = renderLogin(displayName, fields, transaction, csrf, safeError, values);
|
|
315
332
|
response.writeHead(400, {
|
|
316
333
|
"content-type": "text/html; charset=utf-8",
|
|
317
|
-
"content-security-policy":
|
|
334
|
+
"content-security-policy": login.contentSecurityPolicy,
|
|
318
335
|
"cache-control": "no-store",
|
|
319
|
-
"referrer-policy": "no-referrer"
|
|
336
|
+
"referrer-policy": "no-referrer",
|
|
337
|
+
"x-content-type-options": "nosniff"
|
|
320
338
|
});
|
|
321
|
-
response.end(
|
|
339
|
+
response.end(login.html);
|
|
322
340
|
}
|
|
323
341
|
return true;
|
|
324
342
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -95,6 +95,12 @@ export interface Renderers<TResult> {
|
|
|
95
95
|
markdown?: (result: TResult, primitives: RenderPrimitives) => string;
|
|
96
96
|
json?: (result: TResult, primitives: RenderPrimitives) => unknown;
|
|
97
97
|
}
|
|
98
|
+
export interface ToolAnnotations {
|
|
99
|
+
readOnlyHint?: boolean;
|
|
100
|
+
destructiveHint?: boolean;
|
|
101
|
+
idempotentHint?: boolean;
|
|
102
|
+
openWorldHint?: boolean;
|
|
103
|
+
}
|
|
98
104
|
export type HandlerContext<TParamsSchema extends ObjectSchema<any> = AnyObjectSchema, TSecrets extends SecretDeclarations | undefined = undefined, TServices extends object = EmptyServices> = TServices & {
|
|
99
105
|
params: Static<TParamsSchema>;
|
|
100
106
|
secrets: InferSecrets<TSecrets>;
|
|
@@ -106,7 +112,9 @@ export type HandlerContext<TParamsSchema extends ObjectSchema<any> = AnyObjectSc
|
|
|
106
112
|
};
|
|
107
113
|
export interface CommandConfig<TServices extends object, TParamsSchema extends ObjectSchema<any>, TSecrets extends SecretDeclarations | undefined, TResult> {
|
|
108
114
|
name: string;
|
|
115
|
+
title?: string;
|
|
109
116
|
description?: string;
|
|
117
|
+
annotations?: ToolAnnotations;
|
|
110
118
|
hidden?: boolean;
|
|
111
119
|
examples?: CommandExample[];
|
|
112
120
|
aliases?: string[];
|
|
@@ -138,7 +146,9 @@ export interface StreamCommandConfig<TServices extends object, TParamsSchema ext
|
|
|
138
146
|
export interface Command<TServices extends object = EmptyServices, TParamsSchema extends ObjectSchema<any> = AnyObjectSchema, TSecrets extends SecretDeclarations | undefined = undefined, TResult = unknown> {
|
|
139
147
|
kind: "command";
|
|
140
148
|
name: string;
|
|
149
|
+
title?: string;
|
|
141
150
|
description?: string;
|
|
151
|
+
annotations?: ToolAnnotations;
|
|
142
152
|
hidden: boolean;
|
|
143
153
|
examples: CommandExample[];
|
|
144
154
|
aliases: string[];
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,9 @@ function cloneRequires(requires) {
|
|
|
33
33
|
check: requires.check
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
+
function cloneToolAnnotations(annotations) {
|
|
37
|
+
return annotations === undefined ? undefined : { ...annotations };
|
|
38
|
+
}
|
|
36
39
|
function cloneStringArray(values) {
|
|
37
40
|
return values === undefined ? undefined : [...values];
|
|
38
41
|
}
|
|
@@ -291,7 +294,9 @@ function createBaseCommand(config) {
|
|
|
291
294
|
const command = {
|
|
292
295
|
kind: "command",
|
|
293
296
|
name: config.name,
|
|
297
|
+
title: config.title,
|
|
294
298
|
description: config.description,
|
|
299
|
+
annotations: cloneToolAnnotations(config.annotations),
|
|
295
300
|
hidden: config.hidden ?? false,
|
|
296
301
|
examples: cloneCommandExamples(config.examples),
|
|
297
302
|
aliases: [...(config.aliases ?? [])],
|
|
@@ -309,6 +314,8 @@ function createBaseCommand(config) {
|
|
|
309
314
|
};
|
|
310
315
|
Object.defineProperty(command, commandConfigSymbol, {
|
|
311
316
|
value: {
|
|
317
|
+
title: config.title,
|
|
318
|
+
annotations: cloneToolAnnotations(config.annotations),
|
|
312
319
|
scope: cloneScope(config.scope),
|
|
313
320
|
hidden: config.hidden ?? false,
|
|
314
321
|
examples: cloneCommandExamples(config.examples),
|
|
@@ -360,7 +367,9 @@ function materializeCommand(command, inherited) {
|
|
|
360
367
|
const materialized = {
|
|
361
368
|
kind: "command",
|
|
362
369
|
name: command.name,
|
|
370
|
+
title: internal.title,
|
|
363
371
|
description: command.description,
|
|
372
|
+
annotations: cloneToolAnnotations(internal.annotations),
|
|
364
373
|
hidden: internal.hidden,
|
|
365
374
|
examples: cloneCommandExamples(internal.examples),
|
|
366
375
|
aliases: [...command.aliases],
|
|
@@ -378,6 +387,8 @@ function materializeCommand(command, inherited) {
|
|
|
378
387
|
};
|
|
379
388
|
Object.defineProperty(materialized, commandConfigSymbol, {
|
|
380
389
|
value: {
|
|
390
|
+
title: internal.title,
|
|
391
|
+
annotations: cloneToolAnnotations(internal.annotations),
|
|
381
392
|
scope: cloneScope(internal.scope),
|
|
382
393
|
hidden: internal.hidden,
|
|
383
394
|
examples: cloneCommandExamples(internal.examples),
|
package/dist/mcp.js
CHANGED
|
@@ -222,6 +222,8 @@ function enumerateTools(root, casing, allowlist, omitRootToolNamePrefix) {
|
|
|
222
222
|
command: node,
|
|
223
223
|
commandPath: resolvedCommandPath,
|
|
224
224
|
name,
|
|
225
|
+
...(node.title === undefined ? {} : { title: node.title }),
|
|
226
|
+
...(node.annotations === undefined ? {} : { annotations: { ...node.annotations } }),
|
|
225
227
|
description: buildToolDescription(node.description, params, node.examples, node.name, casing),
|
|
226
228
|
inputSchema: applySchemaCasing(toJsonSchema(params), casing),
|
|
227
229
|
...(node.result === undefined
|
|
@@ -915,12 +917,18 @@ function createResolvedMCPServer(root, options, runtime = {}) {
|
|
|
915
917
|
throw toToolError(error, report?.displayPath);
|
|
916
918
|
}
|
|
917
919
|
};
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
920
|
+
server.registerTool({
|
|
921
|
+
name: tool.name,
|
|
922
|
+
...(tool.title === undefined ? {} : { title: tool.title }),
|
|
923
|
+
description: tool.description,
|
|
924
|
+
inputSchema: tool.inputSchema,
|
|
925
|
+
...(tool.outputSchema === undefined
|
|
926
|
+
? {}
|
|
927
|
+
: {
|
|
928
|
+
outputSchema: tool.outputSchema
|
|
929
|
+
}),
|
|
930
|
+
...(tool.annotations === undefined ? {} : { annotations: tool.annotations })
|
|
931
|
+
}, handler);
|
|
924
932
|
}
|
|
925
933
|
return {
|
|
926
934
|
...server,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.146",
|
|
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.146",
|
|
162
162
|
"toolcraft-design": "*",
|
|
163
163
|
"@poe-code/frontmatter": "*",
|
|
164
164
|
"@poe-code/agent-mcp-config": "*",
|