toolfunnel 0.4.0 → 0.6.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 +102 -213
- package/bin/toolfunnel.js +372 -147
- package/docs/KNOWN_BUGS.md +99 -225
- package/docs/MANUAL.pdf +0 -0
- package/docs/design.md +70 -0
- package/docs/packaging.md +115 -115
- package/hooks/hooks.manifest.json +27 -27
- package/hooks/scripts/example-audit.js +21 -21
- package/hooks/scripts/example-deny-dangerous.js +31 -31
- package/mcp/expose.example.json +30 -30
- package/mcp/servers/mock-modern/server.js +147 -0
- package/mcp/servers/mock-upstream/server.js +192 -12
- package/package.json +1 -1
- package/src/auth/config.js +174 -174
- package/src/auth/install.js +181 -181
- package/src/auth/resource-server.js +344 -344
- package/src/core/config-home.js +134 -134
- package/src/core/events.js +105 -105
- package/src/core/hook-engine.js +275 -275
- package/src/core/hook-loader.js +791 -791
- package/src/core/hook-runner.js +346 -346
- package/src/core/logger.js +171 -171
- package/src/core/matcher.js +51 -51
- package/src/core/metrics.js +75 -75
- package/src/core/requires.js +138 -138
- package/src/core/server-config.js +98 -77
- package/src/core/tool-registry.js +180 -180
- package/src/extend/add-hook.md +152 -142
- package/src/extend/add-mcp.md +122 -121
- package/src/extend/configure.md +87 -0
- package/src/extend/create-tool.md +168 -152
- package/src/extend/howto.js +102 -98
- package/src/extend/package.md +187 -187
- package/src/extend/wrap.md +99 -0
- package/src/mcp/aggregator.js +1246 -807
- package/src/mcp/expose-store.js +460 -430
- package/src/mcp/gated-run.js +201 -194
- package/src/mcp/http-transport.js +1311 -981
- package/src/mcp/mcp-client.js +907 -530
- package/src/mcp/modern.js +372 -0
- package/src/mcp/protocol.js +468 -466
- package/src/mcp/server.js +2688 -1322
- package/src/packages/packager.js +715 -715
- package/src/tools/drift.js +138 -138
- package/src/tools/registry.js +513 -511
- package/src/tools/tool-state.js +170 -104
- package/src/ui/public/app.js +1174 -1055
- package/src/ui/public/index.html +286 -249
- package/src/ui/public/styles.css +535 -535
- package/src/ui/server.js +1348 -1190
- package/tools/scripts/base64.js +139 -139
- package/tools/scripts/danger.js +61 -61
- package/tools/scripts/echo.js +39 -39
- package/tools/scripts/hash.js +101 -101
- package/tools/scripts/json.js +109 -109
- package/tools/scripts/text-stats.js +131 -131
- package/tools/scripts/tf-env.js +43 -43
- package/tools/scripts/tf-hook-add.js +151 -151
- package/tools/scripts/tf-hook-set.js +112 -112
- package/tools/scripts/tf-list.js +192 -192
- package/tools/scripts/tf-log.js +86 -86
- package/tools/scripts/tf-mcp-add.js +117 -117
- package/tools/scripts/tf-mcp-set.js +121 -102
- package/tools/scripts/tf-pack.js +237 -237
- package/tools/scripts/tf-tool-add.js +134 -129
- package/tools/scripts/tf-tool-set.js +142 -142
- package/tools/scripts/tf-wrap.js +103 -0
- package/tools/scripts/uuid.js +102 -102
- package/tools/tools.register.json +227 -216
- package/docs/admin-ui.md +0 -404
- package/docs/configuration.md +0 -402
- package/docs/hooks-and-gating.md +0 -428
- package/docs/logging.md +0 -223
- package/docs/management.md +0 -429
- package/docs/oauth.md +0 -103
- package/docs/releasing.md +0 -31
- package/docs/setup.md +0 -352
- package/docs/tools-and-upstreams.md +0 -469
package/tools/scripts/uuid.js
CHANGED
|
@@ -1,102 +1,102 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* uuid-tool.js
|
|
6
|
-
*
|
|
7
|
-
* Purpose
|
|
8
|
-
* -------
|
|
9
|
-
* Generate one or more RFC 4122 v4 UUIDs via the Node built-in
|
|
10
|
-
* `node:crypto.randomUUID()`. Useful from the Tool Manager whenever a fresh
|
|
11
|
-
* identifier is needed. No network, no filesystem, no new deps.
|
|
12
|
-
*
|
|
13
|
-
* Contract with the register (the register's `defaultRunScript`)
|
|
14
|
-
* ----------------------------------------------------------
|
|
15
|
-
* - Structured args arrive as JSON in env TOOLFUNNEL_TOOL_ARGS.
|
|
16
|
-
* - Args: { count?: <integer> }
|
|
17
|
-
* count is clamped to the range [1, 100] so a runaway request cannot ask
|
|
18
|
-
* for an unbounded number.
|
|
19
|
-
* - Prints a SINGLE JSON object to stdout and exits 0
|
|
20
|
-
* on bad input (reported as { ok:false, error }), never a thrown exception.
|
|
21
|
-
*
|
|
22
|
-
* Output (stdout), exactly one JSON object:
|
|
23
|
-
* success: { ok:true, uuids: [ "...", ... ] }
|
|
24
|
-
* failure: { ok:false, error }
|
|
25
|
-
*
|
|
26
|
-
* Safety invariants (mirror the isolation rule):
|
|
27
|
-
* - NO filesystem, NO network, NO process mutation. Pure CPU on the args.
|
|
28
|
-
* - count is hard-capped at 100; a non-integer / out-of-range count is an
|
|
29
|
-
* error rather than a silent surprise.
|
|
30
|
-
* - NEVER throws for ordinary bad input
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
const crypto = require('node:crypto');
|
|
34
|
-
|
|
35
|
-
const MAX_COUNT = 100;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Parse the structured args handed in via env TOOLFUNNEL_TOOL_ARGS.
|
|
39
|
-
* @returns {{ value: any } | { parseError: string }}
|
|
40
|
-
*/
|
|
41
|
-
function parseStructuredArgs() {
|
|
42
|
-
const raw = process.env.TOOLFUNNEL_TOOL_ARGS;
|
|
43
|
-
if (raw === undefined || raw === null || raw === '') {
|
|
44
|
-
return { value: null };
|
|
45
|
-
}
|
|
46
|
-
try {
|
|
47
|
-
return { value: JSON.parse(raw) };
|
|
48
|
-
} catch (_err) {
|
|
49
|
-
return { parseError: `TOOLFUNNEL_TOOL_ARGS was not valid JSON: ${String(raw)}` };
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Pure core: given the parsed args, produce the result object. Never throws.
|
|
55
|
-
*
|
|
56
|
-
* @param {any} args may be null (treated as { count: 1 })
|
|
57
|
-
* @returns {object} the JSON-serialisable result
|
|
58
|
-
*/
|
|
59
|
-
function run(args) {
|
|
60
|
-
// No args (or null) is valid
|
|
61
|
-
let count = 1;
|
|
62
|
-
if (args !== null && args !== undefined) {
|
|
63
|
-
if (typeof args !== 'object' || Array.isArray(args)) {
|
|
64
|
-
return { ok: false, error: 'args must be an object { count? }' };
|
|
65
|
-
}
|
|
66
|
-
if (args.count !== undefined && args.count !== null) {
|
|
67
|
-
if (typeof args.count !== 'number' || !Number.isInteger(args.count)) {
|
|
68
|
-
return { ok: false, error: 'count must be an integer' };
|
|
69
|
-
}
|
|
70
|
-
if (args.count < 1) {
|
|
71
|
-
return { ok: false, error: 'count must be >= 1' };
|
|
72
|
-
}
|
|
73
|
-
if (args.count > MAX_COUNT) {
|
|
74
|
-
return { ok: false, error: `count must be <= ${MAX_COUNT}` };
|
|
75
|
-
}
|
|
76
|
-
count = args.count;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
const uuids = [];
|
|
80
|
-
for (let i = 0; i < count; i += 1) {
|
|
81
|
-
uuids.push(crypto.randomUUID());
|
|
82
|
-
}
|
|
83
|
-
return { ok: true, uuids };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function main() {
|
|
87
|
-
const parsed = parseStructuredArgs();
|
|
88
|
-
let payload;
|
|
89
|
-
if (parsed.parseError) {
|
|
90
|
-
payload = { ok: false, error: parsed.parseError };
|
|
91
|
-
} else {
|
|
92
|
-
try {
|
|
93
|
-
payload = run(parsed.value);
|
|
94
|
-
} catch (err) {
|
|
95
|
-
payload = { ok: false, error: `unexpected error: ${(err && err.message) || String(err)}` };
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
process.stdout.write(JSON.stringify(payload) + '\n');
|
|
99
|
-
process.exit(0);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
main();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* uuid-tool.js - a safe, dependency-free local UUID generator.
|
|
6
|
+
*
|
|
7
|
+
* Purpose
|
|
8
|
+
* -------
|
|
9
|
+
* Generate one or more RFC 4122 v4 UUIDs via the Node built-in
|
|
10
|
+
* `node:crypto.randomUUID()`. Useful from the Tool Manager whenever a fresh
|
|
11
|
+
* identifier is needed. No network, no filesystem, no new deps.
|
|
12
|
+
*
|
|
13
|
+
* Contract with the register (the register's `defaultRunScript`)
|
|
14
|
+
* ----------------------------------------------------------
|
|
15
|
+
* - Structured args arrive as JSON in env TOOLFUNNEL_TOOL_ARGS.
|
|
16
|
+
* - Args: { count?: <integer> } - how many UUIDs to mint. Defaults to 1.
|
|
17
|
+
* count is clamped to the range [1, 100] so a runaway request cannot ask
|
|
18
|
+
* for an unbounded number.
|
|
19
|
+
* - Prints a SINGLE JSON object to stdout and exits 0 - ALWAYS exit 0, even
|
|
20
|
+
* on bad input (reported as { ok:false, error }), never a thrown exception.
|
|
21
|
+
*
|
|
22
|
+
* Output (stdout), exactly one JSON object:
|
|
23
|
+
* success: { ok:true, uuids: [ "...", ... ] }
|
|
24
|
+
* failure: { ok:false, error }
|
|
25
|
+
*
|
|
26
|
+
* Safety invariants (mirror the isolation rule):
|
|
27
|
+
* - NO filesystem, NO network, NO process mutation. Pure CPU on the args.
|
|
28
|
+
* - count is hard-capped at 100; a non-integer / out-of-range count is an
|
|
29
|
+
* error rather than a silent surprise.
|
|
30
|
+
* - NEVER throws for ordinary bad input - only well-shaped JSON on stdout.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
const crypto = require('node:crypto');
|
|
34
|
+
|
|
35
|
+
const MAX_COUNT = 100;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Parse the structured args handed in via env TOOLFUNNEL_TOOL_ARGS.
|
|
39
|
+
* @returns {{ value: any } | { parseError: string }}
|
|
40
|
+
*/
|
|
41
|
+
function parseStructuredArgs() {
|
|
42
|
+
const raw = process.env.TOOLFUNNEL_TOOL_ARGS;
|
|
43
|
+
if (raw === undefined || raw === null || raw === '') {
|
|
44
|
+
return { value: null };
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
return { value: JSON.parse(raw) };
|
|
48
|
+
} catch (_err) {
|
|
49
|
+
return { parseError: `TOOLFUNNEL_TOOL_ARGS was not valid JSON: ${String(raw)}` };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Pure core: given the parsed args, produce the result object. Never throws.
|
|
55
|
+
*
|
|
56
|
+
* @param {any} args may be null (treated as { count: 1 })
|
|
57
|
+
* @returns {object} the JSON-serialisable result
|
|
58
|
+
*/
|
|
59
|
+
function run(args) {
|
|
60
|
+
// No args (or null) is valid - default to a single UUID.
|
|
61
|
+
let count = 1;
|
|
62
|
+
if (args !== null && args !== undefined) {
|
|
63
|
+
if (typeof args !== 'object' || Array.isArray(args)) {
|
|
64
|
+
return { ok: false, error: 'args must be an object { count? }' };
|
|
65
|
+
}
|
|
66
|
+
if (args.count !== undefined && args.count !== null) {
|
|
67
|
+
if (typeof args.count !== 'number' || !Number.isInteger(args.count)) {
|
|
68
|
+
return { ok: false, error: 'count must be an integer' };
|
|
69
|
+
}
|
|
70
|
+
if (args.count < 1) {
|
|
71
|
+
return { ok: false, error: 'count must be >= 1' };
|
|
72
|
+
}
|
|
73
|
+
if (args.count > MAX_COUNT) {
|
|
74
|
+
return { ok: false, error: `count must be <= ${MAX_COUNT}` };
|
|
75
|
+
}
|
|
76
|
+
count = args.count;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const uuids = [];
|
|
80
|
+
for (let i = 0; i < count; i += 1) {
|
|
81
|
+
uuids.push(crypto.randomUUID());
|
|
82
|
+
}
|
|
83
|
+
return { ok: true, uuids };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function main() {
|
|
87
|
+
const parsed = parseStructuredArgs();
|
|
88
|
+
let payload;
|
|
89
|
+
if (parsed.parseError) {
|
|
90
|
+
payload = { ok: false, error: parsed.parseError };
|
|
91
|
+
} else {
|
|
92
|
+
try {
|
|
93
|
+
payload = run(parsed.value);
|
|
94
|
+
} catch (err) {
|
|
95
|
+
payload = { ok: false, error: `unexpected error: ${(err && err.message) || String(err)}` };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
process.stdout.write(JSON.stringify(payload) + '\n');
|
|
99
|
+
process.exit(0);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
main();
|