@cat-factory/server 0.217.0 → 0.219.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/dist/agents/capabilityCredentialResolver.d.ts +23 -0
- package/dist/agents/capabilityCredentialResolver.d.ts.map +1 -1
- package/dist/agents/capabilityCredentialResolver.js +18 -0
- package/dist/agents/capabilityCredentialResolver.js.map +1 -1
- package/dist/agents/jobBody.js +1 -1
- package/dist/agents/jobBody.js.map +1 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +2 -0
- package/dist/app.js.map +1 -1
- package/dist/http/env.d.ts +16 -1
- package/dist/http/env.d.ts.map +1 -1
- package/dist/http/requestLogging.d.ts.map +1 -1
- package/dist/http/requestLogging.js +17 -1
- package/dist/http/requestLogging.js.map +1 -1
- package/dist/http/workspaceAccess.d.ts +42 -0
- package/dist/http/workspaceAccess.d.ts.map +1 -1
- package/dist/http/workspaceAccess.js +48 -0
- package/dist/http/workspaceAccess.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/capabilityCredentials/CapabilityCredentialsController.d.ts +5 -0
- package/dist/modules/capabilityCredentials/CapabilityCredentialsController.d.ts.map +1 -1
- package/dist/modules/capabilityCredentials/CapabilityCredentialsController.js +14 -2
- package/dist/modules/capabilityCredentials/CapabilityCredentialsController.js.map +1 -1
- package/dist/modules/capabilityCredentials/declaredCredentials.d.ts.map +1 -1
- package/dist/modules/capabilityCredentials/declaredCredentials.js +6 -0
- package/dist/modules/capabilityCredentials/declaredCredentials.js.map +1 -1
- package/dist/modules/environments/EnvironmentController.js +4 -1
- package/dist/modules/environments/EnvironmentController.js.map +1 -1
- package/dist/modules/publicApi/PublicApiController.js +14 -9
- package/dist/modules/publicApi/PublicApiController.js.map +1 -1
- package/dist/modules/toolServers/ToolServerController.d.ts +22 -0
- package/dist/modules/toolServers/ToolServerController.d.ts.map +1 -0
- package/dist/modules/toolServers/ToolServerController.js +57 -0
- package/dist/modules/toolServers/ToolServerController.js.map +1 -0
- package/dist/modules/toolServers/declaredToolServers.d.ts +45 -0
- package/dist/modules/toolServers/declaredToolServers.d.ts.map +1 -0
- package/dist/modules/toolServers/declaredToolServers.js +108 -0
- package/dist/modules/toolServers/declaredToolServers.js.map +1 -0
- package/dist/modules/toolServers/mcpProbe.d.ts +50 -0
- package/dist/modules/toolServers/mcpProbe.d.ts.map +1 -0
- package/dist/modules/toolServers/mcpProbe.js +611 -0
- package/dist/modules/toolServers/mcpProbe.js.map +1 -0
- package/dist/modules/toolServers/probeToolServer.d.ts +30 -0
- package/dist/modules/toolServers/probeToolServer.d.ts.map +1 -0
- package/dist/modules/toolServers/probeToolServer.js +170 -0
- package/dist/modules/toolServers/probeToolServer.js.map +1 -0
- package/dist/modules/workspaces/WorkspaceController.d.ts.map +1 -1
- package/dist/modules/workspaces/WorkspaceController.js +7 -0
- package/dist/modules/workspaces/WorkspaceController.js.map +1 -1
- package/dist/persistence/rpc-allowlist.d.ts.map +1 -1
- package/dist/persistence/rpc-allowlist.js +5 -0
- package/dist/persistence/rpc-allowlist.js.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { isAllowedMcpHttpUrl, isLoopbackMcpHttpUrl, mcpServableHarnesses, redactSecrets, } from '@cat-factory/kernel';
|
|
2
|
+
import { stripUrlCredentials } from '../../agents/agentContextRecord.js';
|
|
3
|
+
/**
|
|
4
|
+
* Every declared tool server by id — the ONE resolution both halves of this surface use.
|
|
5
|
+
*
|
|
6
|
+
* Shared rather than re-derived per caller, because the two halves disagreeing about which
|
|
7
|
+
* definition an id names is invisible and mean: the row would describe one endpoint while the Test
|
|
8
|
+
* button probed another, both labelled with the same id. So the LIST and the PROBE ask this.
|
|
9
|
+
*
|
|
10
|
+
* Two sources, unioned, because neither is complete on its own:
|
|
11
|
+
*
|
|
12
|
+
* - walking `kindsWithCapabilities()` finds servers a kind actually gets, inline definitions
|
|
13
|
+
* included, and is the only way to learn WHICH kinds get them (`assignToolServers('coder', …)`
|
|
14
|
+
* is the recommended attachment path and no built-in is a registry entry, which is the hole
|
|
15
|
+
* `kindsWithCapabilities` exists to close);
|
|
16
|
+
* - `allToolServers()` finds registrations attached to NOTHING, which the walk structurally
|
|
17
|
+
* cannot see and which nothing else in the platform reports. Such a server never reaches a
|
|
18
|
+
* dispatch, so its credentials are keys an operator fills in for no run — reported with an
|
|
19
|
+
* empty `declaredBy` rather than filtered out, because only the operator can tell a
|
|
20
|
+
* work-in-progress registration from a kind that lost its assignment in a refactor.
|
|
21
|
+
*
|
|
22
|
+
* First definition wins, matching `normalizeToolRefs`: a kind may declare an id inline while another
|
|
23
|
+
* references the registration, and the dispatch resolves per kind. What one surface can honestly
|
|
24
|
+
* show is one row per id, so it shows the first and names every kind.
|
|
25
|
+
*/
|
|
26
|
+
export function resolveDeclaredToolServers(registry) {
|
|
27
|
+
const declared = new Map();
|
|
28
|
+
for (const kind of registry.kindsWithCapabilities()) {
|
|
29
|
+
for (const server of registry.toolServersFor(kind).servers) {
|
|
30
|
+
const existing = declared.get(server.id);
|
|
31
|
+
if (existing)
|
|
32
|
+
existing.declaredBy.push(kind);
|
|
33
|
+
else
|
|
34
|
+
declared.set(server.id, { definition: server, declaredBy: [kind] });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (const server of registry.allToolServers()) {
|
|
38
|
+
if (!declared.has(server.id))
|
|
39
|
+
declared.set(server.id, { definition: server, declaredBy: [] });
|
|
40
|
+
}
|
|
41
|
+
return declared;
|
|
42
|
+
}
|
|
43
|
+
/** Every declared tool server, projected non-secretly and sorted by id. */
|
|
44
|
+
export function collectDeclaredToolServers(input) {
|
|
45
|
+
return [...resolveDeclaredToolServers(input.agentKindRegistry).values()]
|
|
46
|
+
.map((declared) => toView(declared.definition, declared.declaredBy))
|
|
47
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
48
|
+
}
|
|
49
|
+
/** Project one definition into its non-secret operator-facing view. */
|
|
50
|
+
function toView(definition, declaredBy) {
|
|
51
|
+
const notProbeable = notProbeableReason(definition);
|
|
52
|
+
return {
|
|
53
|
+
id: definition.id,
|
|
54
|
+
label: definition.label ?? definition.id,
|
|
55
|
+
transport: definition.transport.kind,
|
|
56
|
+
target: describeTarget(definition),
|
|
57
|
+
...(definition.guidance ? { guidance: definition.guidance } : {}),
|
|
58
|
+
declaredBy: [...declaredBy].sort(),
|
|
59
|
+
servableHarnesses: mcpServableHarnesses(definition),
|
|
60
|
+
...(definition.allowedTools?.length ? { allowedTools: definition.allowedTools } : {}),
|
|
61
|
+
credentials: (definition.secretKeys ?? []).map((secret) => ({
|
|
62
|
+
key: secret.key,
|
|
63
|
+
// `required` defaults to TRUE at the declaration site: a credential a server bothered to
|
|
64
|
+
// declare is one it needs. Resolved here so no reader repeats the default.
|
|
65
|
+
required: secret.required !== false,
|
|
66
|
+
...(secret.usage ? { usage: secret.usage } : {}),
|
|
67
|
+
})),
|
|
68
|
+
probeable: notProbeable === undefined,
|
|
69
|
+
...(notProbeable ? { notProbeableReason: notProbeable } : {}),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* What the declaration points at, for recognition on the surface.
|
|
74
|
+
*
|
|
75
|
+
* BOTH shapes are scrubbed before they reach a browser, because both are places a credential can
|
|
76
|
+
* legitimately sit. A url carries userinfo: `https://user:token@mcp.example` is a declaration this
|
|
77
|
+
* platform accepts (`isAllowedMcpHttpUrl` only rules on the scheme and host), so it goes through
|
|
78
|
+
* `stripUrlCredentials`. A `stdio` command line carries `--token=…` just as easily, and it is the
|
|
79
|
+
* more tempting spot of the two for a deployment that has not found `secretKeys` yet — so the joined
|
|
80
|
+
* argv goes through `redactSecrets`. Values in the credential store are write-only, which makes this
|
|
81
|
+
* the one place on the surface where a pasted secret could otherwise be READ back.
|
|
82
|
+
*/
|
|
83
|
+
function describeTarget(definition) {
|
|
84
|
+
if (definition.transport.kind === 'http')
|
|
85
|
+
return stripUrlCredentials(definition.transport.url);
|
|
86
|
+
const args = definition.transport.args ?? [];
|
|
87
|
+
return redactSecrets([definition.transport.command, ...args].join(' ')) ?? '';
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Why this deployment cannot probe the definition, or undefined when it can.
|
|
91
|
+
*
|
|
92
|
+
* The order matters: the transport question comes first because a `stdio` server has no url to
|
|
93
|
+
* judge at all, and answering `url_not_allowed` for one would name a fault it does not have.
|
|
94
|
+
*/
|
|
95
|
+
export function notProbeableReason(definition) {
|
|
96
|
+
if (definition.transport.kind === 'stdio')
|
|
97
|
+
return 'stdio_transport';
|
|
98
|
+
const url = definition.transport.url;
|
|
99
|
+
if (!isAllowedMcpHttpUrl(url))
|
|
100
|
+
return 'url_not_allowed';
|
|
101
|
+
// A loopback endpoint means "beside the agent, inside its own container". The backend's loopback
|
|
102
|
+
// is a different machine, so probing it would answer about the wrong process whether it succeeded
|
|
103
|
+
// or failed — and a success would be the more misleading of the two.
|
|
104
|
+
if (isLoopbackMcpHttpUrl(url))
|
|
105
|
+
return 'container_local_url';
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=declaredToolServers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"declaredToolServers.js","sourceRoot":"","sources":["../../../src/modules/toolServers/declaredToolServers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface McpProbeTarget {
|
|
2
|
+
url: string;
|
|
3
|
+
/** The non-secret headers the DECLARATION itself carries (`transport.headers`). */
|
|
4
|
+
headers: Record<string, string>;
|
|
5
|
+
/**
|
|
6
|
+
* The resolved credential headers. Never logged, never returned.
|
|
7
|
+
*
|
|
8
|
+
* Kept APART from `headers` rather than merged by the caller, because the two are treated
|
|
9
|
+
* differently at a redirect: a hop that leaves the declared origin is refused while these are
|
|
10
|
+
* present, and a declaration's own `x-tenant` is not a reason to refuse anything.
|
|
11
|
+
*/
|
|
12
|
+
credentialHeaders: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export interface McpProbeDeps {
|
|
15
|
+
/** Injected for tests; defaults to the global fetch. */
|
|
16
|
+
fetch?: typeof fetch;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
maxPages?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface McpProbeSuccess {
|
|
21
|
+
status: 'ok';
|
|
22
|
+
serverName: string;
|
|
23
|
+
serverVersion: string;
|
|
24
|
+
/** The version the SERVER negotiated, which is what the agent's CLI will speak to it. */
|
|
25
|
+
protocolVersion: string;
|
|
26
|
+
/** Every tool name read, uncapped — the caller caps what reaches the wire. */
|
|
27
|
+
tools: string[];
|
|
28
|
+
/** False when a `nextCursor` was still outstanding at {@link MCP_PROBE_MAX_PAGES}. */
|
|
29
|
+
toolsComplete: boolean;
|
|
30
|
+
}
|
|
31
|
+
export type McpProbeFailure = {
|
|
32
|
+
status: 'unreachable';
|
|
33
|
+
error: string;
|
|
34
|
+
} | {
|
|
35
|
+
status: 'http_error';
|
|
36
|
+
httpStatus: number;
|
|
37
|
+
error: string;
|
|
38
|
+
} | {
|
|
39
|
+
status: 'protocol_error';
|
|
40
|
+
error: string;
|
|
41
|
+
};
|
|
42
|
+
export type McpProbeOutcome = McpProbeSuccess | McpProbeFailure;
|
|
43
|
+
/**
|
|
44
|
+
* Speak MCP to `target` and report what happened.
|
|
45
|
+
*
|
|
46
|
+
* The caller owns the DECISION to probe at all (a stdio server has no url; a loopback one is not
|
|
47
|
+
* ours to reach) and the credential resolution that fills `headers`. This owns only the protocol.
|
|
48
|
+
*/
|
|
49
|
+
export declare function probeMcpHttpServer(target: McpProbeTarget, deps?: McpProbeDeps): Promise<McpProbeOutcome>;
|
|
50
|
+
//# sourceMappingURL=mcpProbe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpProbe.d.ts","sourceRoot":"","sources":["../../../src/modules/toolServers/mcpProbe.ts"],"names":[],"mappings":"AAiEA,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC1C;AAED,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,IAAI,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,yFAAyF;IACzF,eAAe,EAAE,MAAM,CAAA;IACvB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,sFAAsF;IACtF,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE/C,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,eAAe,CAAA;AAO/D;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,eAAe,CAAC,CAoB1B"}
|