@hookline/mcp 0.5.0 → 0.8.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 +16 -6
- package/dist/client.d.ts +5 -0
- package/dist/client.js +8 -3
- package/dist/client.js.map +1 -1
- package/dist/docs-gen.js +16 -6
- package/dist/docs-gen.js.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/create-endpoint.js +26 -0
- package/dist/tools/create-endpoint.js.map +1 -1
- package/dist/tools/create-validator.d.ts +28 -0
- package/dist/tools/create-validator.js +96 -0
- package/dist/tools/create-validator.js.map +1 -0
- package/dist/tools/custom-rules.d.ts +10 -0
- package/dist/tools/custom-rules.js +151 -0
- package/dist/tools/custom-rules.js.map +1 -0
- package/dist/tools/diff-payloads.js +7 -4
- package/dist/tools/diff-payloads.js.map +1 -1
- package/dist/tools/get-request-detail.js +1 -1
- package/dist/tools/get-request-detail.js.map +1 -1
- package/dist/tools/get-requests.d.ts +3 -1
- package/dist/tools/get-requests.js +44 -4
- package/dist/tools/get-requests.js.map +1 -1
- package/dist/tools/list-profiles.d.ts +3 -0
- package/dist/tools/list-profiles.js +42 -0
- package/dist/tools/list-profiles.js.map +1 -0
- package/dist/tools/payload-input.d.ts +1 -0
- package/dist/tools/payload-input.js +17 -0
- package/dist/tools/payload-input.js.map +1 -0
- package/dist/tools/profile-suggestions.d.ts +5 -0
- package/dist/tools/profile-suggestions.js +105 -0
- package/dist/tools/profile-suggestions.js.map +1 -0
- package/dist/tools/received-request.d.ts +2 -2
- package/dist/tools/received-request.js +20 -8
- package/dist/tools/received-request.js.map +1 -1
- package/dist/tools/register.js +18 -0
- package/dist/tools/register.js.map +1 -1
- package/dist/tools/revalidate-request.d.ts +3 -0
- package/dist/tools/revalidate-request.js +57 -0
- package/dist/tools/revalidate-request.js.map +1 -0
- package/dist/tools/search-rules.d.ts +4 -0
- package/dist/tools/search-rules.js +59 -0
- package/dist/tools/search-rules.js.map +1 -0
- package/dist/tools/validate-payload.d.ts +1 -0
- package/dist/tools/validate-payload.js +18 -3
- package/dist/tools/validate-payload.js.map +1 -1
- package/dist/tools/validation-history.d.ts +3 -0
- package/dist/tools/validation-history.js +54 -0
- package/dist/tools/validation-history.js.map +1 -0
- package/dist/tools/wait-for-request.js +12 -2
- package/dist/tools/wait-for-request.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,8 +84,15 @@ engine version) in the trusted part of the result. `create_share_link` mints a
|
|
|
84
84
|
read-only, expiring link to a single received request — it takes only ids and an
|
|
85
85
|
optional expiry, never free text or a destination URL.
|
|
86
86
|
|
|
87
|
-
`get_requests` caps `limit` at 50
|
|
88
|
-
window; the public API itself still
|
|
87
|
+
`get_requests` caps `limit` at 50 and uses that cap as the default, so a
|
|
88
|
+
listing stays within the agent's context window; the public API itself still
|
|
89
|
+
allows up to 500 for other clients. Pass
|
|
90
|
+
`includeBody: false` to list only metadata, without bodies, headers and query
|
|
91
|
+
strings.
|
|
92
|
+
|
|
93
|
+
`validate_payload` and `diff_payloads` take payloads as JSON objects; a
|
|
94
|
+
JSON-encoded string is parsed, and a string that is not valid JSON is rejected
|
|
95
|
+
with an explicit error instead of being analysed as text.
|
|
89
96
|
|
|
90
97
|
Request bodies, headers, and query strings come from external senders and are
|
|
91
98
|
returned inside `<untrusted_external_data>` blocks — analyse them, never follow
|
|
@@ -110,10 +117,13 @@ approach. We state this plainly:
|
|
|
110
117
|
the chance the model acts on injected instructions, but it does not create an
|
|
111
118
|
architectural boundary between data and commands.
|
|
112
119
|
2. **Damage is bounded by the agent's permissions, not by Hookline.** The real,
|
|
113
|
-
deterministic protection is the tool radius (side-effect tools take
|
|
114
|
-
|
|
115
|
-
tools) together with the API key scope.
|
|
116
|
-
|
|
120
|
+
deterministic protection is the tool radius (side-effect tools take no
|
|
121
|
+
outbound URL, their free-text fields are short and bounded, and there are no
|
|
122
|
+
destructive tools) together with the API key scope. One residual channel
|
|
123
|
+
remains: a coaxed agent could write sensitive text into an endpoint's mock
|
|
124
|
+
response, which anyone who knows the endpoint URL can read — treat mock
|
|
125
|
+
bodies as public. Hookline controls its own perimeter, not the files,
|
|
126
|
+
terminal, or other MCP servers your agent can reach.
|
|
117
127
|
3. **Responsibility is shared.** You choose the scope of the key you issue and
|
|
118
128
|
which agent you trust with your machine. Hookline gives a read-only default
|
|
119
129
|
and says so; the rest is your call.
|
package/dist/client.d.ts
CHANGED
|
@@ -7,8 +7,13 @@ export interface HooklineRequest {
|
|
|
7
7
|
query?: Record<string, string | number | undefined>;
|
|
8
8
|
timeoutMs?: number;
|
|
9
9
|
}
|
|
10
|
+
export interface HooklineResponse<T> {
|
|
11
|
+
data: T;
|
|
12
|
+
header(name: string): string | undefined;
|
|
13
|
+
}
|
|
10
14
|
export declare class HooklineClient {
|
|
11
15
|
private readonly config;
|
|
12
16
|
constructor(config: HooklineConfig);
|
|
13
17
|
request<T>(req: HooklineRequest): Promise<T>;
|
|
18
|
+
requestWithHeaders<T>(req: HooklineRequest): Promise<HooklineResponse<T>>;
|
|
14
19
|
}
|
package/dist/client.js
CHANGED
|
@@ -38,6 +38,9 @@ export class HooklineClient {
|
|
|
38
38
|
this.config = config;
|
|
39
39
|
}
|
|
40
40
|
async request(req) {
|
|
41
|
+
return (await this.requestWithHeaders(req)).data;
|
|
42
|
+
}
|
|
43
|
+
async requestWithHeaders(req) {
|
|
41
44
|
const url = `${this.config.apiUrl}${req.path}${buildQuery(req.query)}`;
|
|
42
45
|
const controller = new AbortController();
|
|
43
46
|
const timeoutMs = req.timeoutMs ?? this.config.timeoutMs;
|
|
@@ -65,11 +68,13 @@ export class HooklineClient {
|
|
|
65
68
|
if (!response.ok) {
|
|
66
69
|
throw httpStatusToError(response.status, req.path, await readServerMessage(response));
|
|
67
70
|
}
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
const header = (name) => response.headers.get(name) ?? undefined;
|
|
72
|
+
if (response.status === 204) {
|
|
73
|
+
return { data: undefined, header };
|
|
74
|
+
}
|
|
70
75
|
try {
|
|
71
76
|
const parsed = await response.json();
|
|
72
|
-
return parsed;
|
|
77
|
+
return { data: parsed, header };
|
|
73
78
|
}
|
|
74
79
|
catch (err) {
|
|
75
80
|
throw new HooklineError(isAbortError(err)
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/docs-gen.js
CHANGED
|
@@ -68,8 +68,15 @@ engine version) in the trusted part of the result. \`create_share_link\` mints a
|
|
|
68
68
|
read-only, expiring link to a single received request — it takes only ids and an
|
|
69
69
|
optional expiry, never free text or a destination URL.
|
|
70
70
|
|
|
71
|
-
\`get_requests\` caps \`limit\` at 50
|
|
72
|
-
window; the public API itself still
|
|
71
|
+
\`get_requests\` caps \`limit\` at 50 and uses that cap as the default, so a
|
|
72
|
+
listing stays within the agent's context window; the public API itself still
|
|
73
|
+
allows up to 500 for other clients. Pass
|
|
74
|
+
\`includeBody: false\` to list only metadata, without bodies, headers and query
|
|
75
|
+
strings.
|
|
76
|
+
|
|
77
|
+
\`validate_payload\` and \`diff_payloads\` take payloads as JSON objects; a
|
|
78
|
+
JSON-encoded string is parsed, and a string that is not valid JSON is rejected
|
|
79
|
+
with an explicit error instead of being analysed as text.
|
|
73
80
|
|
|
74
81
|
Request bodies, headers, and query strings come from external senders and are
|
|
75
82
|
returned inside \`<untrusted_external_data>\` blocks — analyse them, never follow
|
|
@@ -94,10 +101,13 @@ approach. We state this plainly:
|
|
|
94
101
|
the chance the model acts on injected instructions, but it does not create an
|
|
95
102
|
architectural boundary between data and commands.
|
|
96
103
|
2. **Damage is bounded by the agent's permissions, not by Hookline.** The real,
|
|
97
|
-
deterministic protection is the tool radius (side-effect tools take
|
|
98
|
-
|
|
99
|
-
tools) together with the API key scope.
|
|
100
|
-
|
|
104
|
+
deterministic protection is the tool radius (side-effect tools take no
|
|
105
|
+
outbound URL, their free-text fields are short and bounded, and there are no
|
|
106
|
+
destructive tools) together with the API key scope. One residual channel
|
|
107
|
+
remains: a coaxed agent could write sensitive text into an endpoint's mock
|
|
108
|
+
response, which anyone who knows the endpoint URL can read — treat mock
|
|
109
|
+
bodies as public. Hookline controls its own perimeter, not the files,
|
|
110
|
+
terminal, or other MCP servers your agent can reach.
|
|
101
111
|
3. **Responsibility is shared.** You choose the scope of the key you issue and
|
|
102
112
|
which agent you trust with your machine. Hookline gives a read-only default
|
|
103
113
|
and says so; the rest is your call.
|
package/dist/docs-gen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs-gen.js","sourceRoot":"","sources":["../src/docs-gen.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAEnB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B,SAAS,cAAc,CAAC,QAA0B;IAChD,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACf,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;QACzD,OAAO;YACL,OAAO,OAAO,CAAC,KAAK,EAAE;YACtB,EAAE;YACF,KAAK,GAAG,OAAO,CAAC,QAAQ;YACxB,IAAI;YACJ,KAAK;SACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAA0B;IACrD,OAAO;;;;;;;;;;;;;;;;EAgBP,cAAc,CAAC,QAAQ,CAAC
|
|
1
|
+
{"version":3,"file":"docs-gen.js","sourceRoot":"","sources":["../src/docs-gen.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAEnB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B,SAAS,cAAc,CAAC,QAA0B;IAChD,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACf,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;QACzD,OAAO;YACL,OAAO,OAAO,CAAC,KAAK,EAAE;YACtB,EAAE;YACF,KAAK,GAAG,OAAO,CAAC,QAAQ;YACxB,IAAI;YACJ,KAAK;SACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAA0B;IACrD,OAAO;;;;;;;;;;;;;;;;EAgBP,cAAc,CAAC,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgGzB,CAAC;AACF,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { ConfigError, loadConfig } from './config.js';
|
|
5
|
+
import { HooklineError } from './errors.js';
|
|
5
6
|
import { HooklineClient } from './client.js';
|
|
6
7
|
import { detectCapabilities } from './capabilities.js';
|
|
7
8
|
import { PACKAGE_VERSION } from './version.js';
|
|
@@ -29,7 +30,12 @@ async function main() {
|
|
|
29
30
|
process.stderr.write(`[hookline-mcp] ${mode}\n`);
|
|
30
31
|
}
|
|
31
32
|
main().catch((err) => {
|
|
32
|
-
|
|
33
|
+
const message = err instanceof HooklineError
|
|
34
|
+
? err.toAgentMessage()
|
|
35
|
+
: err instanceof Error
|
|
36
|
+
? err.message
|
|
37
|
+
: String(err);
|
|
38
|
+
process.stderr.write(`[hookline-mcp] fatal: ${message}\n`);
|
|
33
39
|
process.exit(1);
|
|
34
40
|
});
|
|
35
41
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,WAAW,EAAkB,UAAU,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,SAAS,gBAAgB;IACvB,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;YAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;IAC7E,aAAa,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC;IACxD,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IACtE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,IAAI,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,WAAW,EAAkB,UAAU,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,SAAS,gBAAgB;IACvB,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;YAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;IAC7E,aAAa,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC;IACxD,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IACtE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,IAAI,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,MAAM,OAAO,GACX,GAAG,YAAY,aAAa;QAC1B,CAAC,CAAC,GAAG,CAAC,cAAc,EAAE;QACtB,CAAC,CAAC,GAAG,YAAY,KAAK;YACpB,CAAC,CAAC,GAAG,CAAC,OAAO;YACb,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,OAAO,IAAI,CAAC,CAAC;IAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -12,6 +12,28 @@ export function registerCreateEndpoint(server, ctx) {
|
|
|
12
12
|
autoValidate: z.boolean().optional(),
|
|
13
13
|
validatorId: z.string().uuid().optional(),
|
|
14
14
|
expiresInHours: z.number().int().min(1).max(720).optional(),
|
|
15
|
+
wsEnabled: z
|
|
16
|
+
.boolean()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe('Also accept WebSocket connections on this endpoint — needed for OCPP-J chargers and other socket senders. Requires wsUsername and wsPassword.'),
|
|
19
|
+
wsUsername: z
|
|
20
|
+
.string()
|
|
21
|
+
.min(1)
|
|
22
|
+
.max(255)
|
|
23
|
+
.regex(/^[^:]+$/, 'must not contain a colon')
|
|
24
|
+
.optional()
|
|
25
|
+
.describe('Basic-auth username the WebSocket sender must present'),
|
|
26
|
+
wsPassword: z
|
|
27
|
+
.string()
|
|
28
|
+
.min(8)
|
|
29
|
+
.max(255)
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('Basic-auth password the WebSocket sender must present — stored hashed and never returned'),
|
|
32
|
+
wsSubprotocols: z
|
|
33
|
+
.array(z.string().min(1).max(64))
|
|
34
|
+
.max(16)
|
|
35
|
+
.optional()
|
|
36
|
+
.describe('Allowed WebSocket subprotocols, for example ["ocpp2.0.1"]; a connection offering none of them is closed'),
|
|
15
37
|
},
|
|
16
38
|
annotations: {
|
|
17
39
|
readOnlyHint: false,
|
|
@@ -34,6 +56,10 @@ export function registerCreateEndpoint(server, ctx) {
|
|
|
34
56
|
name: args.name,
|
|
35
57
|
autoValidate: args.autoValidate,
|
|
36
58
|
validatorId: args.validatorId,
|
|
59
|
+
wsEnabled: args.wsEnabled,
|
|
60
|
+
wsUsername: args.wsUsername,
|
|
61
|
+
wsPassword: args.wsPassword,
|
|
62
|
+
wsSubprotocols: args.wsSubprotocols,
|
|
37
63
|
expiresAt: args.expiresInHours === undefined
|
|
38
64
|
? undefined
|
|
39
65
|
: new Date(Date.now() + args.expiresInHours * HOUR_MS).toISOString(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-endpoint.js","sourceRoot":"","sources":["../../src/tools/create-endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE3E,MAAM,OAAO,GAAG,OAAO,CAAC;AACxB,MAAM,YAAY,GAAG,mCAAmC,CAAC;AAQzD,MAAM,UAAU,sBAAsB,CACpC,MAAiB,EACjB,GAAgB;IAEhB,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,2BAA2B;QAClC,WAAW,EACT,gWAAgW;QAClW,WAAW,EAAE;YACX,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;YAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;YACpD,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YACpC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;YACzC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"create-endpoint.js","sourceRoot":"","sources":["../../src/tools/create-endpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { ToolContext } from './context.js';
|
|
3
|
+
export declare const VALIDATOR_ENGINES: readonly ["openrtb", "json-schema", "standard-webhooks", "cloudevents", "ssf-caep", "ocpi", "ocpp-j", "igaming"];
|
|
4
|
+
export declare const OPENRTB_PRESET_KEY = "openrtb";
|
|
5
|
+
type ValidatorEngineName = (typeof VALIDATOR_ENGINES)[number];
|
|
6
|
+
export interface ValidatorOptionsPayload {
|
|
7
|
+
openrtbVersion: string;
|
|
8
|
+
target: string;
|
|
9
|
+
semanticRules: Record<string, string>;
|
|
10
|
+
tmaxThresholdMs: number;
|
|
11
|
+
tcf: {
|
|
12
|
+
check: boolean;
|
|
13
|
+
};
|
|
14
|
+
ocpiVersion?: string;
|
|
15
|
+
ocppVersion?: string;
|
|
16
|
+
igamingMessageType?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface CreateValidatorArgs {
|
|
19
|
+
engine: ValidatorEngineName;
|
|
20
|
+
openrtbVersion?: string;
|
|
21
|
+
bidDirection?: string;
|
|
22
|
+
ocpiVersion?: string;
|
|
23
|
+
ocppVersion?: string;
|
|
24
|
+
igamingMessageType?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function buildValidatorOptions(args: CreateValidatorArgs): ValidatorOptionsPayload;
|
|
27
|
+
export declare function registerCreateValidator(server: McpServer, ctx: ToolContext): void;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { errorResult, result, trusted, withStructured } from './result.js';
|
|
3
|
+
export const VALIDATOR_ENGINES = [
|
|
4
|
+
'openrtb',
|
|
5
|
+
'json-schema',
|
|
6
|
+
'standard-webhooks',
|
|
7
|
+
'cloudevents',
|
|
8
|
+
'ssf-caep',
|
|
9
|
+
'ocpi',
|
|
10
|
+
'ocpp-j',
|
|
11
|
+
'igaming',
|
|
12
|
+
];
|
|
13
|
+
export const OPENRTB_PRESET_KEY = 'openrtb';
|
|
14
|
+
export function buildValidatorOptions(args) {
|
|
15
|
+
return {
|
|
16
|
+
openrtbVersion: args.openrtbVersion ?? '2.6',
|
|
17
|
+
target: args.bidDirection ?? 'request',
|
|
18
|
+
semanticRules: {},
|
|
19
|
+
tmaxThresholdMs: 50,
|
|
20
|
+
tcf: { check: false },
|
|
21
|
+
ocpiVersion: args.engine === 'ocpi' ? (args.ocpiVersion ?? '2.2.1') : undefined,
|
|
22
|
+
ocppVersion: args.engine === 'ocpp-j' ? (args.ocppVersion ?? '2.0.1') : undefined,
|
|
23
|
+
igamingMessageType: args.engine === 'igaming'
|
|
24
|
+
? (args.igamingMessageType ?? 'wallet-bet')
|
|
25
|
+
: undefined,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function registerCreateValidator(server, ctx) {
|
|
29
|
+
server.registerTool('create_validator', {
|
|
30
|
+
title: 'Create a validator',
|
|
31
|
+
description: 'Create a reusable validator for one payload format, then attach it to an endpoint with create_endpoint (validatorId + autoValidate) so incoming traffic is checked automatically. Call list_profiles first to pick the engine. Use json-schema together with customSchemaId to validate against your own JSON Schema; the other engines validate with the rules Hookline ships for that format.',
|
|
32
|
+
inputSchema: {
|
|
33
|
+
name: z.string().min(1).max(120),
|
|
34
|
+
engine: z
|
|
35
|
+
.enum(VALIDATOR_ENGINES)
|
|
36
|
+
.describe('The payload format this validator checks'),
|
|
37
|
+
description: z.string().max(500).optional(),
|
|
38
|
+
customSchemaId: z
|
|
39
|
+
.string()
|
|
40
|
+
.uuid()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe('Required for the json-schema engine; rejected by some others'),
|
|
43
|
+
openrtbVersion: z
|
|
44
|
+
.enum(['2.5', '2.6'])
|
|
45
|
+
.optional()
|
|
46
|
+
.describe('openrtb engine only — defaults to 2.6'),
|
|
47
|
+
bidDirection: z
|
|
48
|
+
.enum(['request', 'response'])
|
|
49
|
+
.optional()
|
|
50
|
+
.describe('openrtb engine only — validate the bid request or the bid response'),
|
|
51
|
+
ocpiVersion: z.enum(['2.2.1', '2.3.0']).optional(),
|
|
52
|
+
ocppVersion: z.enum(['1.6j', '2.0.1']).optional(),
|
|
53
|
+
igamingMessageType: z
|
|
54
|
+
.enum(['wallet-bet', 'wallet-win', 'wallet-rollback'])
|
|
55
|
+
.optional()
|
|
56
|
+
.describe('igaming engine only — defaults to wallet-bet'),
|
|
57
|
+
},
|
|
58
|
+
annotations: {
|
|
59
|
+
readOnlyHint: false,
|
|
60
|
+
destructiveHint: false,
|
|
61
|
+
idempotentHint: false,
|
|
62
|
+
openWorldHint: true,
|
|
63
|
+
title: 'Create a validator',
|
|
64
|
+
},
|
|
65
|
+
outputSchema: {
|
|
66
|
+
id: z.string(),
|
|
67
|
+
name: z.string(),
|
|
68
|
+
engine: z.string(),
|
|
69
|
+
},
|
|
70
|
+
}, async (args) => {
|
|
71
|
+
try {
|
|
72
|
+
const validator = await ctx.client.request({
|
|
73
|
+
method: 'POST',
|
|
74
|
+
path: '/validators',
|
|
75
|
+
body: {
|
|
76
|
+
name: args.name,
|
|
77
|
+
description: args.description ?? null,
|
|
78
|
+
engine: args.engine,
|
|
79
|
+
presetKey: args.engine === 'openrtb' ? OPENRTB_PRESET_KEY : null,
|
|
80
|
+
customSchemaId: args.customSchemaId ?? null,
|
|
81
|
+
options: buildValidatorOptions(args),
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
const payload = {
|
|
85
|
+
id: validator.id,
|
|
86
|
+
name: validator.name,
|
|
87
|
+
engine: validator.engine,
|
|
88
|
+
};
|
|
89
|
+
return withStructured(result(trusted(payload)), payload);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
return errorResult(err);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=create-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-validator.js","sourceRoot":"","sources":["../../src/tools/create-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { ToolContext } from './context.js';
|
|
3
|
+
export declare enum CustomRuleSeverity {
|
|
4
|
+
Error = "error",
|
|
5
|
+
Warning = "warning",
|
|
6
|
+
Info = "info"
|
|
7
|
+
}
|
|
8
|
+
export declare function registerListCustomRules(server: McpServer, ctx: ToolContext): void;
|
|
9
|
+
export declare function registerPreviewCustomRule(server: McpServer, ctx: ToolContext): void;
|
|
10
|
+
export declare function registerCreateCustomRule(server: McpServer, ctx: ToolContext): void;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { errorResult, result, trusted, withStructured } from './result.js';
|
|
3
|
+
export var CustomRuleSeverity;
|
|
4
|
+
(function (CustomRuleSeverity) {
|
|
5
|
+
CustomRuleSeverity["Error"] = "error";
|
|
6
|
+
CustomRuleSeverity["Warning"] = "warning";
|
|
7
|
+
CustomRuleSeverity["Info"] = "info";
|
|
8
|
+
})(CustomRuleSeverity || (CustomRuleSeverity = {}));
|
|
9
|
+
const SPEC_GUIDE = 'A rule spec is {scope, assert, message, when?, appliesTo?}. scope is a JSON pointer to the node the rule runs on ("" for the whole document, "/imp" to run once per impression). assert and when are conditions: {kind:"check", path, op, value} where op is one of eq, ne, gt, gte, lt, lte, matches, in, type-of, length-gt, exists, absent; {kind:"compare", left, op, right} to compare two pointers; or {kind:"and"|"or", conditions:[...]} and {kind:"not", condition:{...}}. Example: {"scope":"","assert":{"kind":"check","path":"/tmax","op":"gte","value":50},"message":"tmax must be at least 50ms"}.';
|
|
10
|
+
const specSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
scope: z.string(),
|
|
13
|
+
assert: z.record(z.unknown()),
|
|
14
|
+
message: z.string().min(1).max(500),
|
|
15
|
+
when: z.record(z.unknown()).optional(),
|
|
16
|
+
appliesTo: z
|
|
17
|
+
.object({
|
|
18
|
+
profileId: z.string().max(64).optional(),
|
|
19
|
+
profileVersions: z.array(z.string().max(32)).max(16).optional(),
|
|
20
|
+
messageTypes: z.array(z.string().max(64)).max(16).optional(),
|
|
21
|
+
})
|
|
22
|
+
.optional(),
|
|
23
|
+
})
|
|
24
|
+
.describe(SPEC_GUIDE);
|
|
25
|
+
function toCreatedRulePayload(rule) {
|
|
26
|
+
return {
|
|
27
|
+
id: rule.id,
|
|
28
|
+
ruleId: rule.ruleId,
|
|
29
|
+
slug: rule.slug,
|
|
30
|
+
name: rule.name,
|
|
31
|
+
severity: rule.severity,
|
|
32
|
+
enabled: rule.enabled,
|
|
33
|
+
version: rule.version,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function registerListCustomRules(server, ctx) {
|
|
37
|
+
server.registerTool('list_custom_rules', {
|
|
38
|
+
title: 'List custom rules',
|
|
39
|
+
description: 'List the rules you wrote yourself. They run alongside the built-in rule packs of whichever profile a validator uses, so a custom rule applies to every validation that matches its appliesTo.',
|
|
40
|
+
inputSchema: {},
|
|
41
|
+
annotations: {
|
|
42
|
+
readOnlyHint: true,
|
|
43
|
+
openWorldHint: true,
|
|
44
|
+
title: 'List custom rules',
|
|
45
|
+
},
|
|
46
|
+
outputSchema: {
|
|
47
|
+
count: z.number(),
|
|
48
|
+
rules: z.array(z.unknown()),
|
|
49
|
+
},
|
|
50
|
+
}, async () => {
|
|
51
|
+
try {
|
|
52
|
+
const rules = await ctx.client.request({
|
|
53
|
+
method: 'GET',
|
|
54
|
+
path: '/custom-rules',
|
|
55
|
+
});
|
|
56
|
+
const payload = { count: rules.length, rules };
|
|
57
|
+
return withStructured(result(trusted(payload)), payload);
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
return errorResult(err);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export function registerPreviewCustomRule(server, ctx) {
|
|
65
|
+
server.registerTool('preview_custom_rule', {
|
|
66
|
+
title: 'Try a custom rule',
|
|
67
|
+
description: `Run a rule spec against a sample payload without saving it, and see what it would report. Use this to iterate on a rule before creating it. ${SPEC_GUIDE}`,
|
|
68
|
+
inputSchema: {
|
|
69
|
+
spec: specSchema,
|
|
70
|
+
payload: z.record(z.unknown()),
|
|
71
|
+
severity: z.nativeEnum(CustomRuleSeverity).optional(),
|
|
72
|
+
profileId: z.string().max(64).optional(),
|
|
73
|
+
profileVersion: z.string().max(32).optional(),
|
|
74
|
+
messageType: z.string().max(64).optional(),
|
|
75
|
+
},
|
|
76
|
+
annotations: {
|
|
77
|
+
readOnlyHint: true,
|
|
78
|
+
openWorldHint: true,
|
|
79
|
+
title: 'Try a custom rule',
|
|
80
|
+
},
|
|
81
|
+
outputSchema: {
|
|
82
|
+
engineVersion: z.string(),
|
|
83
|
+
findings: z.array(z.unknown()),
|
|
84
|
+
skippedRules: z.array(z.unknown()),
|
|
85
|
+
},
|
|
86
|
+
}, async (args) => {
|
|
87
|
+
try {
|
|
88
|
+
const outcome = await ctx.client.request({
|
|
89
|
+
method: 'POST',
|
|
90
|
+
path: '/custom-rules/preview',
|
|
91
|
+
body: args,
|
|
92
|
+
});
|
|
93
|
+
const payload = {
|
|
94
|
+
engineVersion: outcome.engineVersion,
|
|
95
|
+
findings: outcome.findings,
|
|
96
|
+
skippedRules: outcome.skippedRules,
|
|
97
|
+
};
|
|
98
|
+
return withStructured(result(trusted(payload)), payload);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
return errorResult(err);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
export function registerCreateCustomRule(server, ctx) {
|
|
106
|
+
server.registerTool('create_custom_rule', {
|
|
107
|
+
title: 'Create a custom rule',
|
|
108
|
+
description: `Save a rule of your own so every matching validation applies it. Try the spec with preview_custom_rule first — an invalid spec is rejected with a message naming the problem. ${SPEC_GUIDE}`,
|
|
109
|
+
inputSchema: {
|
|
110
|
+
slug: z
|
|
111
|
+
.string()
|
|
112
|
+
.min(1)
|
|
113
|
+
.max(64)
|
|
114
|
+
.regex(/^[a-z0-9][a-z0-9-]*$/, 'lowercase letters, digits and dashes'),
|
|
115
|
+
name: z.string().min(1).max(120),
|
|
116
|
+
severity: z.nativeEnum(CustomRuleSeverity),
|
|
117
|
+
spec: specSchema,
|
|
118
|
+
enabled: z.boolean().optional(),
|
|
119
|
+
},
|
|
120
|
+
annotations: {
|
|
121
|
+
readOnlyHint: false,
|
|
122
|
+
destructiveHint: false,
|
|
123
|
+
idempotentHint: false,
|
|
124
|
+
openWorldHint: true,
|
|
125
|
+
title: 'Create a custom rule',
|
|
126
|
+
},
|
|
127
|
+
outputSchema: {
|
|
128
|
+
id: z.string(),
|
|
129
|
+
ruleId: z.string(),
|
|
130
|
+
slug: z.string(),
|
|
131
|
+
name: z.string(),
|
|
132
|
+
severity: z.string(),
|
|
133
|
+
enabled: z.boolean(),
|
|
134
|
+
version: z.number(),
|
|
135
|
+
},
|
|
136
|
+
}, async (args) => {
|
|
137
|
+
try {
|
|
138
|
+
const rule = await ctx.client.request({
|
|
139
|
+
method: 'POST',
|
|
140
|
+
path: '/custom-rules',
|
|
141
|
+
body: args,
|
|
142
|
+
});
|
|
143
|
+
const payload = toCreatedRulePayload(rule);
|
|
144
|
+
return withStructured(result(trusted(payload)), payload);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
return errorResult(err);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=custom-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-rules.js","sourceRoot":"","sources":["../../src/tools/custom-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { coerceJsonArgument } from './payload-input.js';
|
|
2
3
|
import { errorResult, result, trusted, withStructured } from './result.js';
|
|
3
4
|
export function registerDiffPayloads(server, ctx) {
|
|
4
5
|
server.registerTool('diff_payloads', {
|
|
@@ -7,10 +8,12 @@ export function registerDiffPayloads(server, ctx) {
|
|
|
7
8
|
inputSchema: {
|
|
8
9
|
left: z
|
|
9
10
|
.unknown()
|
|
10
|
-
.refine((value) => value !== undefined, 'left is required')
|
|
11
|
+
.refine((value) => value !== undefined, 'left is required')
|
|
12
|
+
.describe('The first payload, as a JSON object — not a string (a JSON-encoded string is parsed, anything else is rejected)'),
|
|
11
13
|
right: z
|
|
12
14
|
.unknown()
|
|
13
|
-
.refine((value) => value !== undefined, 'right is required')
|
|
15
|
+
.refine((value) => value !== undefined, 'right is required')
|
|
16
|
+
.describe('The second payload, as a JSON object — not a string (a JSON-encoded string is parsed, anything else is rejected)'),
|
|
14
17
|
profileId: z.string().optional(),
|
|
15
18
|
treatNullAsAbsent: z.boolean().optional(),
|
|
16
19
|
ignoreFields: z.array(z.string()).optional(),
|
|
@@ -31,8 +34,8 @@ export function registerDiffPayloads(server, ctx) {
|
|
|
31
34
|
method: 'POST',
|
|
32
35
|
path: '/diff',
|
|
33
36
|
body: {
|
|
34
|
-
left: args.left,
|
|
35
|
-
right: args.right,
|
|
37
|
+
left: coerceJsonArgument(args.left, 'left'),
|
|
38
|
+
right: coerceJsonArgument(args.right, 'right'),
|
|
36
39
|
profileId: args.profileId,
|
|
37
40
|
treatNullAsAbsent: args.treatNullAsAbsent,
|
|
38
41
|
ignoreFields: args.ignoreFields,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-payloads.js","sourceRoot":"","sources":["../../src/tools/diff-payloads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQ3E,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,GAAgB;IAEhB,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,yIAAyI;QAC3I,WAAW,EAAE;YACX,IAAI,EAAE,CAAC;iBACJ,OAAO,EAAE;iBACT,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,EAAE,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"diff-payloads.js","sourceRoot":"","sources":["../../src/tools/diff-payloads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQ3E,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,GAAgB;IAEhB,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,yIAAyI;QAC3I,WAAW,EAAE;YACX,IAAI,EAAE,CAAC;iBACJ,OAAO,EAAE;iBACT,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,EAAE,kBAAkB,CAAC;iBAC1D,QAAQ,CACP,iHAAiH,CAClH;YACH,KAAK,EAAE,CAAC;iBACL,OAAO,EAAE;iBACT,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,EAAE,mBAAmB,CAAC;iBAC3D,QAAQ,CACP,kHAAkH,CACnH;YACH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAChC,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YACzC,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;SAC7C;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,IAAI;YACnB,KAAK,EAAE,mBAAmB;SAC3B;QACD,YAAY,EAAE;YACZ,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;YACtB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC9B;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAe;gBACtD,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE;oBACJ,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;oBAC3C,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;oBAC9C,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;oBACzC,YAAY,EAAE,IAAI,CAAC,YAAY;iBAChC;aACF,CAAC,CAAC;YACH,MAAM,IAAI,GAAG;gBACX,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE;aAChC,CAAC;YACF,OAAO,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -37,7 +37,7 @@ export function registerGetRequestDetail(server, ctx) {
|
|
|
37
37
|
method: 'GET',
|
|
38
38
|
path: `/webhook-endpoints/${args.endpointId}/requests/${args.requestId}`,
|
|
39
39
|
});
|
|
40
|
-
const meta = detailMetaOf(request);
|
|
40
|
+
const meta = detailMetaOf(request, ctx.config.maxBodyBytes);
|
|
41
41
|
return withStructured(result(trusted(meta), ...untrustedBlocksOf(request, ctx.config.maxBodyBytes)), structuredDetailOf(request, ctx.config.maxBodyBytes));
|
|
42
42
|
}
|
|
43
43
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-request-detail.js","sourceRoot":"","sources":["../../src/tools/get-request-detail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAEL,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,GAAgB;IAEhB,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,wZAAwZ;QAC1Z,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;YAC7B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;SAC7B;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,IAAI;YACnB,KAAK,EAAE,oDAAoD;SAC5D;QACD,YAAY,EAAE;YACZ,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;YACd,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;YACtB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;YACtB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;YAC1B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACvC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACvC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACzC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YACvD,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;YACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;SAClB;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAwB;gBAC9D,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,sBAAsB,IAAI,CAAC,UAAU,aAAa,IAAI,CAAC,SAAS,EAAE;aACzE,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"get-request-detail.js","sourceRoot":"","sources":["../../src/tools/get-request-detail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAEL,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,GAAgB;IAEhB,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,wZAAwZ;QAC1Z,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;YAC7B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;SAC7B;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,IAAI;YACnB,KAAK,EAAE,oDAAoD;SAC5D;QACD,YAAY,EAAE;YACZ,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;YACd,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;YACtB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;YACtB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;YAC1B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACvC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACvC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACzC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YACvD,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;YACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;SAClB;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAwB;gBAC9D,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,sBAAsB,IAAI,CAAC,UAAU,aAAa,IAAI,CAAC,SAAS,EAAE;aACzE,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAC5D,OAAO,cAAc,CACnB,MAAM,CACJ,OAAO,CAAC,IAAI,CAAC,EACb,GAAG,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CACvD,EACD,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CACrD,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { ToolContext } from './context.js';
|
|
3
3
|
export declare const MAX_LIST_LIMIT = 50;
|
|
4
|
-
export declare
|
|
4
|
+
export declare const NEXT_CURSOR_HEADER = "X-Next-Cursor";
|
|
5
|
+
export declare const VALIDATION_STATUS_FILTERS: readonly ["valid", "invalid", "warning", "unvalidated"];
|
|
6
|
+
export declare function clampListLimit(limit?: number): number;
|
|
5
7
|
export declare function registerGetRequests(server: McpServer, ctx: ToolContext): void;
|