@webpieces/mcp-server 0.4.804 → 0.4.806
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/package.json +6 -6
- package/src/__tests__/McpRemoteFixtures.d.ts +11 -0
- package/src/__tests__/McpRemoteFixtures.js +25 -7
- package/src/__tests__/McpRemoteFixtures.js.map +1 -1
- package/src/__tests__/WpMcpServerTestFixtures.d.ts +9 -0
- package/src/__tests__/WpMcpServerTestFixtures.js +13 -2
- package/src/__tests__/WpMcpServerTestFixtures.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/mcp-server",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.806",
|
|
4
4
|
"description": "Secure MCP tool generation from annotated Webpieces API contracts",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -24,15 +24,15 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@modelcontextprotocol/node": "2.0.0",
|
|
26
26
|
"@modelcontextprotocol/server": "2.0.0",
|
|
27
|
-
"@webpieces/core-context": "0.4.
|
|
28
|
-
"@webpieces/core-util": "0.4.
|
|
29
|
-
"@webpieces/http-routing": "0.4.
|
|
30
|
-
"@webpieces/http-server": "0.4.
|
|
27
|
+
"@webpieces/core-context": "0.4.806",
|
|
28
|
+
"@webpieces/core-util": "0.4.806",
|
|
29
|
+
"@webpieces/http-routing": "0.4.806",
|
|
30
|
+
"@webpieces/http-server": "0.4.806",
|
|
31
31
|
"express": "5.1.0",
|
|
32
32
|
"reflect-metadata": "0.2.2",
|
|
33
33
|
"tslib": "2.8.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@webpieces/http-client-node": "0.4.
|
|
36
|
+
"@webpieces/http-client-node": "0.4.806"
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -12,34 +12,45 @@ export declare const EXTERNAL_MCP_BEARER = "external-mcp-access-token";
|
|
|
12
12
|
export declare const LOCAL_ENDPOINT_JWT = "local-endpoint-jwt-that-must-not-cross-the-remote-hop";
|
|
13
13
|
export declare const GATEWAY_PATH = "/gateway/mcp";
|
|
14
14
|
export declare class RemoteRequest {
|
|
15
|
+
/** Search text */
|
|
15
16
|
query: string;
|
|
16
17
|
constructor(query?: string);
|
|
17
18
|
}
|
|
18
19
|
export declare class RemoteResponse {
|
|
20
|
+
/** Delegated user */
|
|
19
21
|
user: string;
|
|
22
|
+
/** Delegated roles */
|
|
20
23
|
roles: string;
|
|
24
|
+
/** Result */
|
|
21
25
|
result: string;
|
|
22
26
|
constructor(user?: string, roles?: string, result?: string);
|
|
23
27
|
}
|
|
24
28
|
export declare abstract class RemoteMcpApi {
|
|
29
|
+
/** Calls a remote Webpieces API. */
|
|
25
30
|
search(_request: RemoteRequest): Promise<RemoteResponse>;
|
|
26
31
|
}
|
|
27
32
|
export declare abstract class MissingRemoteMcpApi {
|
|
33
|
+
/** Intentionally absent route. */
|
|
28
34
|
search(_request: RemoteRequest): Promise<RemoteResponse>;
|
|
29
35
|
}
|
|
30
36
|
export declare abstract class RefusedRemoteApi {
|
|
37
|
+
/** Nothing listens on this port. */
|
|
31
38
|
search(_request: RemoteRequest): Promise<RemoteResponse>;
|
|
32
39
|
}
|
|
33
40
|
export declare abstract class GarbageRemoteApi {
|
|
41
|
+
/** Answers an undecodable body. */
|
|
34
42
|
search(_request: RemoteRequest): Promise<RemoteResponse>;
|
|
35
43
|
}
|
|
36
44
|
export declare abstract class OidcFailRemoteApi {
|
|
45
|
+
/** Its OIDC token cannot be minted. */
|
|
37
46
|
search(_request: RemoteRequest): Promise<RemoteResponse>;
|
|
38
47
|
}
|
|
39
48
|
export declare abstract class LocalThrowApi {
|
|
49
|
+
/** Throws the requested failure in-process. */
|
|
40
50
|
fail(_request: RemoteRequest): Promise<RemoteResponse>;
|
|
41
51
|
}
|
|
42
52
|
export declare abstract class RemoteThrowApi {
|
|
53
|
+
/** Throws the requested failure remotely. */
|
|
43
54
|
fail(_request: RemoteRequest): Promise<RemoteResponse>;
|
|
44
55
|
}
|
|
45
56
|
/**
|
|
@@ -19,6 +19,7 @@ exports.EXTERNAL_MCP_BEARER = 'external-mcp-access-token';
|
|
|
19
19
|
exports.LOCAL_ENDPOINT_JWT = 'local-endpoint-jwt-that-must-not-cross-the-remote-hop';
|
|
20
20
|
exports.GATEWAY_PATH = '/gateway/mcp';
|
|
21
21
|
let RemoteRequest = class RemoteRequest {
|
|
22
|
+
/** Search text */
|
|
22
23
|
query;
|
|
23
24
|
constructor(query) {
|
|
24
25
|
if (query !== undefined)
|
|
@@ -35,8 +36,11 @@ exports.RemoteRequest = RemoteRequest = tslib_1.__decorate([
|
|
|
35
36
|
tslib_1.__metadata("design:paramtypes", [String])
|
|
36
37
|
], RemoteRequest);
|
|
37
38
|
let RemoteResponse = class RemoteResponse {
|
|
39
|
+
/** Delegated user */
|
|
38
40
|
user;
|
|
41
|
+
/** Delegated roles */
|
|
39
42
|
roles;
|
|
43
|
+
/** Result */
|
|
40
44
|
result;
|
|
41
45
|
constructor(user, roles, result) {
|
|
42
46
|
if (user !== undefined)
|
|
@@ -65,6 +69,7 @@ exports.RemoteResponse = RemoteResponse = tslib_1.__decorate([
|
|
|
65
69
|
tslib_1.__metadata("design:paramtypes", [String, String, String])
|
|
66
70
|
], RemoteResponse);
|
|
67
71
|
let RemoteMcpApi = class RemoteMcpApi {
|
|
72
|
+
/** Calls a remote Webpieces API. */
|
|
68
73
|
search(_request) {
|
|
69
74
|
throw new Error('contract only');
|
|
70
75
|
}
|
|
@@ -85,9 +90,11 @@ tslib_1.__decorate([
|
|
|
85
90
|
tslib_1.__metadata("design:returntype", Promise)
|
|
86
91
|
], RemoteMcpApi.prototype, "search", null);
|
|
87
92
|
exports.RemoteMcpApi = RemoteMcpApi = tslib_1.__decorate([
|
|
88
|
-
(0, core_util_1.ApiPath)('/remote-mcp')
|
|
93
|
+
(0, core_util_1.ApiPath)('/remote-mcp'),
|
|
94
|
+
(0, core_util_1.ApiType)(core_util_1.SVC_TO_SVC, core_util_1.MCP)
|
|
89
95
|
], RemoteMcpApi);
|
|
90
96
|
let MissingRemoteMcpApi = class MissingRemoteMcpApi {
|
|
97
|
+
/** Intentionally absent route. */
|
|
91
98
|
search(_request) {
|
|
92
99
|
throw new Error('contract only');
|
|
93
100
|
}
|
|
@@ -108,9 +115,11 @@ tslib_1.__decorate([
|
|
|
108
115
|
tslib_1.__metadata("design:returntype", Promise)
|
|
109
116
|
], MissingRemoteMcpApi.prototype, "search", null);
|
|
110
117
|
exports.MissingRemoteMcpApi = MissingRemoteMcpApi = tslib_1.__decorate([
|
|
111
|
-
(0, core_util_1.ApiPath)('/missing-remote-mcp')
|
|
118
|
+
(0, core_util_1.ApiPath)('/missing-remote-mcp'),
|
|
119
|
+
(0, core_util_1.ApiType)(core_util_1.SVC_TO_SVC, core_util_1.MCP)
|
|
112
120
|
], MissingRemoteMcpApi);
|
|
113
121
|
let RefusedRemoteApi = class RefusedRemoteApi {
|
|
122
|
+
/** Nothing listens on this port. */
|
|
114
123
|
search(_request) {
|
|
115
124
|
throw new Error('contract only');
|
|
116
125
|
}
|
|
@@ -131,9 +140,11 @@ tslib_1.__decorate([
|
|
|
131
140
|
tslib_1.__metadata("design:returntype", Promise)
|
|
132
141
|
], RefusedRemoteApi.prototype, "search", null);
|
|
133
142
|
exports.RefusedRemoteApi = RefusedRemoteApi = tslib_1.__decorate([
|
|
134
|
-
(0, core_util_1.ApiPath)('/refused-remote-mcp')
|
|
143
|
+
(0, core_util_1.ApiPath)('/refused-remote-mcp'),
|
|
144
|
+
(0, core_util_1.ApiType)(core_util_1.SVC_TO_SVC, core_util_1.MCP)
|
|
135
145
|
], RefusedRemoteApi);
|
|
136
146
|
let GarbageRemoteApi = class GarbageRemoteApi {
|
|
147
|
+
/** Answers an undecodable body. */
|
|
137
148
|
search(_request) {
|
|
138
149
|
throw new Error('contract only');
|
|
139
150
|
}
|
|
@@ -154,9 +165,11 @@ tslib_1.__decorate([
|
|
|
154
165
|
tslib_1.__metadata("design:returntype", Promise)
|
|
155
166
|
], GarbageRemoteApi.prototype, "search", null);
|
|
156
167
|
exports.GarbageRemoteApi = GarbageRemoteApi = tslib_1.__decorate([
|
|
157
|
-
(0, core_util_1.ApiPath)('/garbage-remote-mcp')
|
|
168
|
+
(0, core_util_1.ApiPath)('/garbage-remote-mcp'),
|
|
169
|
+
(0, core_util_1.ApiType)(core_util_1.SVC_TO_SVC, core_util_1.MCP)
|
|
158
170
|
], GarbageRemoteApi);
|
|
159
171
|
let OidcFailRemoteApi = class OidcFailRemoteApi {
|
|
172
|
+
/** Its OIDC token cannot be minted. */
|
|
160
173
|
search(_request) {
|
|
161
174
|
throw new Error('contract only');
|
|
162
175
|
}
|
|
@@ -177,9 +190,11 @@ tslib_1.__decorate([
|
|
|
177
190
|
tslib_1.__metadata("design:returntype", Promise)
|
|
178
191
|
], OidcFailRemoteApi.prototype, "search", null);
|
|
179
192
|
exports.OidcFailRemoteApi = OidcFailRemoteApi = tslib_1.__decorate([
|
|
180
|
-
(0, core_util_1.ApiPath)('/oidc-fail-remote-mcp')
|
|
193
|
+
(0, core_util_1.ApiPath)('/oidc-fail-remote-mcp'),
|
|
194
|
+
(0, core_util_1.ApiType)(core_util_1.SVC_TO_SVC, core_util_1.MCP)
|
|
181
195
|
], OidcFailRemoteApi);
|
|
182
196
|
let LocalThrowApi = class LocalThrowApi {
|
|
197
|
+
/** Throws the requested failure in-process. */
|
|
183
198
|
fail(_request) {
|
|
184
199
|
throw new Error('contract only');
|
|
185
200
|
}
|
|
@@ -200,9 +215,11 @@ tslib_1.__decorate([
|
|
|
200
215
|
tslib_1.__metadata("design:returntype", Promise)
|
|
201
216
|
], LocalThrowApi.prototype, "fail", null);
|
|
202
217
|
exports.LocalThrowApi = LocalThrowApi = tslib_1.__decorate([
|
|
203
|
-
(0, core_util_1.ApiPath)('/local-throw')
|
|
218
|
+
(0, core_util_1.ApiPath)('/local-throw'),
|
|
219
|
+
(0, core_util_1.ApiType)(core_util_1.SVC_TO_SVC, core_util_1.MCP)
|
|
204
220
|
], LocalThrowApi);
|
|
205
221
|
let RemoteThrowApi = class RemoteThrowApi {
|
|
222
|
+
/** Throws the requested failure remotely. */
|
|
206
223
|
fail(_request) {
|
|
207
224
|
throw new Error('contract only');
|
|
208
225
|
}
|
|
@@ -223,7 +240,8 @@ tslib_1.__decorate([
|
|
|
223
240
|
tslib_1.__metadata("design:returntype", Promise)
|
|
224
241
|
], RemoteThrowApi.prototype, "fail", null);
|
|
225
242
|
exports.RemoteThrowApi = RemoteThrowApi = tslib_1.__decorate([
|
|
226
|
-
(0, core_util_1.ApiPath)('/remote-throw')
|
|
243
|
+
(0, core_util_1.ApiPath)('/remote-throw'),
|
|
244
|
+
(0, core_util_1.ApiType)(core_util_1.SVC_TO_SVC, core_util_1.MCP)
|
|
227
245
|
], RemoteThrowApi);
|
|
228
246
|
/**
|
|
229
247
|
* One named throw, run identically behind the local and the remote binding.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpRemoteFixtures.js","sourceRoot":"","sources":["../../../../../../packages/http/mcp-server/src/__tests__/McpRemoteFixtures.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { injectable } from 'inversify';\nimport {\n ApiBadRequestError,\n ApiCodedError,\n ApiConflictError,\n ApiConnectionError,\n ApiDependencyBackoffError,\n ApiDependencyError,\n ApiDependencyTimeoutError,\n ApiEndpointNotFoundError,\n ApiEndUserError,\n ApiErrorCodec,\n ApiErrorHttpStatus,\n ApiForbiddenError,\n ApiImplementationError,\n ApiNotFoundError,\n ApiNotImplementedError,\n ApiPath,\n ApiPreconditionFailedError,\n ApiRateLimitedError,\n ApiRequestTimeoutError,\n ApiUnauthorizedError,\n ApiUnavailableError,\n ApiUnprocessableError,\n ApiUnsupportedMediaTypeError,\n ContextKey,\n Endpoint,\n ErrorTranslator,\n Filter,\n WebpiecesDefaultErrorTranslator,\n HttpResponseDto,\n LogLevel,\n Service,\n WebpiecesCoreHeaders,\n WpAuthJwt,\n WpAuthOidc,\n WpDto,\n WpDtoField,\n WpDtoFieldOptions,\n WpMcpAuthJwt,\n WpMcpTool,\n WpResponseDto,\n POST,\n READ,\n RPC,\n} from '@webpieces/core-util';\nimport { RequestContext } from '@webpieces/core-context';\nimport { MethodMeta, OidcHook, WpResponse } from '@webpieces/http-routing';\n\n/** Contracts, controllers and test doubles for McpRemoteBinding.integration.spec.ts. */\n\nexport const REMOTE_USER = ContextKey.trusted<string>(\n 'mcpRemoteUser',\n 'verified by the MCP access-token authority before delegation',\n 'x-mcp-remote-user',\n);\nexport const REMOTE_ROLES = ContextKey.trusted<string>(\n 'mcpRemoteRoles',\n 'verified by the MCP access-token authority before delegation',\n 'x-mcp-remote-roles',\n);\nexport const REMOTE_SERVICE = 'mcp-remote-integration';\nexport const REFUSED_SERVICE = 'mcp-remote-refused';\nexport const GARBAGE_SERVICE = 'mcp-remote-garbage';\nexport const OIDC_TOKEN = 'oidc-for-mcp-remote-integration';\nexport const EXTERNAL_MCP_BEARER = 'external-mcp-access-token';\nexport const LOCAL_ENDPOINT_JWT = 'local-endpoint-jwt-that-must-not-cross-the-remote-hop';\nexport const GATEWAY_PATH = '/gateway/mcp';\n\n@WpDto()\nexport class RemoteRequest {\n @WpDtoField(new WpDtoFieldOptions('Search text', true))\n query!: string;\n\n constructor(query?: string) {\n if (query !== undefined) this.query = query;\n }\n}\n\n@WpDto()\nexport class RemoteResponse {\n @WpDtoField(new WpDtoFieldOptions('Delegated user', true))\n user!: string;\n\n @WpDtoField(new WpDtoFieldOptions('Delegated roles', true))\n roles!: string;\n\n @WpDtoField(new WpDtoFieldOptions('Result', true))\n result!: string;\n\n constructor(user?: string, roles?: string, result?: string) {\n if (user !== undefined) this.user = user;\n if (roles !== undefined) this.roles = roles;\n if (result !== undefined) this.result = result;\n }\n}\n\n@ApiPath('/remote-mcp')\nexport abstract class RemoteMcpApi {\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'remote_integration_search',\n description: 'Calls a remote Webpieces API.',\n openWorldHint: false,\n })\n search(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/missing-remote-mcp')\nexport abstract class MissingRemoteMcpApi {\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'missing_remote_integration_search',\n description: 'Intentionally absent route.',\n openWorldHint: false,\n })\n search(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/refused-remote-mcp')\nexport abstract class RefusedRemoteApi {\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'refused_remote',\n description: 'Nothing listens on this port.',\n openWorldHint: false,\n })\n search(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/garbage-remote-mcp')\nexport abstract class GarbageRemoteApi {\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'garbage_remote',\n description: 'Answers an undecodable body.',\n openWorldHint: false,\n })\n search(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/oidc-fail-remote-mcp')\nexport abstract class OidcFailRemoteApi {\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'oidc_fail_remote',\n description: 'Its OIDC token cannot be minted.',\n openWorldHint: false,\n })\n search(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/local-throw')\nexport abstract class LocalThrowApi {\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthJwt({ allRolesAllowed: true })\n @Endpoint(POST, '/throw', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'local_throw',\n description: 'Throws the requested failure in-process.',\n openWorldHint: false,\n })\n fail(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/remote-throw')\nexport abstract class RemoteThrowApi {\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/throw', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'remote_throw',\n description: 'Throws the requested failure remotely.',\n openWorldHint: false,\n })\n fail(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n/**\n * One named throw, run identically behind the local and the remote binding.\n *\n * `expectedServerLevel` is the level of the ONE operator line the failure now produces on the server\n * that raised it — `LogApiCall`'s, at `warn` for `[API-server-resp-OTHER]` (a healthy rejection of\n * the caller's mistake) and `error` for `[API-server-resp-FAIL]`. `ApiErrorBoundary` no longer\n * writes a second line of its own (#961).\n */\nexport class ThrowCase {\n constructor(\n public readonly name: string,\n public readonly expectedKind: string,\n public readonly expectedServerLevel: LogLevel,\n public readonly raise: () => never,\n ) {}\n}\n\nexport const THROW_CASES: readonly ThrowCase[] = [\n new ThrowCase('end-user', 'end-user', 'warn', () => {\n throw new ApiEndUserError('The two passwords you entered do not match.', 'PW_MISMATCH');\n }),\n new ThrowCase('bad-request', 'bad-request', 'warn', () => {\n throw new ApiBadRequestError('internal column name', '$.query', 'query must be a word');\n }),\n new ThrowCase('unauthorized', 'unauthorized', 'warn', () => {\n throw new ApiUnauthorizedError('session internals');\n }),\n new ThrowCase('forbidden', 'forbidden', 'warn', () => {\n throw new ApiForbiddenError('acl internals');\n }),\n new ThrowCase('not-found', 'not-found', 'warn', () => {\n throw new ApiNotFoundError('row 7 missing');\n }),\n new ThrowCase('endpoint-not-found', 'endpoint-not-found', 'warn', () => {\n throw new ApiEndpointNotFoundError('route internals');\n }),\n new ThrowCase('request-timeout', 'request-timeout', 'error', () => {\n throw new ApiRequestTimeoutError('slow internals');\n }),\n new ThrowCase('rate-limited', 'rate-limited', 'error', () => {\n throw new ApiRateLimitedError('quota internals');\n }),\n new ThrowCase('conflict', 'conflict', 'warn', () => {\n throw new ApiConflictError('version internals');\n }),\n new ThrowCase('unprocessable', 'unprocessable', 'warn', () => {\n throw new ApiUnprocessableError('rule internals');\n }),\n new ThrowCase('precondition-failed', 'precondition-failed', 'warn', () => {\n throw new ApiPreconditionFailedError('etag internals');\n }),\n new ThrowCase('unsupported-media-type', 'unsupported-media-type', 'warn', () => {\n throw new ApiUnsupportedMediaTypeError('parser internals');\n }),\n new ThrowCase('not-implemented', 'not-implemented', 'error', () => {\n throw new ApiNotImplementedError('feature internals');\n }),\n new ThrowCase('coded-4xx', 'coded', 'warn', () => {\n throw new ApiCodedError('quota internals', 460, 'QUOTA');\n }),\n new ThrowCase('coded-5xx', 'coded', 'error', () => {\n throw new ApiCodedError('disk internals', 507);\n }),\n new ThrowCase('implementation', 'implementation', 'error', () => {\n throw new ApiImplementationError('bug internals');\n }),\n new ThrowCase('dependency', 'dependency', 'error', () => {\n throw new ApiDependencyError('upstream internals');\n }),\n new ThrowCase('unavailable', 'unavailable', 'error', () => {\n throw new ApiUnavailableError('maintenance internals');\n }),\n new ThrowCase('dependency-timeout', 'dependency-timeout', 'error', () => {\n throw new ApiDependencyTimeoutError('upstream slow internals');\n }),\n new ThrowCase('dependency-backoff', 'dependency-backoff', 'error', () => {\n throw new ApiDependencyBackoffError('backoff internals', 42);\n }),\n new ThrowCase('connection', 'implementation', 'error', () => {\n throw new ApiConnectionError('ECONNRESET internals');\n }),\n new ThrowCase('raw-error', 'implementation', 'error', () => {\n throw new Error('SECRET-raw-internals');\n }),\n new ThrowCase('thrown-string', 'implementation', 'error', () => {\n throw 'SECRET-string-internals';\n }),\n];\n\nexport function raiseFor(query: string): never {\n const found = THROW_CASES.find((candidate: ThrowCase) => candidate.name === query);\n if (!found) throw new Error(`unknown throw case ${query}`);\n return found.raise();\n}\n\n@injectable()\nexport class RemoteMcpController extends RemoteMcpApi {\n calls = 0;\n authorization?: string;\n\n override search(request: RemoteRequest): Promise<RemoteResponse> {\n this.calls += 1;\n this.authorization = RequestContext.getRequest()?.getHeader('authorization');\n return Promise.resolve(\n new RemoteResponse(\n RequestContext.getTrusted(REMOTE_USER) ?? 'missing-user',\n RequestContext.getTrusted(REMOTE_ROLES) ?? 'missing-roles',\n `remote:${request.query}`,\n ),\n );\n }\n}\n\n@injectable()\nexport class LocalThrowController extends LocalThrowApi {\n override async fail(request: RemoteRequest): Promise<RemoteResponse> {\n return raiseFor(request.query);\n }\n}\n\n@injectable()\nexport class RemoteThrowController extends RemoteThrowApi {\n override async fail(request: RemoteRequest): Promise<RemoteResponse> {\n return raiseFor(request.query);\n }\n}\n\nexport class RecordingOidcMinter {\n readonly audiences: string[] = [];\n\n constructor(\n private readonly failure?: Error,\n private readonly token = OIDC_TOKEN,\n ) {}\n\n mintIdToken(audience: string): Promise<string> {\n this.audiences.push(audience);\n if (this.failure) return Promise.reject(this.failure);\n return Promise.resolve(this.token);\n }\n}\n\nexport class RecordingOidcVerifier extends OidcHook {\n readonly tokens: string[] = [];\n readonly callerLists: string[][] = [];\n\n override verifyOidc(token: string, callers: string[]): Promise<void> {\n this.tokens.push(token);\n this.callerLists.push(callers);\n if (token !== OIDC_TOKEN) throw new Error(`unexpected OIDC token '${token}'`);\n return Promise.resolve();\n }\n}\n\n@injectable()\nexport class BoundaryProbeFilter extends Filter<MethodMeta, WpResponse<unknown>> {\n calls = 0;\n sawLogIdentity = false;\n sawTrustedUser?: string;\n\n override filter(\n meta: MethodMeta,\n next: Service<MethodMeta, WpResponse<unknown>>,\n ): Promise<WpResponse<unknown>> {\n this.calls += 1;\n this.sawLogIdentity =\n RequestContext.getUntrusted(WebpiecesCoreHeaders.CONTROLLER) ===\n 'RemoteMcpController' &&\n RequestContext.getUntrusted(WebpiecesCoreHeaders.METHOD) === 'search';\n this.sawTrustedUser = RequestContext.getTrusted(REMOTE_USER);\n return next.invoke(meta);\n }\n}\n\n/**\n * The documented gateway opt-out from http-client-node's \"a dependency's 4xx is OUR 500\" invariant:\n * an MCP gateway relays a Webpieces peer's typed failure so the model sees the same kind it would see\n * for a local binding. `relay = false` answers \"not mine\", which is the framework default.\n */\nexport class RelayWebpiecesPeerErrors implements ErrorTranslator {\n relay = true;\n\n private readonly fallback = new WebpiecesDefaultErrorTranslator();\n\n toWire(error: Error): HttpResponseDto {\n return this.fallback.toWire(error);\n }\n\n fromWire(response: HttpResponseDto): void {\n if (this.relay && ApiErrorCodec.isPayload(response.body)) {\n const decoded = ApiErrorCodec.decode(response.body);\n const statusCode = decoded instanceof ApiCodedError ? decoded.statusCode : undefined;\n if (\n ApiErrorHttpStatus.hasCode(decoded) &&\n ApiErrorHttpStatus.codeFor(decoded.kind, statusCode) === response.status.code\n ) {\n throw decoded;\n }\n }\n this.fallback.fromWire(response);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"McpRemoteFixtures.js","sourceRoot":"","sources":["../../../../../../packages/http/mcp-server/src/__tests__/McpRemoteFixtures.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { injectable } from 'inversify';\nimport {\n ApiBadRequestError,\n ApiCodedError,\n ApiConflictError,\n ApiConnectionError,\n ApiDependencyBackoffError,\n ApiDependencyError,\n ApiDependencyTimeoutError,\n ApiEndpointNotFoundError,\n ApiEndUserError,\n ApiErrorCodec,\n ApiErrorHttpStatus,\n ApiForbiddenError,\n ApiImplementationError,\n ApiNotFoundError,\n ApiNotImplementedError,\n ApiPath,\n ApiType,\n ApiPreconditionFailedError,\n ApiRateLimitedError,\n ApiRequestTimeoutError,\n ApiUnauthorizedError,\n ApiUnavailableError,\n ApiUnprocessableError,\n ApiUnsupportedMediaTypeError,\n ContextKey,\n Endpoint,\n ErrorTranslator,\n Filter,\n WebpiecesDefaultErrorTranslator,\n HttpResponseDto,\n LogLevel,\n Service,\n WebpiecesCoreHeaders,\n WpAuthJwt,\n WpAuthOidc,\n WpDto,\n WpDtoField,\n WpDtoFieldOptions,\n WpMcpAuthJwt,\n WpMcpTool,\n WpResponseDto,\n MCP,\n POST,\n READ,\n RPC,\n SVC_TO_SVC,\n} from '@webpieces/core-util';\nimport { RequestContext } from '@webpieces/core-context';\nimport { MethodMeta, OidcHook, WpResponse } from '@webpieces/http-routing';\n\n/** Contracts, controllers and test doubles for McpRemoteBinding.integration.spec.ts. */\n\nexport const REMOTE_USER = ContextKey.trusted<string>(\n 'mcpRemoteUser',\n 'verified by the MCP access-token authority before delegation',\n 'x-mcp-remote-user',\n);\nexport const REMOTE_ROLES = ContextKey.trusted<string>(\n 'mcpRemoteRoles',\n 'verified by the MCP access-token authority before delegation',\n 'x-mcp-remote-roles',\n);\nexport const REMOTE_SERVICE = 'mcp-remote-integration';\nexport const REFUSED_SERVICE = 'mcp-remote-refused';\nexport const GARBAGE_SERVICE = 'mcp-remote-garbage';\nexport const OIDC_TOKEN = 'oidc-for-mcp-remote-integration';\nexport const EXTERNAL_MCP_BEARER = 'external-mcp-access-token';\nexport const LOCAL_ENDPOINT_JWT = 'local-endpoint-jwt-that-must-not-cross-the-remote-hop';\nexport const GATEWAY_PATH = '/gateway/mcp';\n\n@WpDto()\nexport class RemoteRequest {\n /** Search text */\n @WpDtoField(new WpDtoFieldOptions('Search text', true))\n query!: string;\n\n constructor(query?: string) {\n if (query !== undefined) this.query = query;\n }\n}\n\n@WpDto()\nexport class RemoteResponse {\n /** Delegated user */\n @WpDtoField(new WpDtoFieldOptions('Delegated user', true))\n user!: string;\n\n /** Delegated roles */\n @WpDtoField(new WpDtoFieldOptions('Delegated roles', true))\n roles!: string;\n\n /** Result */\n @WpDtoField(new WpDtoFieldOptions('Result', true))\n result!: string;\n\n constructor(user?: string, roles?: string, result?: string) {\n if (user !== undefined) this.user = user;\n if (roles !== undefined) this.roles = roles;\n if (result !== undefined) this.result = result;\n }\n}\n\n@ApiPath('/remote-mcp')\n@ApiType(SVC_TO_SVC, MCP)\nexport abstract class RemoteMcpApi {\n /** Calls a remote Webpieces API. */\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'remote_integration_search',\n description: 'Calls a remote Webpieces API.',\n openWorldHint: false,\n })\n search(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/missing-remote-mcp')\n@ApiType(SVC_TO_SVC, MCP)\nexport abstract class MissingRemoteMcpApi {\n /** Intentionally absent route. */\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'missing_remote_integration_search',\n description: 'Intentionally absent route.',\n openWorldHint: false,\n })\n search(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/refused-remote-mcp')\n@ApiType(SVC_TO_SVC, MCP)\nexport abstract class RefusedRemoteApi {\n /** Nothing listens on this port. */\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'refused_remote',\n description: 'Nothing listens on this port.',\n openWorldHint: false,\n })\n search(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/garbage-remote-mcp')\n@ApiType(SVC_TO_SVC, MCP)\nexport abstract class GarbageRemoteApi {\n /** Answers an undecodable body. */\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'garbage_remote',\n description: 'Answers an undecodable body.',\n openWorldHint: false,\n })\n search(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/oidc-fail-remote-mcp')\n@ApiType(SVC_TO_SVC, MCP)\nexport abstract class OidcFailRemoteApi {\n /** Its OIDC token cannot be minted. */\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'oidc_fail_remote',\n description: 'Its OIDC token cannot be minted.',\n openWorldHint: false,\n })\n search(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/local-throw')\n@ApiType(SVC_TO_SVC, MCP)\nexport abstract class LocalThrowApi {\n /** Throws the requested failure in-process. */\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthJwt({ allRolesAllowed: true })\n @Endpoint(POST, '/throw', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'local_throw',\n description: 'Throws the requested failure in-process.',\n openWorldHint: false,\n })\n fail(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/remote-throw')\n@ApiType(SVC_TO_SVC, MCP)\nexport abstract class RemoteThrowApi {\n /** Throws the requested failure remotely. */\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc('mcp-gateway')\n @Endpoint(POST, '/throw', READ, RPC)\n @WpResponseDto(() => RemoteResponse)\n @WpMcpTool({\n name: 'remote_throw',\n description: 'Throws the requested failure remotely.',\n openWorldHint: false,\n })\n fail(_request: RemoteRequest): Promise<RemoteResponse> {\n throw new Error('contract only');\n }\n}\n\n/**\n * One named throw, run identically behind the local and the remote binding.\n *\n * `expectedServerLevel` is the level of the ONE operator line the failure now produces on the server\n * that raised it — `LogApiCall`'s, at `warn` for `[API-server-resp-OTHER]` (a healthy rejection of\n * the caller's mistake) and `error` for `[API-server-resp-FAIL]`. `ApiErrorBoundary` no longer\n * writes a second line of its own (#961).\n */\nexport class ThrowCase {\n constructor(\n public readonly name: string,\n public readonly expectedKind: string,\n public readonly expectedServerLevel: LogLevel,\n public readonly raise: () => never,\n ) {}\n}\n\nexport const THROW_CASES: readonly ThrowCase[] = [\n new ThrowCase('end-user', 'end-user', 'warn', () => {\n throw new ApiEndUserError('The two passwords you entered do not match.', 'PW_MISMATCH');\n }),\n new ThrowCase('bad-request', 'bad-request', 'warn', () => {\n throw new ApiBadRequestError('internal column name', '$.query', 'query must be a word');\n }),\n new ThrowCase('unauthorized', 'unauthorized', 'warn', () => {\n throw new ApiUnauthorizedError('session internals');\n }),\n new ThrowCase('forbidden', 'forbidden', 'warn', () => {\n throw new ApiForbiddenError('acl internals');\n }),\n new ThrowCase('not-found', 'not-found', 'warn', () => {\n throw new ApiNotFoundError('row 7 missing');\n }),\n new ThrowCase('endpoint-not-found', 'endpoint-not-found', 'warn', () => {\n throw new ApiEndpointNotFoundError('route internals');\n }),\n new ThrowCase('request-timeout', 'request-timeout', 'error', () => {\n throw new ApiRequestTimeoutError('slow internals');\n }),\n new ThrowCase('rate-limited', 'rate-limited', 'error', () => {\n throw new ApiRateLimitedError('quota internals');\n }),\n new ThrowCase('conflict', 'conflict', 'warn', () => {\n throw new ApiConflictError('version internals');\n }),\n new ThrowCase('unprocessable', 'unprocessable', 'warn', () => {\n throw new ApiUnprocessableError('rule internals');\n }),\n new ThrowCase('precondition-failed', 'precondition-failed', 'warn', () => {\n throw new ApiPreconditionFailedError('etag internals');\n }),\n new ThrowCase('unsupported-media-type', 'unsupported-media-type', 'warn', () => {\n throw new ApiUnsupportedMediaTypeError('parser internals');\n }),\n new ThrowCase('not-implemented', 'not-implemented', 'error', () => {\n throw new ApiNotImplementedError('feature internals');\n }),\n new ThrowCase('coded-4xx', 'coded', 'warn', () => {\n throw new ApiCodedError('quota internals', 460, 'QUOTA');\n }),\n new ThrowCase('coded-5xx', 'coded', 'error', () => {\n throw new ApiCodedError('disk internals', 507);\n }),\n new ThrowCase('implementation', 'implementation', 'error', () => {\n throw new ApiImplementationError('bug internals');\n }),\n new ThrowCase('dependency', 'dependency', 'error', () => {\n throw new ApiDependencyError('upstream internals');\n }),\n new ThrowCase('unavailable', 'unavailable', 'error', () => {\n throw new ApiUnavailableError('maintenance internals');\n }),\n new ThrowCase('dependency-timeout', 'dependency-timeout', 'error', () => {\n throw new ApiDependencyTimeoutError('upstream slow internals');\n }),\n new ThrowCase('dependency-backoff', 'dependency-backoff', 'error', () => {\n throw new ApiDependencyBackoffError('backoff internals', 42);\n }),\n new ThrowCase('connection', 'implementation', 'error', () => {\n throw new ApiConnectionError('ECONNRESET internals');\n }),\n new ThrowCase('raw-error', 'implementation', 'error', () => {\n throw new Error('SECRET-raw-internals');\n }),\n new ThrowCase('thrown-string', 'implementation', 'error', () => {\n throw 'SECRET-string-internals';\n }),\n];\n\nexport function raiseFor(query: string): never {\n const found = THROW_CASES.find((candidate: ThrowCase) => candidate.name === query);\n if (!found) throw new Error(`unknown throw case ${query}`);\n return found.raise();\n}\n\n@injectable()\nexport class RemoteMcpController extends RemoteMcpApi {\n calls = 0;\n authorization?: string;\n\n override search(request: RemoteRequest): Promise<RemoteResponse> {\n this.calls += 1;\n this.authorization = RequestContext.getRequest()?.getHeader('authorization');\n return Promise.resolve(\n new RemoteResponse(\n RequestContext.getTrusted(REMOTE_USER) ?? 'missing-user',\n RequestContext.getTrusted(REMOTE_ROLES) ?? 'missing-roles',\n `remote:${request.query}`,\n ),\n );\n }\n}\n\n@injectable()\nexport class LocalThrowController extends LocalThrowApi {\n override async fail(request: RemoteRequest): Promise<RemoteResponse> {\n return raiseFor(request.query);\n }\n}\n\n@injectable()\nexport class RemoteThrowController extends RemoteThrowApi {\n override async fail(request: RemoteRequest): Promise<RemoteResponse> {\n return raiseFor(request.query);\n }\n}\n\nexport class RecordingOidcMinter {\n readonly audiences: string[] = [];\n\n constructor(\n private readonly failure?: Error,\n private readonly token = OIDC_TOKEN,\n ) {}\n\n mintIdToken(audience: string): Promise<string> {\n this.audiences.push(audience);\n if (this.failure) return Promise.reject(this.failure);\n return Promise.resolve(this.token);\n }\n}\n\nexport class RecordingOidcVerifier extends OidcHook {\n readonly tokens: string[] = [];\n readonly callerLists: string[][] = [];\n\n override verifyOidc(token: string, callers: string[]): Promise<void> {\n this.tokens.push(token);\n this.callerLists.push(callers);\n if (token !== OIDC_TOKEN) throw new Error(`unexpected OIDC token '${token}'`);\n return Promise.resolve();\n }\n}\n\n@injectable()\nexport class BoundaryProbeFilter extends Filter<MethodMeta, WpResponse<unknown>> {\n calls = 0;\n sawLogIdentity = false;\n sawTrustedUser?: string;\n\n override filter(\n meta: MethodMeta,\n next: Service<MethodMeta, WpResponse<unknown>>,\n ): Promise<WpResponse<unknown>> {\n this.calls += 1;\n this.sawLogIdentity =\n RequestContext.getUntrusted(WebpiecesCoreHeaders.CONTROLLER) ===\n 'RemoteMcpController' &&\n RequestContext.getUntrusted(WebpiecesCoreHeaders.METHOD) === 'search';\n this.sawTrustedUser = RequestContext.getTrusted(REMOTE_USER);\n return next.invoke(meta);\n }\n}\n\n/**\n * The documented gateway opt-out from http-client-node's \"a dependency's 4xx is OUR 500\" invariant:\n * an MCP gateway relays a Webpieces peer's typed failure so the model sees the same kind it would see\n * for a local binding. `relay = false` answers \"not mine\", which is the framework default.\n */\nexport class RelayWebpiecesPeerErrors implements ErrorTranslator {\n relay = true;\n\n private readonly fallback = new WebpiecesDefaultErrorTranslator();\n\n toWire(error: Error): HttpResponseDto {\n return this.fallback.toWire(error);\n }\n\n fromWire(response: HttpResponseDto): void {\n if (this.relay && ApiErrorCodec.isPayload(response.body)) {\n const decoded = ApiErrorCodec.decode(response.body);\n const statusCode = decoded instanceof ApiCodedError ? decoded.statusCode : undefined;\n if (\n ApiErrorHttpStatus.hasCode(decoded) &&\n ApiErrorHttpStatus.codeFor(decoded.kind, statusCode) === response.status.code\n ) {\n throw decoded;\n }\n }\n this.fallback.fromWire(response);\n }\n}\n"]}
|
|
@@ -12,17 +12,26 @@ export declare const OLDER_LEGACY_VERSION = "2025-03-26";
|
|
|
12
12
|
/** A revision NO era knows: the one case a server is still right to refuse. */
|
|
13
13
|
export declare const UNKNOWN_VERSION = "1999-01-01";
|
|
14
14
|
export declare class SearchRequest {
|
|
15
|
+
/**
|
|
16
|
+
* Search text
|
|
17
|
+
* @mcpHeader query
|
|
18
|
+
*/
|
|
15
19
|
query: string;
|
|
16
20
|
}
|
|
17
21
|
export declare class SearchResponse {
|
|
22
|
+
/** Authenticated user */
|
|
18
23
|
userId: string;
|
|
24
|
+
/** Search result */
|
|
19
25
|
result: string;
|
|
20
26
|
}
|
|
21
27
|
export declare abstract class SearchApi {
|
|
28
|
+
/** Search records owned by the authenticated user. */
|
|
22
29
|
search(_request: SearchRequest): Promise<SearchResponse>;
|
|
30
|
+
/** Administrative search. */
|
|
23
31
|
admin(_request: SearchRequest): Promise<SearchResponse>;
|
|
24
32
|
}
|
|
25
33
|
export declare abstract class RemoteSearchApi {
|
|
34
|
+
/** Search a remote binding. */
|
|
26
35
|
search(_request: SearchRequest): Promise<SearchResponse>;
|
|
27
36
|
}
|
|
28
37
|
export declare class SearchController extends SearchApi {
|
|
@@ -20,6 +20,10 @@ exports.OLDER_LEGACY_VERSION = '2025-03-26';
|
|
|
20
20
|
/** A revision NO era knows: the one case a server is still right to refuse. */
|
|
21
21
|
exports.UNKNOWN_VERSION = '1999-01-01';
|
|
22
22
|
let SearchRequest = class SearchRequest {
|
|
23
|
+
/**
|
|
24
|
+
* Search text
|
|
25
|
+
* @mcpHeader query
|
|
26
|
+
*/
|
|
23
27
|
query;
|
|
24
28
|
};
|
|
25
29
|
exports.SearchRequest = SearchRequest;
|
|
@@ -31,7 +35,9 @@ exports.SearchRequest = SearchRequest = tslib_1.__decorate([
|
|
|
31
35
|
(0, core_util_1.WpDto)()
|
|
32
36
|
], SearchRequest);
|
|
33
37
|
let SearchResponse = class SearchResponse {
|
|
38
|
+
/** Authenticated user */
|
|
34
39
|
userId;
|
|
40
|
+
/** Search result */
|
|
35
41
|
result;
|
|
36
42
|
};
|
|
37
43
|
exports.SearchResponse = SearchResponse;
|
|
@@ -47,9 +53,11 @@ exports.SearchResponse = SearchResponse = tslib_1.__decorate([
|
|
|
47
53
|
(0, core_util_1.WpDto)()
|
|
48
54
|
], SearchResponse);
|
|
49
55
|
let SearchApi = class SearchApi {
|
|
56
|
+
/** Search records owned by the authenticated user. */
|
|
50
57
|
search(_request) {
|
|
51
58
|
throw new Error('contract only');
|
|
52
59
|
}
|
|
60
|
+
/** Administrative search. */
|
|
53
61
|
admin(_request) {
|
|
54
62
|
throw new Error('contract only');
|
|
55
63
|
}
|
|
@@ -84,9 +92,11 @@ tslib_1.__decorate([
|
|
|
84
92
|
tslib_1.__metadata("design:returntype", Promise)
|
|
85
93
|
], SearchApi.prototype, "admin", null);
|
|
86
94
|
exports.SearchApi = SearchApi = tslib_1.__decorate([
|
|
87
|
-
(0, core_util_1.ApiPath)('/mcp-spec')
|
|
95
|
+
(0, core_util_1.ApiPath)('/mcp-spec'),
|
|
96
|
+
(0, core_util_1.ApiType)(core_util_1.SVC_TO_SVC, core_util_1.MCP)
|
|
88
97
|
], SearchApi);
|
|
89
98
|
let RemoteSearchApi = class RemoteSearchApi {
|
|
99
|
+
/** Search a remote binding. */
|
|
90
100
|
search(_request) {
|
|
91
101
|
throw new Error('contract only');
|
|
92
102
|
}
|
|
@@ -107,7 +117,8 @@ tslib_1.__decorate([
|
|
|
107
117
|
tslib_1.__metadata("design:returntype", Promise)
|
|
108
118
|
], RemoteSearchApi.prototype, "search", null);
|
|
109
119
|
exports.RemoteSearchApi = RemoteSearchApi = tslib_1.__decorate([
|
|
110
|
-
(0, core_util_1.ApiPath)('/remote-spec')
|
|
120
|
+
(0, core_util_1.ApiPath)('/remote-spec'),
|
|
121
|
+
(0, core_util_1.ApiType)(core_util_1.SVC_TO_SVC, core_util_1.MCP)
|
|
111
122
|
], RemoteSearchApi);
|
|
112
123
|
let SearchController = class SearchController extends SearchApi {
|
|
113
124
|
static { SearchController_1 = this; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WpMcpServerTestFixtures.js","sourceRoot":"","sources":["../../../../../../packages/http/mcp-server/src/__tests__/WpMcpServerTestFixtures.ts"],"names":[],"mappings":";;;;;AAAA,4BAA0B;AAC1B,yCAAuC;AACvC,oDA8B8B;AAC9B,0DAAyD;AACzD,0DAAkF;AAClF,wCAA4E;AAC5E,kEAAiE;AAEpD,QAAA,OAAO,GAAG,sBAAU,CAAC,OAAO,CACrC,eAAe,EACf,iCAAiC,CACpC,CAAC;AACW,QAAA,aAAa,GAAG,gBAAgB,CAAC;AACjC,QAAA,cAAc,GAAG,YAAY,CAAC;AAC3C,+FAA+F;AAClF,QAAA,cAAc,GAAG,YAAY,CAAC;AAC3C,sEAAsE;AACzD,QAAA,oBAAoB,GAAG,YAAY,CAAC;AACjD,+EAA+E;AAClE,QAAA,eAAe,GAAG,YAAY,CAAC;AAGrC,IAAM,aAAa,GAAnB,MAAM,aAAa;IAatB,KAAK,CAAU;CAClB,CAAA;AAdY,sCAAa;AAatB;IAZC,IAAA,sBAAU,EACP,IAAI,6BAAiB,CACjB,aAAa,EACb,IAAI,EACJ,SAAS,EACT,KAAK,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,IAAI,uBAAW,CAAC,OAAO,CAAC,CAC3B,CACJ;;4CACc;wBAbN,aAAa;IADzB,IAAA,iBAAK,GAAE;GACK,aAAa,CAczB;AAGM,IAAM,cAAc,GAApB,MAAM,cAAc;IAEvB,MAAM,CAAU;IAGhB,MAAM,CAAU;CACnB,CAAA;AANY,wCAAc;AAEvB;IADC,IAAA,sBAAU,EAAC,IAAI,6BAAiB,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;;8CAC9C;AAGhB;IADC,IAAA,sBAAU,EAAC,IAAI,6BAAiB,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;;8CACzC;yBALP,cAAc;IAD1B,IAAA,iBAAK,GAAE;GACK,cAAc,CAM1B;AAGM,IAAe,SAAS,GAAxB,MAAe,SAAS;IAU3B,MAAM,CAAC,QAAuB;QAC1B,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;IAWD,KAAK,CAAC,QAAuB;QACzB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;CACJ,CAAA;AA1BqB,8BAAS;AAU3B;IATC,IAAA,wBAAY,EAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IACvC,IAAA,qBAAS,EAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IACpC,IAAA,oBAAQ,EAAC,gBAAI,EAAE,SAAS,EAAE,gBAAI,EAAE,eAAG,CAAC;IACpC,IAAA,yBAAa,EAAC,GAAG,EAAE,CAAC,cAAc,CAAC;IACnC,IAAA,qBAAS,EAAC;QACP,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,iDAAiD;QAC9D,aAAa,EAAE,KAAK;KACvB,CAAC;;6CACe,aAAa;;uCAE7B;AAWD;IATC,IAAA,wBAAY,EAAC,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAClC,IAAA,qBAAS,EAAC,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/B,IAAA,oBAAQ,EAAC,gBAAI,EAAE,QAAQ,EAAE,iBAAK,EAAE,eAAG,CAAC;IACpC,IAAA,yBAAa,EAAC,GAAG,EAAE,CAAC,cAAc,CAAC;IACnC,IAAA,qBAAS,EAAC;QACP,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,wBAAwB;QACrC,aAAa,EAAE,KAAK;KACvB,CAAC;;6CACc,aAAa;;sCAE5B;oBAzBiB,SAAS;IAD9B,IAAA,mBAAO,EAAC,WAAW,CAAC;GACC,SAAS,CA0B9B;AAGM,IAAe,eAAe,GAA9B,MAAe,eAAe;IAUjC,MAAM,CAAC,QAAuB;QAC1B,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;CACJ,CAAA;AAbqB,0CAAe;AAUjC;IATC,IAAA,wBAAY,EAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IACvC,IAAA,sBAAU,GAAE;IACZ,IAAA,oBAAQ,EAAC,gBAAI,EAAE,SAAS,EAAE,iBAAK,EAAE,eAAG,CAAC;IACrC,IAAA,yBAAa,EAAC,GAAG,EAAE,CAAC,cAAc,CAAC;IACnC,IAAA,qBAAS,EAAC;QACP,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,0BAA0B;QACvC,aAAa,EAAE,KAAK;KACvB,CAAC;;6CACe,aAAa;;6CAE7B;0BAZiB,eAAe;IADpC,IAAA,mBAAO,EAAC,cAAc,CAAC;GACF,eAAe,CAapC;AAGM,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,SAAS;;IAC3C,MAAM,CAAC,eAAe,CAAc;IACpC,MAAM,CAAC,eAAe,CAAc;IACpC,gBAAgB,GAAG,CAAC,CAAC;IAEZ,KAAK,CAAC,MAAM,CAAC,OAAsB;QACxC,IAAI,OAAO,CAAC,KAAK,KAAK,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrF,2FAA2F;QAC3F,8DAA8D;QAC9D,IAAI,OAAO,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;YACjC,MAAM,IAAI,8BAAkB,CAAC,gCAAgC,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,KAAK,OAAO;YAAE,MAAM,IAAI,2BAAe,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACvF,IAAI,OAAO,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAChC,MAAM,IAAI,8BAAkB,CACxB,yCAAyC,EACzC,SAAS,EACT,oBAAoB,CACvB,CAAC;QACN,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,KAAK,YAAY;YAAE,MAAM,IAAI,8BAAkB,CAAC,kBAAkB,CAAC,CAAC;QACrF,IAAI,OAAO,CAAC,KAAK,KAAK,aAAa;YAAE,MAAM,IAAI,8BAAkB,CAAC,eAAe,CAAC,CAAC;QACnF,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,qCAAyB,CAAC,iBAAiB,CAAC,CAAC;QACxF,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,IAAI,qCAAyB,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,KAAK,aAAa;YAAE,MAAM,IAAI,+BAAmB,CAAC,oBAAoB,CAAC,CAAC;QACzF,MAAM,UAAU,GAAG,6BAAc,CAAC,UAAU,CAAC,6CAAsB,CAAC,CAAC;QACrE,IAAI,OAAO,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YAC/B,MAAM,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,IAAI,UAAU,EAAE,CAAC;YACzC,MAAM,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;YACnD,kBAAgB,CAAC,eAAe,EAAE,EAAE,CAAC;YACrC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAmB,EAAE,EAAE;gBAC5C,MAAM,MAAM,GAAG,GAAS,EAAE;oBACtB,kBAAgB,CAAC,eAAe,EAAE,EAAE,CAAC;oBACrC,OAAO,EAAE,CAAC;gBACd,CAAC,CAAC;gBACF,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO;oBAAE,MAAM,EAAE,CAAC;;oBACnC,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7E,CAAC,CAAC,CAAC;QACP,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,6BAAc,CAAC,UAAU,CAAC,eAAO,CAAC,IAAI,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;IAC9F,CAAC;IAEQ,KAAK,CAAC,KAAK,CAAC,OAAsB;QACvC,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;CACJ,CAAA;AAlDY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,sBAAU,GAAE;GACA,gBAAgB,CAkD5B;AAED,MAAa,kBAAmB,SAAQ,eAAe;IACnD,iBAAiB,CAAU;IAElB,KAAK,CAAC,MAAM,CAAC,OAAsB;QACxC,IAAI,CAAC,iBAAiB,GAAG,6BAAc,CAAC,UAAU,EAAE,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;QACjF,OAAO,EAAE,MAAM,EAAE,6BAAc,CAAC,UAAU,CAAC,eAAO,CAAC,IAAI,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;IAC9F,CAAC;CACJ;AAPD,gDAOC;AAED,MAAa,WAAY,SAAQ,sBAAe;IAC5C,YAAY,GAAa,EAAE,CAAC;IAC5B,eAAe,GAAG,EAAE,CAAC;IACrB,QAAQ,CAAS;IAER,KAAK,CAAC,IAAI,CAAC,OAAe;QAC/B,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,CAAC,QAAQ,CAAC;QACvC,MAAM,KAAK,GACP,OAAO,KAAK,aAAa;YACrB,CAAC,CAAC,iBAAiB;YACnB,CAAC,CAAC,GAAG,OAAO,aAAa,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,OAAO,IAAI,wBAAS,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;IACtF,CAAC;IAEQ,KAAK,CAAC,QAAQ,CAAC,KAAa;QACjC,IAAI,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACtC,OAAO,IAAI,kCAAmB,CAC1B,SAAS,EACT,CAAC,OAAO,CAAC,EACT,CAAC,IAAI,wBAAY,CAAC,eAAO,EAAE,SAAS,CAAC,CAAC,CACzC,CAAC;QACN,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACnF,OAAO,IAAI,kCAAmB,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,IAAI,wBAAY,CAAC,eAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxF,CAAC;CACJ;AA1BD,kCA0BC;AAED,MAAa,kBAAkB;IAC3B,iBAAiB,GAAG,CAAC,CAAC;IACtB,KAAK,GAAsB,EAAE,CAAC;IAE9B,KAAK,CAAC,eAAe,CAAC,MAAc;QAChC,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,KAAa,EAAE,QAAgB;QACnD,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,gCAAoB,CAAC,eAAe,CAAC,CAAC;QACzE,IAAI,KAAK,KAAK,eAAe;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACzE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,MAAM,cAAc,GAChB,KAAK,KAAK,gBAAgB,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC3E,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC;YACzC,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,KAAK,KAAK,iBAAiB;gBAC3B,CAAC,CAAC,aAAa;gBACf,CAAC,CAAC,MAAM,CAAC;QACf,MAAM,MAAM,GACR,KAAK,KAAK,cAAc,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,4BAA4B,CAAC;QACzF,MAAM,SAAS,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC;QAC3D,MAAM,MAAM,GAAG,KAAK,KAAK,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,WAAW,GAAG,KAAK,KAAK,eAAe,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;QAClE,MAAM,UAAU,GAAG,IAAI,+BAAqB,CACxC,OAAO,EACP,MAAM,EACN,cAAc,EACd,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EACpC,SAAS,EACT,MAAM,EACN,WAAW,EACX,IAAI,CAAC,KAAK,EACV,CAAC,IAAI,wBAAY,CAAC,eAAO,EAAE,GAAG,OAAO,YAAY,CAAC,CAAC,CACtD,CAAC;QACF,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;YACvB,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,cAAc,EAAE;gBAC9C,GAAG,EAAE,GAAsB,EAAE;oBACzB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;gBAC9C,CAAC;aACJ,CAAC,CAAC;QACP,CAAC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ;AA7CD,gDA6CC;AAED,MAAa,eAAe;IAEJ;IACA;IACA;IACA;IAJpB,YACoB,MAAc,EACd,KAAe,EACf,OAAe,EACf,KAAa;QAHb,WAAM,GAAN,MAAM,CAAQ;QACd,UAAK,GAAL,KAAK,CAAU;QACf,YAAO,GAAP,OAAO,CAAQ;QACf,UAAK,GAAL,KAAK,CAAQ;IAC9B,CAAC;IAEJ,gGAAgG;IAChG,QAAQ;QACJ,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC;IACrF,CAAC;CACJ;AAZD,0CAYC;AAED,MAAM,eAAe;IAEI;IACA;IAFrB,YACqB,IAAY,EACZ,KAAwB;QADxB,SAAI,GAAJ,IAAI,CAAQ;QACZ,UAAK,GAAL,KAAK,CAAmB;IAC1C,CAAC;IAEJ,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAW;QAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAW;QAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3E,CAAC;CACJ;AAED,6FAA6F;AAC7F,MAAa,sBAAsB;IACtB,KAAK,GAAsB,EAAE,CAAC;IAEvC,SAAS,CAAC,IAAY;QAClB,OAAO,IAAI,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,UAAU,CAAC,IAAY;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAqB,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACxF,CAAC;CACJ;AAVD,wDAUC","sourcesContent":["import 'reflect-metadata';\nimport { injectable } from 'inversify';\nimport {\n ApiBadRequestError,\n ApiBadGatewayError,\n ApiConnectionError,\n ApiDependencyBackoffError,\n ApiDependencyError,\n ApiDependencyTimeoutError,\n ApiEndUserError,\n ApiPath,\n ApiUnauthorizedError,\n ApiUnavailableError,\n Logger,\n LoggerFactory,\n LogLevel,\n ContextKey,\n ContextTuple,\n Endpoint,\n WpAuthJwt,\n WpAuthOidc,\n WpDto,\n WpDtoField,\n WpDtoFieldOptions,\n WpMcpAuthJwt,\n WpMcpHeader,\n WpMcpTool,\n WpResponseDto,\n POST,\n READ,\n RPC,\n WRITE,\n} from '@webpieces/core-util';\nimport { RequestContext } from '@webpieces/core-context';\nimport { AuthenticatedCaller, JwtHook, MintedJwt } from '@webpieces/http-routing';\nimport { McpAccessTokenAuthority, VerifiedMcpCredential } from '../McpAuth';\nimport { MCP_INVOCATION_CONTEXT } from '../McpInvocationContext';\n\nexport const USER_ID = ContextKey.trusted<string>(\n 'mcpSpecUserId',\n 'proven by a credential verifier',\n);\nexport const ENDPOINT_PATH = '/app-owned/mcp';\nexport const MODERN_VERSION = '2026-07-28';\n/** What every shipping MCP client opens with today — the top of the 2025 negotiation table. */\nexport const LEGACY_VERSION = '2025-11-25';\n/** An older 2025-era revision the negotiation table still carries. */\nexport const OLDER_LEGACY_VERSION = '2025-03-26';\n/** A revision NO era knows: the one case a server is still right to refuse. */\nexport const UNKNOWN_VERSION = '1999-01-01';\n\n@WpDto()\nexport class SearchRequest {\n @WpDtoField(\n new WpDtoFieldOptions(\n 'Search text',\n true,\n undefined,\n false,\n undefined,\n undefined,\n undefined,\n new WpMcpHeader('query'),\n ),\n )\n query!: string;\n}\n\n@WpDto()\nexport class SearchResponse {\n @WpDtoField(new WpDtoFieldOptions('Authenticated user', true))\n userId!: string;\n\n @WpDtoField(new WpDtoFieldOptions('Search result', true))\n result!: string;\n}\n\n@ApiPath('/mcp-spec')\nexport abstract class SearchApi {\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthJwt({ allRolesAllowed: true })\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => SearchResponse)\n @WpMcpTool({\n name: 'account_search',\n description: 'Search records owned by the authenticated user.',\n openWorldHint: false,\n })\n search(_request: SearchRequest): Promise<SearchResponse> {\n throw new Error('contract only');\n }\n\n @WpMcpAuthJwt({ roles: ['admin'] })\n @WpAuthJwt({ roles: ['admin'] })\n @Endpoint(POST, '/admin', WRITE, RPC)\n @WpResponseDto(() => SearchResponse)\n @WpMcpTool({\n name: 'admin_search',\n description: 'Administrative search.',\n openWorldHint: false,\n })\n admin(_request: SearchRequest): Promise<SearchResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/remote-spec')\nexport abstract class RemoteSearchApi {\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc()\n @Endpoint(POST, '/search', WRITE, RPC)\n @WpResponseDto(() => SearchResponse)\n @WpMcpTool({\n name: 'remote_search',\n description: 'Search a remote binding.',\n openWorldHint: false,\n })\n search(_request: SearchRequest): Promise<SearchResponse> {\n throw new Error('contract only');\n }\n}\n\n@injectable()\nexport class SearchController extends SearchApi {\n static waitStartedHook?: () => void;\n static waitAbortedHook?: () => void;\n adminInvocations = 0;\n\n override async search(request: SearchRequest): Promise<SearchResponse> {\n if (request.query === 'internal') throw new Error('database password appeared here');\n // A DOWNSTREAM call of ours failed. From the model's seat that is OUR bug, never a kind of\n // its own on the wire — see #959 and ApiErrorBoundary.encode.\n if (request.query === 'downstream') {\n throw new ApiConnectionError('ECONNREFUSED private-host:8443');\n }\n if (request.query === 'human') throw new ApiEndUserError('Safe human message', 'SAFE');\n if (request.query === 'malformed') {\n throw new ApiBadRequestError(\n 'operator-only: column tenant_7 rejected',\n '$.query',\n 'query is malformed',\n );\n }\n if (request.query === 'dependency') throw new ApiDependencyError('private upstream');\n if (request.query === 'bad-gateway') throw new ApiBadGatewayError('private proxy');\n if (request.query === 'timeout') throw new ApiDependencyTimeoutError('private timeout');\n if (request.query === 'backoff') {\n throw new ApiDependencyBackoffError('private throttling detail', 37);\n }\n if (request.query === 'unavailable') throw new ApiUnavailableError('private deployment');\n const invocation = RequestContext.getTrusted(MCP_INVOCATION_CONTEXT);\n if (request.query === 'progress') {\n await invocation?.reportProgress?.(1, 2, 'halfway');\n }\n if (request.query === 'wait' && invocation) {\n await invocation.reportProgress?.(0, 1, 'waiting');\n SearchController.waitStartedHook?.();\n await new Promise<void>((resolve: () => void) => {\n const finish = (): void => {\n SearchController.waitAbortedHook?.();\n resolve();\n };\n if (invocation.signal.aborted) finish();\n else invocation.signal.addEventListener('abort', finish, { once: true });\n });\n }\n return { userId: RequestContext.getTrusted(USER_ID) ?? 'missing', result: request.query };\n }\n\n override async admin(request: SearchRequest): Promise<SearchResponse> {\n this.adminInvocations += 1;\n return this.search(request);\n }\n}\n\nexport class RemoteSearchClient extends RemoteSearchApi {\n seenAuthorization?: string;\n\n override async search(request: SearchRequest): Promise<SearchResponse> {\n this.seenAuthorization = RequestContext.getRequest()?.getHeader('authorization');\n return { userId: RequestContext.getTrusted(USER_ID) ?? 'missing', result: request.query };\n }\n}\n\nexport class TestJwtHook extends JwtHook<string> {\n mintedTokens: string[] = [];\n lifetimeSeconds = 60;\n failWith?: Error;\n\n override async mint(subject: string): Promise<MintedJwt> {\n if (this.failWith) throw this.failWith;\n const token =\n subject === 'passthrough'\n ? 'mcp-passthrough'\n : `${subject}-endpoint-${this.mintedTokens.length + 1}`;\n this.mintedTokens.push(token);\n return new MintedJwt(token, Math.floor(Date.now() / 1000) + this.lifetimeSeconds);\n }\n\n override async parseJwt(token: string): Promise<AuthenticatedCaller> {\n if (token.startsWith('admin-endpoint-')) {\n return new AuthenticatedCaller(\n 'admin-7',\n ['admin'],\n [new ContextTuple(USER_ID, 'admin-7')],\n );\n }\n if (!token.startsWith('user-endpoint-')) throw new Error('invalid endpoint token');\n return new AuthenticatedCaller('user-7', [], [new ContextTuple(USER_ID, 'user-7')]);\n }\n}\n\nexport class TestTokenAuthority implements McpAccessTokenAuthority<string> {\n verificationCount = 0;\n roles: readonly string[] = [];\n\n async mintAccessToken(_grant: string): Promise<never> {\n throw new Error('not used');\n }\n\n async verifyAccessToken(token: string, resource: string): Promise<VerifiedMcpCredential> {\n this.verificationCount += 1;\n if (token === 'invalid') throw new ApiUnauthorizedError('invalid token');\n if (token === 'authority-bug') throw new Error('SECRET-internal-detail');\n const now = Math.floor(Date.now() / 1000);\n const actualResource =\n token === 'wrong-resource' ? 'https://attacker.example/mcp' : resource;\n const subject = token.startsWith('mcp-admin')\n ? 'admin'\n : token === 'mcp-passthrough'\n ? 'passthrough'\n : 'user';\n const issuer =\n token === 'wrong-issuer' ? 'https://attacker.example' : 'https://login.example.test';\n const expiresAt = token === 'expired' ? now - 1 : now + 60;\n const scopes = token === 'missing-scope' ? [] : ['tools'];\n const validatedAt = token === 'stale-account' ? now - 3_601 : now;\n const credential = new VerifiedMcpCredential(\n subject,\n issuer,\n actualResource,\n token === 'expired' ? now - 61 : now,\n expiresAt,\n scopes,\n validatedAt,\n this.roles,\n [new ContextTuple(USER_ID, `${subject}-delegated`)],\n );\n if (token === 'list-bug') {\n Object.defineProperty(credential, 'listingRoles', {\n get: (): readonly string[] => {\n throw new Error('SECRET-internal-detail');\n },\n });\n }\n return credential;\n }\n}\n\nexport class RecordedLogLine {\n constructor(\n public readonly logger: string,\n public readonly level: LogLevel,\n public readonly message: string,\n public readonly error?: Error,\n ) {}\n\n /** The rendered line an operator would see, including an attached error's message and stack. */\n rendered(): string {\n return `${this.message} ${this.error?.message ?? ''} ${this.error?.stack ?? ''}`;\n }\n}\n\nclass RecordingLogger implements Logger {\n constructor(\n private readonly name: string,\n private readonly lines: RecordedLogLine[],\n ) {}\n\n trace(message: string, err?: Error): void {\n this.lines.push(new RecordedLogLine(this.name, 'trace', message, err));\n }\n\n debug(message: string, err?: Error): void {\n this.lines.push(new RecordedLogLine(this.name, 'debug', message, err));\n }\n\n info(message: string, err?: Error): void {\n this.lines.push(new RecordedLogLine(this.name, 'info', message, err));\n }\n\n warn(message: string, err?: Error): void {\n this.lines.push(new RecordedLogLine(this.name, 'warn', message, err));\n }\n\n error(message: string, err?: Error): void {\n this.lines.push(new RecordedLogLine(this.name, 'error', message, err));\n }\n}\n\n/** Captures every log line in-process so tests can count and level-check operator output. */\nexport class RecordingLoggerFactory implements LoggerFactory {\n readonly lines: RecordedLogLine[] = [];\n\n getLogger(name: string): Logger {\n return new RecordingLogger(name, this.lines);\n }\n\n containing(text: string): RecordedLogLine[] {\n return this.lines.filter((line: RecordedLogLine) => line.rendered().includes(text));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"WpMcpServerTestFixtures.js","sourceRoot":"","sources":["../../../../../../packages/http/mcp-server/src/__tests__/WpMcpServerTestFixtures.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { injectable } from 'inversify';\nimport {\n ApiBadRequestError,\n ApiBadGatewayError,\n ApiConnectionError,\n ApiDependencyBackoffError,\n ApiDependencyError,\n ApiDependencyTimeoutError,\n ApiEndUserError,\n ApiPath,\n ApiType,\n ApiUnauthorizedError,\n ApiUnavailableError,\n Logger,\n LoggerFactory,\n LogLevel,\n ContextKey,\n ContextTuple,\n Endpoint,\n WpAuthJwt,\n WpAuthOidc,\n WpDto,\n WpDtoField,\n WpDtoFieldOptions,\n WpMcpAuthJwt,\n WpMcpHeader,\n WpMcpTool,\n WpResponseDto,\n MCP,\n POST,\n READ,\n RPC,\n SVC_TO_SVC,\n WRITE,\n} from '@webpieces/core-util';\nimport { RequestContext } from '@webpieces/core-context';\nimport { AuthenticatedCaller, JwtHook, MintedJwt } from '@webpieces/http-routing';\nimport { McpAccessTokenAuthority, VerifiedMcpCredential } from '../McpAuth';\nimport { MCP_INVOCATION_CONTEXT } from '../McpInvocationContext';\n\nexport const USER_ID = ContextKey.trusted<string>(\n 'mcpSpecUserId',\n 'proven by a credential verifier',\n);\nexport const ENDPOINT_PATH = '/app-owned/mcp';\nexport const MODERN_VERSION = '2026-07-28';\n/** What every shipping MCP client opens with today — the top of the 2025 negotiation table. */\nexport const LEGACY_VERSION = '2025-11-25';\n/** An older 2025-era revision the negotiation table still carries. */\nexport const OLDER_LEGACY_VERSION = '2025-03-26';\n/** A revision NO era knows: the one case a server is still right to refuse. */\nexport const UNKNOWN_VERSION = '1999-01-01';\n\n@WpDto()\nexport class SearchRequest {\n /**\n * Search text\n * @mcpHeader query\n */\n @WpDtoField(\n new WpDtoFieldOptions(\n 'Search text',\n true,\n undefined,\n false,\n undefined,\n undefined,\n undefined,\n new WpMcpHeader('query'),\n ),\n )\n query!: string;\n}\n\n@WpDto()\nexport class SearchResponse {\n /** Authenticated user */\n @WpDtoField(new WpDtoFieldOptions('Authenticated user', true))\n userId!: string;\n\n /** Search result */\n @WpDtoField(new WpDtoFieldOptions('Search result', true))\n result!: string;\n}\n\n@ApiPath('/mcp-spec')\n@ApiType(SVC_TO_SVC, MCP)\nexport abstract class SearchApi {\n /** Search records owned by the authenticated user. */\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthJwt({ allRolesAllowed: true })\n @Endpoint(POST, '/search', READ, RPC)\n @WpResponseDto(() => SearchResponse)\n @WpMcpTool({\n name: 'account_search',\n description: 'Search records owned by the authenticated user.',\n openWorldHint: false,\n })\n search(_request: SearchRequest): Promise<SearchResponse> {\n throw new Error('contract only');\n }\n\n /** Administrative search. */\n @WpMcpAuthJwt({ roles: ['admin'] })\n @WpAuthJwt({ roles: ['admin'] })\n @Endpoint(POST, '/admin', WRITE, RPC)\n @WpResponseDto(() => SearchResponse)\n @WpMcpTool({\n name: 'admin_search',\n description: 'Administrative search.',\n openWorldHint: false,\n })\n admin(_request: SearchRequest): Promise<SearchResponse> {\n throw new Error('contract only');\n }\n}\n\n@ApiPath('/remote-spec')\n@ApiType(SVC_TO_SVC, MCP)\nexport abstract class RemoteSearchApi {\n /** Search a remote binding. */\n @WpMcpAuthJwt({ allRolesAllowed: true })\n @WpAuthOidc()\n @Endpoint(POST, '/search', WRITE, RPC)\n @WpResponseDto(() => SearchResponse)\n @WpMcpTool({\n name: 'remote_search',\n description: 'Search a remote binding.',\n openWorldHint: false,\n })\n search(_request: SearchRequest): Promise<SearchResponse> {\n throw new Error('contract only');\n }\n}\n\n@injectable()\nexport class SearchController extends SearchApi {\n static waitStartedHook?: () => void;\n static waitAbortedHook?: () => void;\n adminInvocations = 0;\n\n override async search(request: SearchRequest): Promise<SearchResponse> {\n if (request.query === 'internal') throw new Error('database password appeared here');\n // A DOWNSTREAM call of ours failed. From the model's seat that is OUR bug, never a kind of\n // its own on the wire — see #959 and ApiErrorBoundary.encode.\n if (request.query === 'downstream') {\n throw new ApiConnectionError('ECONNREFUSED private-host:8443');\n }\n if (request.query === 'human') throw new ApiEndUserError('Safe human message', 'SAFE');\n if (request.query === 'malformed') {\n throw new ApiBadRequestError(\n 'operator-only: column tenant_7 rejected',\n '$.query',\n 'query is malformed',\n );\n }\n if (request.query === 'dependency') throw new ApiDependencyError('private upstream');\n if (request.query === 'bad-gateway') throw new ApiBadGatewayError('private proxy');\n if (request.query === 'timeout') throw new ApiDependencyTimeoutError('private timeout');\n if (request.query === 'backoff') {\n throw new ApiDependencyBackoffError('private throttling detail', 37);\n }\n if (request.query === 'unavailable') throw new ApiUnavailableError('private deployment');\n const invocation = RequestContext.getTrusted(MCP_INVOCATION_CONTEXT);\n if (request.query === 'progress') {\n await invocation?.reportProgress?.(1, 2, 'halfway');\n }\n if (request.query === 'wait' && invocation) {\n await invocation.reportProgress?.(0, 1, 'waiting');\n SearchController.waitStartedHook?.();\n await new Promise<void>((resolve: () => void) => {\n const finish = (): void => {\n SearchController.waitAbortedHook?.();\n resolve();\n };\n if (invocation.signal.aborted) finish();\n else invocation.signal.addEventListener('abort', finish, { once: true });\n });\n }\n return { userId: RequestContext.getTrusted(USER_ID) ?? 'missing', result: request.query };\n }\n\n override async admin(request: SearchRequest): Promise<SearchResponse> {\n this.adminInvocations += 1;\n return this.search(request);\n }\n}\n\nexport class RemoteSearchClient extends RemoteSearchApi {\n seenAuthorization?: string;\n\n override async search(request: SearchRequest): Promise<SearchResponse> {\n this.seenAuthorization = RequestContext.getRequest()?.getHeader('authorization');\n return { userId: RequestContext.getTrusted(USER_ID) ?? 'missing', result: request.query };\n }\n}\n\nexport class TestJwtHook extends JwtHook<string> {\n mintedTokens: string[] = [];\n lifetimeSeconds = 60;\n failWith?: Error;\n\n override async mint(subject: string): Promise<MintedJwt> {\n if (this.failWith) throw this.failWith;\n const token =\n subject === 'passthrough'\n ? 'mcp-passthrough'\n : `${subject}-endpoint-${this.mintedTokens.length + 1}`;\n this.mintedTokens.push(token);\n return new MintedJwt(token, Math.floor(Date.now() / 1000) + this.lifetimeSeconds);\n }\n\n override async parseJwt(token: string): Promise<AuthenticatedCaller> {\n if (token.startsWith('admin-endpoint-')) {\n return new AuthenticatedCaller(\n 'admin-7',\n ['admin'],\n [new ContextTuple(USER_ID, 'admin-7')],\n );\n }\n if (!token.startsWith('user-endpoint-')) throw new Error('invalid endpoint token');\n return new AuthenticatedCaller('user-7', [], [new ContextTuple(USER_ID, 'user-7')]);\n }\n}\n\nexport class TestTokenAuthority implements McpAccessTokenAuthority<string> {\n verificationCount = 0;\n roles: readonly string[] = [];\n\n async mintAccessToken(_grant: string): Promise<never> {\n throw new Error('not used');\n }\n\n async verifyAccessToken(token: string, resource: string): Promise<VerifiedMcpCredential> {\n this.verificationCount += 1;\n if (token === 'invalid') throw new ApiUnauthorizedError('invalid token');\n if (token === 'authority-bug') throw new Error('SECRET-internal-detail');\n const now = Math.floor(Date.now() / 1000);\n const actualResource =\n token === 'wrong-resource' ? 'https://attacker.example/mcp' : resource;\n const subject = token.startsWith('mcp-admin')\n ? 'admin'\n : token === 'mcp-passthrough'\n ? 'passthrough'\n : 'user';\n const issuer =\n token === 'wrong-issuer' ? 'https://attacker.example' : 'https://login.example.test';\n const expiresAt = token === 'expired' ? now - 1 : now + 60;\n const scopes = token === 'missing-scope' ? [] : ['tools'];\n const validatedAt = token === 'stale-account' ? now - 3_601 : now;\n const credential = new VerifiedMcpCredential(\n subject,\n issuer,\n actualResource,\n token === 'expired' ? now - 61 : now,\n expiresAt,\n scopes,\n validatedAt,\n this.roles,\n [new ContextTuple(USER_ID, `${subject}-delegated`)],\n );\n if (token === 'list-bug') {\n Object.defineProperty(credential, 'listingRoles', {\n get: (): readonly string[] => {\n throw new Error('SECRET-internal-detail');\n },\n });\n }\n return credential;\n }\n}\n\nexport class RecordedLogLine {\n constructor(\n public readonly logger: string,\n public readonly level: LogLevel,\n public readonly message: string,\n public readonly error?: Error,\n ) {}\n\n /** The rendered line an operator would see, including an attached error's message and stack. */\n rendered(): string {\n return `${this.message} ${this.error?.message ?? ''} ${this.error?.stack ?? ''}`;\n }\n}\n\nclass RecordingLogger implements Logger {\n constructor(\n private readonly name: string,\n private readonly lines: RecordedLogLine[],\n ) {}\n\n trace(message: string, err?: Error): void {\n this.lines.push(new RecordedLogLine(this.name, 'trace', message, err));\n }\n\n debug(message: string, err?: Error): void {\n this.lines.push(new RecordedLogLine(this.name, 'debug', message, err));\n }\n\n info(message: string, err?: Error): void {\n this.lines.push(new RecordedLogLine(this.name, 'info', message, err));\n }\n\n warn(message: string, err?: Error): void {\n this.lines.push(new RecordedLogLine(this.name, 'warn', message, err));\n }\n\n error(message: string, err?: Error): void {\n this.lines.push(new RecordedLogLine(this.name, 'error', message, err));\n }\n}\n\n/** Captures every log line in-process so tests can count and level-check operator output. */\nexport class RecordingLoggerFactory implements LoggerFactory {\n readonly lines: RecordedLogLine[] = [];\n\n getLogger(name: string): Logger {\n return new RecordingLogger(name, this.lines);\n }\n\n containing(text: string): RecordedLogLine[] {\n return this.lines.filter((line: RecordedLogLine) => line.rendered().includes(text));\n }\n}\n"]}
|