mcp-use-compat 0.3.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/CHANGELOG.md +23 -0
- package/LICENSE +21 -0
- package/README.md +375 -0
- package/dist/checks/auth.d.ts +2 -0
- package/dist/checks/auth.d.ts.map +1 -0
- package/dist/checks/auth.js +229 -0
- package/dist/checks/auth.js.map +1 -0
- package/dist/checks/calls.d.ts +4 -0
- package/dist/checks/calls.d.ts.map +1 -0
- package/dist/checks/calls.js +192 -0
- package/dist/checks/calls.js.map +1 -0
- package/dist/checks/discovery.d.ts +3 -0
- package/dist/checks/discovery.d.ts.map +1 -0
- package/dist/checks/discovery.js +47 -0
- package/dist/checks/discovery.js.map +1 -0
- package/dist/checks/explanations.d.ts +15 -0
- package/dist/checks/explanations.d.ts.map +1 -0
- package/dist/checks/explanations.js +346 -0
- package/dist/checks/explanations.js.map +1 -0
- package/dist/checks/index.d.ts +3 -0
- package/dist/checks/index.d.ts.map +1 -0
- package/dist/checks/index.js +23 -0
- package/dist/checks/index.js.map +1 -0
- package/dist/checks/protocol.d.ts +5 -0
- package/dist/checks/protocol.d.ts.map +1 -0
- package/dist/checks/protocol.js +380 -0
- package/dist/checks/protocol.js.map +1 -0
- package/dist/checks/resources.d.ts +10 -0
- package/dist/checks/resources.d.ts.map +1 -0
- package/dist/checks/resources.js +144 -0
- package/dist/checks/resources.js.map +1 -0
- package/dist/checks/schema.d.ts +21 -0
- package/dist/checks/schema.d.ts.map +1 -0
- package/dist/checks/schema.js +412 -0
- package/dist/checks/schema.js.map +1 -0
- package/dist/checks/sdk.d.ts +10 -0
- package/dist/checks/sdk.d.ts.map +1 -0
- package/dist/checks/sdk.js +68 -0
- package/dist/checks/sdk.js.map +1 -0
- package/dist/checks/tools.d.ts +18 -0
- package/dist/checks/tools.d.ts.map +1 -0
- package/dist/checks/tools.js +422 -0
- package/dist/checks/tools.js.map +1 -0
- package/dist/checks/transport.d.ts +2 -0
- package/dist/checks/transport.d.ts.map +1 -0
- package/dist/checks/transport.js +123 -0
- package/dist/checks/transport.js.map +1 -0
- package/dist/checks/types.d.ts +37 -0
- package/dist/checks/types.d.ts.map +1 -0
- package/dist/checks/types.js +5 -0
- package/dist/checks/types.js.map +1 -0
- package/dist/checks/ui.d.ts +2 -0
- package/dist/checks/ui.d.ts.map +1 -0
- package/dist/checks/ui.js +207 -0
- package/dist/checks/ui.js.map +1 -0
- package/dist/checks/util.d.ts +20 -0
- package/dist/checks/util.d.ts.map +1 -0
- package/dist/checks/util.js +42 -0
- package/dist/checks/util.js.map +1 -0
- package/dist/cli.d.ts +110 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +317 -0
- package/dist/cli.js.map +1 -0
- package/dist/connect/calls.d.ts +13 -0
- package/dist/connect/calls.d.ts.map +1 -0
- package/dist/connect/calls.js +130 -0
- package/dist/connect/calls.js.map +1 -0
- package/dist/connect/http.d.ts +14 -0
- package/dist/connect/http.d.ts.map +1 -0
- package/dist/connect/http.js +122 -0
- package/dist/connect/http.js.map +1 -0
- package/dist/connect/index.d.ts +41 -0
- package/dist/connect/index.d.ts.map +1 -0
- package/dist/connect/index.js +168 -0
- package/dist/connect/index.js.map +1 -0
- package/dist/connect/lists.d.ts +12 -0
- package/dist/connect/lists.d.ts.map +1 -0
- package/dist/connect/lists.js +70 -0
- package/dist/connect/lists.js.map +1 -0
- package/dist/connect/modern.d.ts +13 -0
- package/dist/connect/modern.d.ts.map +1 -0
- package/dist/connect/modern.js +169 -0
- package/dist/connect/modern.js.map +1 -0
- package/dist/connect/session.d.ts +29 -0
- package/dist/connect/session.d.ts.map +1 -0
- package/dist/connect/session.js +96 -0
- package/dist/connect/session.js.map +1 -0
- package/dist/connect/stdio.d.ts +36 -0
- package/dist/connect/stdio.d.ts.map +1 -0
- package/dist/connect/stdio.js +127 -0
- package/dist/connect/stdio.js.map +1 -0
- package/dist/diff.d.ts +23 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +255 -0
- package/dist/diff.js.map +1 -0
- package/dist/evaluate.d.ts +70 -0
- package/dist/evaluate.d.ts.map +1 -0
- package/dist/evaluate.js +104 -0
- package/dist/evaluate.js.map +1 -0
- package/dist/explain.d.ts +4 -0
- package/dist/explain.d.ts.map +1 -0
- package/dist/explain.js +46 -0
- package/dist/explain.js.map +1 -0
- package/dist/fix.d.ts +19 -0
- package/dist/fix.d.ts.map +1 -0
- package/dist/fix.js +116 -0
- package/dist/fix.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth.d.ts +85 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +287 -0
- package/dist/oauth.js.map +1 -0
- package/dist/policy.d.ts +29 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +63 -0
- package/dist/policy.js.map +1 -0
- package/dist/profiles/chatgpt.d.ts +3 -0
- package/dist/profiles/chatgpt.d.ts.map +1 -0
- package/dist/profiles/chatgpt.js +29 -0
- package/dist/profiles/chatgpt.js.map +1 -0
- package/dist/profiles/claude-code.d.ts +3 -0
- package/dist/profiles/claude-code.d.ts.map +1 -0
- package/dist/profiles/claude-code.js +62 -0
- package/dist/profiles/claude-code.js.map +1 -0
- package/dist/profiles/claude-desktop.d.ts +3 -0
- package/dist/profiles/claude-desktop.d.ts.map +1 -0
- package/dist/profiles/claude-desktop.js +51 -0
- package/dist/profiles/claude-desktop.js.map +1 -0
- package/dist/profiles/cline.d.ts +4 -0
- package/dist/profiles/cline.d.ts.map +1 -0
- package/dist/profiles/cline.js +118 -0
- package/dist/profiles/cline.js.map +1 -0
- package/dist/profiles/codex.d.ts +4 -0
- package/dist/profiles/codex.d.ts.map +1 -0
- package/dist/profiles/codex.js +168 -0
- package/dist/profiles/codex.js.map +1 -0
- package/dist/profiles/continue.d.ts +4 -0
- package/dist/profiles/continue.d.ts.map +1 -0
- package/dist/profiles/continue.js +93 -0
- package/dist/profiles/continue.js.map +1 -0
- package/dist/profiles/cursor.d.ts +3 -0
- package/dist/profiles/cursor.d.ts.map +1 -0
- package/dist/profiles/cursor.js +52 -0
- package/dist/profiles/cursor.js.map +1 -0
- package/dist/profiles/gemini-cli.d.ts +4 -0
- package/dist/profiles/gemini-cli.d.ts.map +1 -0
- package/dist/profiles/gemini-cli.js +137 -0
- package/dist/profiles/gemini-cli.js.map +1 -0
- package/dist/profiles/goose.d.ts +4 -0
- package/dist/profiles/goose.d.ts.map +1 -0
- package/dist/profiles/goose.js +114 -0
- package/dist/profiles/goose.js.map +1 -0
- package/dist/profiles/index.d.ts +7 -0
- package/dist/profiles/index.d.ts.map +1 -0
- package/dist/profiles/index.js +43 -0
- package/dist/profiles/index.js.map +1 -0
- package/dist/profiles/opencode.d.ts +3 -0
- package/dist/profiles/opencode.d.ts.map +1 -0
- package/dist/profiles/opencode.js +47 -0
- package/dist/profiles/opencode.js.map +1 -0
- package/dist/profiles/types.d.ts +86 -0
- package/dist/profiles/types.d.ts.map +1 -0
- package/dist/profiles/types.js +2 -0
- package/dist/profiles/types.js.map +1 -0
- package/dist/profiles/vscode-copilot.d.ts +3 -0
- package/dist/profiles/vscode-copilot.d.ts.map +1 -0
- package/dist/profiles/vscode-copilot.js +71 -0
- package/dist/profiles/vscode-copilot.js.map +1 -0
- package/dist/profiles/windsurf.d.ts +4 -0
- package/dist/profiles/windsurf.d.ts.map +1 -0
- package/dist/profiles/windsurf.js +49 -0
- package/dist/profiles/windsurf.js.map +1 -0
- package/dist/project.d.ts +52 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +291 -0
- package/dist/project.js.map +1 -0
- package/dist/reporters/escape.d.ts +7 -0
- package/dist/reporters/escape.d.ts.map +1 -0
- package/dist/reporters/escape.js +15 -0
- package/dist/reporters/escape.js.map +1 -0
- package/dist/reporters/github.d.ts +7 -0
- package/dist/reporters/github.d.ts.map +1 -0
- package/dist/reporters/github.js +19 -0
- package/dist/reporters/github.js.map +1 -0
- package/dist/reporters/index.d.ts +6 -0
- package/dist/reporters/index.d.ts.map +1 -0
- package/dist/reporters/index.js +10 -0
- package/dist/reporters/index.js.map +1 -0
- package/dist/reporters/json.d.ts +3 -0
- package/dist/reporters/json.d.ts.map +1 -0
- package/dist/reporters/json.js +4 -0
- package/dist/reporters/json.js.map +1 -0
- package/dist/reporters/markdown.d.ts +3 -0
- package/dist/reporters/markdown.d.ts.map +1 -0
- package/dist/reporters/markdown.js +98 -0
- package/dist/reporters/markdown.js.map +1 -0
- package/dist/run.d.ts +14 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +163 -0
- package/dist/run.js.map +1 -0
- package/dist/sdk-facts.d.ts +27 -0
- package/dist/sdk-facts.d.ts.map +1 -0
- package/dist/sdk-facts.js +63 -0
- package/dist/sdk-facts.js.map +1 -0
- package/dist/snapshot.d.ts +189 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +22 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/ui.d.ts +18 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +22 -0
- package/dist/ui.js.map +1 -0
- package/dist/upgrade.d.ts +12 -0
- package/dist/upgrade.d.ts.map +1 -0
- package/dist/upgrade.js +115 -0
- package/dist/upgrade.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/package.json +65 -0
- package/schema/report.schema.json +327 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { LIST_KINDS } from "../snapshot.js";
|
|
3
|
+
import { connected, declared, str } from "./util.js";
|
|
4
|
+
import { upgradeHint } from "./sdk.js";
|
|
5
|
+
import { defineCheck } from "./types.js";
|
|
6
|
+
const KINDS = Object.keys(LIST_KINDS);
|
|
7
|
+
const MODERN = "2026-07-28";
|
|
8
|
+
const SPEC_MODERN = `https://modelcontextprotocol.io/specification/${MODERN}`;
|
|
9
|
+
/** Server rejected initialize but speaks 2026-07-28 (older snapshots: discover worked, connect failed). */
|
|
10
|
+
export function modernOnly(s) {
|
|
11
|
+
return s.era === "modern" || (!s.connect.ok && !!s.discover?.ok);
|
|
12
|
+
}
|
|
13
|
+
const legacyConnected = (s) => connected(s) && s.era !== "modern";
|
|
14
|
+
const modernSupported = (s) => !!s.modern?.supported && !!s.modern.lists;
|
|
15
|
+
const VALID_RESULT_TYPES = new Set(["complete", "input_required"]);
|
|
16
|
+
/** Every modern result we saw, labelled by where it came from. */
|
|
17
|
+
function modernResults(s) {
|
|
18
|
+
const out = [];
|
|
19
|
+
if (s.modern?.discoverMeta)
|
|
20
|
+
out.push(["server/discover", s.modern.discoverMeta]);
|
|
21
|
+
for (const kind of KINDS) {
|
|
22
|
+
for (const meta of s.modern?.pagesMeta?.[kind] ?? [])
|
|
23
|
+
out.push([LIST_KINDS[kind].method, meta]);
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
function supportedVersions(s) {
|
|
28
|
+
const v = s.discover?.result?.supportedVersions;
|
|
29
|
+
return Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
|
|
30
|
+
}
|
|
31
|
+
export const protocolChecks = [
|
|
32
|
+
defineCheck({
|
|
33
|
+
id: "PROTOCOL_MODERN_ONLY",
|
|
34
|
+
area: "protocol",
|
|
35
|
+
description: "Server still accepts the initialize handshake most clients use",
|
|
36
|
+
appliesTo: (s) => !!s.discover,
|
|
37
|
+
run: (s) => modernOnly(s)
|
|
38
|
+
? [
|
|
39
|
+
{
|
|
40
|
+
checkId: "PROTOCOL_MODERN_ONLY",
|
|
41
|
+
severity: "error",
|
|
42
|
+
message: `Server rejects initialize and only answers server/discover (versions: ${supportedVersions(s).join(", ") || "none listed"}). Clients that still use the initialize handshake (protocol 2025-11-25 and older) cannot connect.`,
|
|
43
|
+
evidence: { initializeError: s.connect.legacyError ?? s.connect.error, discover: s.discover?.result },
|
|
44
|
+
fix: "Keep accepting initialize alongside server/discover until your target clients support the new revision.",
|
|
45
|
+
},
|
|
46
|
+
]
|
|
47
|
+
: [],
|
|
48
|
+
}),
|
|
49
|
+
defineCheck({
|
|
50
|
+
id: "PROTOCOL_DISCOVER_MISSING",
|
|
51
|
+
area: "protocol",
|
|
52
|
+
description: `Server implements server/discover (required from protocol ${MODERN})`,
|
|
53
|
+
appliesTo: (s) => connected(s) && !!s.discover,
|
|
54
|
+
run: (s) => s.discover.ok
|
|
55
|
+
? []
|
|
56
|
+
: [
|
|
57
|
+
{
|
|
58
|
+
checkId: "PROTOCOL_DISCOVER_MISSING",
|
|
59
|
+
severity: "info",
|
|
60
|
+
message: `server/discover failed (${s.discover.error?.message ?? "unknown error"}), so the server only speaks the initialize-based protocol. That works with today's clients; clients on revision ${MODERN} have to fall back to initialize.`,
|
|
61
|
+
fix: `When your target clients support ${MODERN}: ${upgradeHint(s, true)}`,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
}),
|
|
65
|
+
defineCheck({
|
|
66
|
+
id: "PROTOCOL_MODERN_RESULT_TYPE",
|
|
67
|
+
area: "protocol",
|
|
68
|
+
description: `${MODERN} results carry a valid resultType`,
|
|
69
|
+
appliesTo: modernSupported,
|
|
70
|
+
run: (s) => {
|
|
71
|
+
const results = modernResults(s);
|
|
72
|
+
const missing = results.filter(([, m]) => m.resultType === undefined).map(([where]) => where);
|
|
73
|
+
const invalid = results.filter(([, m]) => m.resultType !== undefined && !VALID_RESULT_TYPES.has(String(m.resultType)));
|
|
74
|
+
const findings = [];
|
|
75
|
+
if (missing.length) {
|
|
76
|
+
findings.push({
|
|
77
|
+
checkId: "PROTOCOL_MODERN_RESULT_TYPE",
|
|
78
|
+
severity: "warn",
|
|
79
|
+
subject: [...new Set(missing)].join(", "),
|
|
80
|
+
message: `${MODERN} requires resultType on every result; it's missing from ${[...new Set(missing)].join(", ")}. The v2 SDK treats a missing value as "complete", but stricter clients may not.`,
|
|
81
|
+
source: `${SPEC_MODERN}/basic/index`,
|
|
82
|
+
fix: 'Upgrade to an SDK that implements 2026-07-28, or add resultType: "complete".',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
for (const [where, meta] of invalid) {
|
|
86
|
+
findings.push({
|
|
87
|
+
checkId: "PROTOCOL_MODERN_RESULT_TYPE",
|
|
88
|
+
severity: "error",
|
|
89
|
+
subject: where,
|
|
90
|
+
message: `resultType ${JSON.stringify(meta.resultType)} is not "complete" or "input_required"; clients must treat the result as invalid.`,
|
|
91
|
+
source: `${SPEC_MODERN}/basic/index`,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return findings;
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
97
|
+
defineCheck({
|
|
98
|
+
id: "PROTOCOL_MODERN_CACHE_FIELDS",
|
|
99
|
+
area: "protocol",
|
|
100
|
+
description: `${MODERN} list and discover results carry ttlMs and cacheScope`,
|
|
101
|
+
appliesTo: modernSupported,
|
|
102
|
+
run: (s) => {
|
|
103
|
+
const bad = modernResults(s).filter(([, m]) => typeof m.ttlMs !== "number" || m.ttlMs < 0 || (m.cacheScope !== "public" && m.cacheScope !== "private"));
|
|
104
|
+
if (bad.length === 0)
|
|
105
|
+
return [];
|
|
106
|
+
const where = [...new Set(bad.map(([w]) => w))];
|
|
107
|
+
return [
|
|
108
|
+
{
|
|
109
|
+
checkId: "PROTOCOL_MODERN_CACHE_FIELDS",
|
|
110
|
+
severity: "warn",
|
|
111
|
+
subject: where.join(", "),
|
|
112
|
+
message: `${MODERN} requires ttlMs (≥ 0) and cacheScope ("public" or "private") on ${where.join(", ")}, but they're missing or invalid (e.g. ttlMs=${JSON.stringify(bad[0][1].ttlMs ?? null)}, cacheScope=${JSON.stringify(bad[0][1].cacheScope ?? null)}). Clients can't tell how long to cache the list, or whether it's per-user.`,
|
|
113
|
+
source: `${SPEC_MODERN}/changelog`,
|
|
114
|
+
fix: 'Return e.g. ttlMs: 60000, cacheScope: "private" (use "private" when the list depends on who is authorized).',
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
},
|
|
118
|
+
}),
|
|
119
|
+
defineCheck({
|
|
120
|
+
id: "PROTOCOL_MODERN_SERVERINFO",
|
|
121
|
+
area: "protocol",
|
|
122
|
+
description: `${MODERN} results identify the server in _meta`,
|
|
123
|
+
appliesTo: modernSupported,
|
|
124
|
+
run: (s) => {
|
|
125
|
+
const missing = modernResults(s).filter(([, m]) => !m.serverInfo);
|
|
126
|
+
if (missing.length === 0)
|
|
127
|
+
return [];
|
|
128
|
+
return [
|
|
129
|
+
{
|
|
130
|
+
checkId: "PROTOCOL_MODERN_SERVERINFO",
|
|
131
|
+
severity: "info",
|
|
132
|
+
message: `Without initialize, results SHOULD carry _meta["io.modelcontextprotocol/serverInfo"]; ${missing.length} result(s) don't, so clients can't show which server answered.`,
|
|
133
|
+
source: `${SPEC_MODERN}/basic/index`,
|
|
134
|
+
},
|
|
135
|
+
];
|
|
136
|
+
},
|
|
137
|
+
}),
|
|
138
|
+
defineCheck({
|
|
139
|
+
id: "PROTOCOL_MODERN_VERSION_ERROR",
|
|
140
|
+
area: "protocol",
|
|
141
|
+
description: `${MODERN} servers reject unsupported versions with UnsupportedProtocolVersion (-32022)`,
|
|
142
|
+
appliesTo: (s) => modernSupported(s) && !!s.modern?.unsupportedVersion,
|
|
143
|
+
run: (s) => {
|
|
144
|
+
const r = s.modern.unsupportedVersion;
|
|
145
|
+
const data = r.data;
|
|
146
|
+
if (!r.answered && r.code === -32022 && Array.isArray(data?.supported))
|
|
147
|
+
return [];
|
|
148
|
+
return [
|
|
149
|
+
{
|
|
150
|
+
checkId: "PROTOCOL_MODERN_VERSION_ERROR",
|
|
151
|
+
severity: "warn",
|
|
152
|
+
message: r.answered
|
|
153
|
+
? "A request with an unsupported protocol version (1999-01-01) was answered normally. Clients rely on the -32022 error to retry with a version both sides support."
|
|
154
|
+
: r.code !== -32022
|
|
155
|
+
? `An unsupported protocol version got error ${r.code ?? "(none)"} ("${r.message}") instead of -32022, so clients won't know to retry with another version.`
|
|
156
|
+
: "The -32022 error has no data.supported list, so clients can't pick a version to retry with.",
|
|
157
|
+
evidence: { answered: r.answered, code: r.code, data: r.data },
|
|
158
|
+
source: `${SPEC_MODERN}/basic/versioning`,
|
|
159
|
+
fix: 'Answer unknown versions with { code: -32022, data: { supported: ["2026-07-28", ...], requested } }.',
|
|
160
|
+
},
|
|
161
|
+
];
|
|
162
|
+
},
|
|
163
|
+
}),
|
|
164
|
+
defineCheck({
|
|
165
|
+
id: "PROTOCOL_MODERN_SURFACE_DIFFERS",
|
|
166
|
+
area: "protocol",
|
|
167
|
+
description: `Tools are the same over the initialize handshake and ${MODERN}`,
|
|
168
|
+
appliesTo: (s) => s.era === "both" && !!s.modern?.lists?.tools?.ok && !!s.lists.tools?.ok,
|
|
169
|
+
run: (s) => {
|
|
170
|
+
const names = (items) => new Set(items.flatMap((t) => (typeof t.name === "string" ? [t.name] : [])));
|
|
171
|
+
const legacy = names(s.lists.tools.items);
|
|
172
|
+
const modern = names(s.modern.lists.tools.items);
|
|
173
|
+
const onlyLegacy = [...legacy].filter((n) => !modern.has(n));
|
|
174
|
+
const onlyModern = [...modern].filter((n) => !legacy.has(n));
|
|
175
|
+
if (!onlyLegacy.length && !onlyModern.length)
|
|
176
|
+
return [];
|
|
177
|
+
return [
|
|
178
|
+
{
|
|
179
|
+
checkId: "PROTOCOL_MODERN_SURFACE_DIFFERS",
|
|
180
|
+
severity: "info",
|
|
181
|
+
message: `Tool lists differ by protocol: only over initialize: ${onlyLegacy.join(", ") || "none"}; only over ${MODERN}: ${onlyModern.join(", ") || "none"}. Clients see different tools depending on which protocol they speak.`,
|
|
182
|
+
evidence: { onlyLegacy, onlyModern },
|
|
183
|
+
fix: "Expose the same tools on both, unless the difference is intentional.",
|
|
184
|
+
},
|
|
185
|
+
];
|
|
186
|
+
},
|
|
187
|
+
}),
|
|
188
|
+
defineCheck({
|
|
189
|
+
id: "PROTOCOL_VERSION_UNSUPPORTED",
|
|
190
|
+
area: "protocol",
|
|
191
|
+
description: "Negotiated protocol version is one the SDK supports",
|
|
192
|
+
appliesTo: legacyConnected,
|
|
193
|
+
run: (s) => {
|
|
194
|
+
const v = s.initialize?.negotiatedProtocolVersion;
|
|
195
|
+
if (v && SUPPORTED_PROTOCOL_VERSIONS.includes(v))
|
|
196
|
+
return [];
|
|
197
|
+
return [
|
|
198
|
+
{
|
|
199
|
+
checkId: "PROTOCOL_VERSION_UNSUPPORTED",
|
|
200
|
+
severity: "error",
|
|
201
|
+
message: v
|
|
202
|
+
? `Server answered with protocol version "${v}", which SDK-based clients reject.`
|
|
203
|
+
: "initialize result has no protocolVersion.",
|
|
204
|
+
evidence: { negotiated: v ?? null, supported: SUPPORTED_PROTOCOL_VERSIONS },
|
|
205
|
+
fix: `Return the client's requested version (${LATEST_PROTOCOL_VERSION}) if you support it, otherwise the latest version you do support.`,
|
|
206
|
+
},
|
|
207
|
+
];
|
|
208
|
+
},
|
|
209
|
+
}),
|
|
210
|
+
defineCheck({
|
|
211
|
+
id: "PROTOCOL_VERSION_OLD",
|
|
212
|
+
area: "protocol",
|
|
213
|
+
description: "Server speaks the latest protocol version",
|
|
214
|
+
appliesTo: (s) => legacyConnected(s) && SUPPORTED_PROTOCOL_VERSIONS.includes(s.initialize?.negotiatedProtocolVersion ?? ""),
|
|
215
|
+
run: (s) => {
|
|
216
|
+
const v = s.initialize.negotiatedProtocolVersion;
|
|
217
|
+
if (v === LATEST_PROTOCOL_VERSION)
|
|
218
|
+
return [];
|
|
219
|
+
return [
|
|
220
|
+
{
|
|
221
|
+
checkId: "PROTOCOL_VERSION_OLD",
|
|
222
|
+
severity: v.startsWith("2024-") ? "warn" : "info",
|
|
223
|
+
message: `Server negotiated ${v}; latest is ${LATEST_PROTOCOL_VERSION}. Features added in later spec revisions are unavailable to clients.`,
|
|
224
|
+
evidence: { negotiated: v, latest: LATEST_PROTOCOL_VERSION },
|
|
225
|
+
fix: upgradeHint(s),
|
|
226
|
+
},
|
|
227
|
+
];
|
|
228
|
+
},
|
|
229
|
+
}),
|
|
230
|
+
defineCheck({
|
|
231
|
+
id: "PROTOCOL_VERSIONS_REJECTED",
|
|
232
|
+
area: "protocol",
|
|
233
|
+
description: "Server handles every published protocol version clients may request (--version-matrix)",
|
|
234
|
+
appliesTo: (s) => connected(s) && !!s.versionMatrix?.length,
|
|
235
|
+
run: (s) => s.versionMatrix.flatMap((probe) => {
|
|
236
|
+
if (!probe.ok) {
|
|
237
|
+
return [
|
|
238
|
+
{
|
|
239
|
+
checkId: "PROTOCOL_VERSIONS_REJECTED",
|
|
240
|
+
severity: "warn",
|
|
241
|
+
subject: probe.requested,
|
|
242
|
+
message: `initialize with protocolVersion ${probe.requested} failed (${probe.error}). The spec says to answer with a version the server supports, so clients can decide; failing instead cuts off clients that start at ${probe.requested}.`,
|
|
243
|
+
fix: "On an unsupported version, respond with your latest supported version instead of an error.",
|
|
244
|
+
},
|
|
245
|
+
];
|
|
246
|
+
}
|
|
247
|
+
if (probe.negotiated && !SUPPORTED_PROTOCOL_VERSIONS.includes(probe.negotiated)) {
|
|
248
|
+
return [
|
|
249
|
+
{
|
|
250
|
+
checkId: "PROTOCOL_VERSIONS_REJECTED",
|
|
251
|
+
severity: "error",
|
|
252
|
+
subject: probe.requested,
|
|
253
|
+
message: `Asked for ${probe.requested}, server answered with unknown version "${probe.negotiated}".`,
|
|
254
|
+
fix: "Answer with a published protocol version.",
|
|
255
|
+
},
|
|
256
|
+
];
|
|
257
|
+
}
|
|
258
|
+
// Answering with an older version is correct negotiation; answering with a newer one
|
|
259
|
+
// (versions are dates, so they compare as strings) leaves an older client unable to talk.
|
|
260
|
+
if (probe.negotiated && probe.negotiated > probe.requested) {
|
|
261
|
+
return [
|
|
262
|
+
{
|
|
263
|
+
checkId: "PROTOCOL_VERSIONS_REJECTED",
|
|
264
|
+
severity: "info",
|
|
265
|
+
subject: probe.requested,
|
|
266
|
+
message: `Asked for ${probe.requested}, server answered the newer ${probe.negotiated}; clients that only speak ${probe.requested} will disconnect.`,
|
|
267
|
+
fix: `Support ${probe.requested} too if you need older clients (most SDKs do by default).`,
|
|
268
|
+
},
|
|
269
|
+
];
|
|
270
|
+
}
|
|
271
|
+
return [];
|
|
272
|
+
}),
|
|
273
|
+
}),
|
|
274
|
+
defineCheck({
|
|
275
|
+
id: "PROTOCOL_VERSION_SURFACE_DIFFERS",
|
|
276
|
+
area: "protocol",
|
|
277
|
+
description: "The tool list is the same whichever protocol version a client negotiates",
|
|
278
|
+
appliesTo: (s) => connected(s) && (s.versionMatrix?.filter((p) => p.tools).length ?? 0) > 1,
|
|
279
|
+
run: (s) => {
|
|
280
|
+
const probes = s.versionMatrix.filter((p) => p.tools);
|
|
281
|
+
const all = new Set(probes.flatMap((p) => p.tools));
|
|
282
|
+
return probes.flatMap((p) => {
|
|
283
|
+
const missing = [...all].filter((t) => !p.tools.includes(t));
|
|
284
|
+
if (missing.length === 0)
|
|
285
|
+
return [];
|
|
286
|
+
return [
|
|
287
|
+
{
|
|
288
|
+
checkId: "PROTOCOL_VERSION_SURFACE_DIFFERS",
|
|
289
|
+
severity: "info",
|
|
290
|
+
subject: p.requested,
|
|
291
|
+
message: `Clients negotiating ${p.negotiated ?? p.requested} don't get ${missing.length} tool(s) other versions get: ${missing.slice(0, 8).join(", ")}${missing.length > 8 ? ", …" : ""}.`,
|
|
292
|
+
evidence: { missing },
|
|
293
|
+
fix: "If intentional (features that need newer protocol), document it; otherwise expose the same tools on every version.",
|
|
294
|
+
},
|
|
295
|
+
];
|
|
296
|
+
});
|
|
297
|
+
},
|
|
298
|
+
}),
|
|
299
|
+
defineCheck({
|
|
300
|
+
id: "PROTOCOL_SERVERINFO_MISSING",
|
|
301
|
+
area: "protocol",
|
|
302
|
+
description: "initialize returns serverInfo with name and version",
|
|
303
|
+
appliesTo: legacyConnected,
|
|
304
|
+
run: (s) => {
|
|
305
|
+
const info = s.initialize?.serverInfo;
|
|
306
|
+
const missing = ["name", "version"].filter((k) => !str(info?.[k]));
|
|
307
|
+
if (missing.length === 0)
|
|
308
|
+
return [];
|
|
309
|
+
return [
|
|
310
|
+
{
|
|
311
|
+
checkId: "PROTOCOL_SERVERINFO_MISSING",
|
|
312
|
+
severity: "warn",
|
|
313
|
+
message: `serverInfo is missing ${missing.join(" and ")}.`,
|
|
314
|
+
fix: "Pass name and version when constructing the server.",
|
|
315
|
+
},
|
|
316
|
+
];
|
|
317
|
+
},
|
|
318
|
+
}),
|
|
319
|
+
defineCheck({
|
|
320
|
+
id: "PROTOCOL_CAPABILITY_UNDECLARED",
|
|
321
|
+
area: "protocol",
|
|
322
|
+
description: "Every feature the server serves is declared in capabilities",
|
|
323
|
+
appliesTo: connected,
|
|
324
|
+
run: (s) => KINDS.flatMap((kind) => {
|
|
325
|
+
const list = s.lists[kind];
|
|
326
|
+
const cap = LIST_KINDS[kind].capability;
|
|
327
|
+
if (!list?.ok || list.items.length === 0 || declared(s, cap))
|
|
328
|
+
return [];
|
|
329
|
+
return [
|
|
330
|
+
{
|
|
331
|
+
checkId: "PROTOCOL_CAPABILITY_UNDECLARED",
|
|
332
|
+
severity: "error",
|
|
333
|
+
subject: kind,
|
|
334
|
+
message: `Server answers ${LIST_KINDS[kind].method} with ${list.items.length} item(s) but doesn't declare the "${cap}" capability, so spec-following clients never ask for them.`,
|
|
335
|
+
fix: `Declare "${cap}": {} in the server capabilities.`,
|
|
336
|
+
},
|
|
337
|
+
];
|
|
338
|
+
}),
|
|
339
|
+
}),
|
|
340
|
+
defineCheck({
|
|
341
|
+
id: "PROTOCOL_CAPABILITY_BROKEN",
|
|
342
|
+
area: "protocol",
|
|
343
|
+
description: "Every declared capability's list method works",
|
|
344
|
+
appliesTo: connected,
|
|
345
|
+
run: (s) => KINDS.flatMap((kind) => {
|
|
346
|
+
const list = s.lists[kind];
|
|
347
|
+
const cap = LIST_KINDS[kind].capability;
|
|
348
|
+
if (!list || list.ok || !declared(s, cap))
|
|
349
|
+
return [];
|
|
350
|
+
// resources/templates/list is optional-ish in practice; many servers skip it.
|
|
351
|
+
const severity = kind === "resourceTemplates" ? "warn" : "error";
|
|
352
|
+
return [
|
|
353
|
+
{
|
|
354
|
+
checkId: "PROTOCOL_CAPABILITY_BROKEN",
|
|
355
|
+
severity,
|
|
356
|
+
subject: kind,
|
|
357
|
+
message: `"${cap}" is declared but ${LIST_KINDS[kind].method} failed: ${list.error?.message ?? "unknown error"}`,
|
|
358
|
+
evidence: { error: list.error },
|
|
359
|
+
fix: kind === "resourceTemplates"
|
|
360
|
+
? "Implement resources/templates/list (an empty list is fine)."
|
|
361
|
+
: `Implement ${LIST_KINDS[kind].method} or stop declaring "${cap}".`,
|
|
362
|
+
},
|
|
363
|
+
];
|
|
364
|
+
}),
|
|
365
|
+
}),
|
|
366
|
+
defineCheck({
|
|
367
|
+
id: "PROTOCOL_PAGINATION_BROKEN",
|
|
368
|
+
area: "protocol",
|
|
369
|
+
description: "List pagination terminates",
|
|
370
|
+
appliesTo: connected,
|
|
371
|
+
run: (s) => KINDS.filter((kind) => s.lists[kind]?.cursorLoop).map((kind) => ({
|
|
372
|
+
checkId: "PROTOCOL_PAGINATION_BROKEN",
|
|
373
|
+
severity: "error",
|
|
374
|
+
subject: kind,
|
|
375
|
+
message: `${LIST_KINDS[kind].method} returned a nextCursor it had already returned; clients loop forever or stop early.`,
|
|
376
|
+
fix: "Return a new cursor per page and omit nextCursor on the last page.",
|
|
377
|
+
})),
|
|
378
|
+
}),
|
|
379
|
+
];
|
|
380
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/checks/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 6570 syntax check. Returns undefined when valid, otherwise the problem.
|
|
3
|
+
* `fatal` marks errors the TypeScript SDK's own parser throws on.
|
|
4
|
+
*/
|
|
5
|
+
export declare function uriTemplateProblem(template: string): {
|
|
6
|
+
problem: string;
|
|
7
|
+
fatal: boolean;
|
|
8
|
+
} | undefined;
|
|
9
|
+
export declare const resourceChecks: import("./types.js").Check[];
|
|
10
|
+
//# sourceMappingURL=resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/checks/resources.ts"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAoBpG;AAED,eAAO,MAAM,cAAc,8BAqG1B,CAAC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { connected, itemLabel, items, str } from "./util.js";
|
|
2
|
+
import { defineCheck } from "./types.js";
|
|
3
|
+
const hasResources = (s) => connected(s) && items(s, "resources").length > 0;
|
|
4
|
+
const hasTemplates = (s) => connected(s) && items(s, "resourceTemplates").length > 0;
|
|
5
|
+
function parsesAsUri(value) {
|
|
6
|
+
try {
|
|
7
|
+
new URL(value);
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const VARSPEC = /^(?:[A-Za-z0-9_]|%[0-9A-Fa-f]{2})(?:\.?(?:[A-Za-z0-9_]|%[0-9A-Fa-f]{2}))*(?::[1-9][0-9]{0,3}|\*)?$/;
|
|
15
|
+
/**
|
|
16
|
+
* RFC 6570 syntax check. Returns undefined when valid, otherwise the problem.
|
|
17
|
+
* `fatal` marks errors the TypeScript SDK's own parser throws on.
|
|
18
|
+
*/
|
|
19
|
+
export function uriTemplateProblem(template) {
|
|
20
|
+
let depth = 0;
|
|
21
|
+
for (const ch of template) {
|
|
22
|
+
if (ch === "{")
|
|
23
|
+
depth++;
|
|
24
|
+
if (ch === "}")
|
|
25
|
+
depth--;
|
|
26
|
+
if (depth > 1)
|
|
27
|
+
return { problem: "nested '{'", fatal: false };
|
|
28
|
+
if (depth < 0)
|
|
29
|
+
return { problem: "unmatched '}'", fatal: false };
|
|
30
|
+
}
|
|
31
|
+
if (depth !== 0)
|
|
32
|
+
return { problem: "unclosed '{' expression", fatal: true };
|
|
33
|
+
for (const [, body] of template.matchAll(/\{([^}]*)\}/g)) {
|
|
34
|
+
const op = /^[+#./;?&]/.test(body) ? body[0] : "";
|
|
35
|
+
const vars = body.slice(op.length);
|
|
36
|
+
if (/^[=,!@|]/.test(vars))
|
|
37
|
+
return { problem: `reserved operator in {${body}}`, fatal: false };
|
|
38
|
+
if (vars === "")
|
|
39
|
+
return { problem: "empty expression {}", fatal: false };
|
|
40
|
+
for (const v of vars.split(",")) {
|
|
41
|
+
if (!VARSPEC.test(v))
|
|
42
|
+
return { problem: `invalid variable ${JSON.stringify(v)} in {${body}}`, fatal: false };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
export const resourceChecks = [
|
|
48
|
+
defineCheck({
|
|
49
|
+
id: "RESOURCE_URI_INVALID",
|
|
50
|
+
area: "resources",
|
|
51
|
+
description: "Resource URIs are absolute and parse",
|
|
52
|
+
appliesTo: hasResources,
|
|
53
|
+
run: (s) => items(s, "resources")
|
|
54
|
+
.filter((r) => typeof r.uri !== "string" || !parsesAsUri(r.uri))
|
|
55
|
+
.map((r) => ({
|
|
56
|
+
checkId: "RESOURCE_URI_INVALID",
|
|
57
|
+
severity: "error",
|
|
58
|
+
subject: itemLabel(r),
|
|
59
|
+
message: typeof r.uri !== "string"
|
|
60
|
+
? "Resource has no string uri."
|
|
61
|
+
: `${JSON.stringify(r.uri)} is not an absolute URI; clients can't read it back.`,
|
|
62
|
+
fix: "Use a scheme, e.g. file:///path or myapp://items/1.",
|
|
63
|
+
})),
|
|
64
|
+
}),
|
|
65
|
+
defineCheck({
|
|
66
|
+
id: "RESOURCE_URI_DUPLICATE",
|
|
67
|
+
area: "resources",
|
|
68
|
+
description: "Resource URIs are unique",
|
|
69
|
+
appliesTo: hasResources,
|
|
70
|
+
run: (s) => {
|
|
71
|
+
const counts = new Map();
|
|
72
|
+
for (const r of items(s, "resources")) {
|
|
73
|
+
if (typeof r.uri === "string")
|
|
74
|
+
counts.set(r.uri, (counts.get(r.uri) ?? 0) + 1);
|
|
75
|
+
}
|
|
76
|
+
return [...counts]
|
|
77
|
+
.filter(([, n]) => n > 1)
|
|
78
|
+
.map(([uri, n]) => ({
|
|
79
|
+
checkId: "RESOURCE_URI_DUPLICATE",
|
|
80
|
+
severity: "error",
|
|
81
|
+
subject: uri,
|
|
82
|
+
message: `${n} resources share the URI ${uri}.`,
|
|
83
|
+
fix: "Give every resource a unique URI.",
|
|
84
|
+
}));
|
|
85
|
+
},
|
|
86
|
+
}),
|
|
87
|
+
defineCheck({
|
|
88
|
+
id: "RESOURCE_NAME_MISSING",
|
|
89
|
+
area: "resources",
|
|
90
|
+
description: "Resources and templates have a name (required by the spec)",
|
|
91
|
+
appliesTo: (s) => hasResources(s) || hasTemplates(s),
|
|
92
|
+
run: (s) => [...items(s, "resources"), ...items(s, "resourceTemplates")]
|
|
93
|
+
.filter((r) => !str(r.name))
|
|
94
|
+
.map((r) => ({
|
|
95
|
+
checkId: "RESOURCE_NAME_MISSING",
|
|
96
|
+
severity: "error",
|
|
97
|
+
subject: itemLabel(r),
|
|
98
|
+
message: "Resource has no name; the spec requires one and the TypeScript SDK rejects the list.",
|
|
99
|
+
fix: "Add a short name to every resource and template.",
|
|
100
|
+
})),
|
|
101
|
+
}),
|
|
102
|
+
defineCheck({
|
|
103
|
+
id: "RESOURCE_MIME_MISSING",
|
|
104
|
+
area: "resources",
|
|
105
|
+
description: "Resources declare a mimeType",
|
|
106
|
+
appliesTo: hasResources,
|
|
107
|
+
run: (s) => {
|
|
108
|
+
const missing = items(s, "resources").filter((r) => !str(r.mimeType));
|
|
109
|
+
if (missing.length === 0)
|
|
110
|
+
return [];
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
checkId: "RESOURCE_MIME_MISSING",
|
|
114
|
+
severity: "info",
|
|
115
|
+
message: `${missing.length} resource(s) have no mimeType, so clients must guess how to display them.`,
|
|
116
|
+
evidence: { resources: missing.slice(0, 10).map((r) => itemLabel(r)) },
|
|
117
|
+
fix: "Set mimeType (e.g. text/markdown, application/json).",
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
defineCheck({
|
|
123
|
+
id: "RESOURCE_TEMPLATE_INVALID",
|
|
124
|
+
area: "resources",
|
|
125
|
+
description: "Resource templates are valid RFC 6570 URI templates",
|
|
126
|
+
appliesTo: hasTemplates,
|
|
127
|
+
run: (s) => items(s, "resourceTemplates").flatMap((t) => {
|
|
128
|
+
const template = str(t.uriTemplate);
|
|
129
|
+
const problem = template === undefined ? { problem: "missing uriTemplate", fatal: true } : uriTemplateProblem(template);
|
|
130
|
+
if (!problem)
|
|
131
|
+
return [];
|
|
132
|
+
return [
|
|
133
|
+
{
|
|
134
|
+
checkId: "RESOURCE_TEMPLATE_INVALID",
|
|
135
|
+
severity: problem.fatal ? "error" : "warn",
|
|
136
|
+
subject: itemLabel(t),
|
|
137
|
+
message: `uriTemplate ${JSON.stringify(template ?? null)}: ${problem.problem}.`,
|
|
138
|
+
fix: "Use RFC 6570 syntax, e.g. users://{id}/profile.",
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
}),
|
|
142
|
+
}),
|
|
143
|
+
];
|
|
144
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/checks/resources.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Meta-validates against the draft named in $schema (2020-12 by default, per the MCP spec). */
|
|
2
|
+
export declare function metaValidate(schema: Record<string, unknown>): string[] | undefined;
|
|
3
|
+
interface SchemaStats {
|
|
4
|
+
keywords: Set<string>;
|
|
5
|
+
depth: number;
|
|
6
|
+
untypedProperties: string[];
|
|
7
|
+
/** Paths of subschemas whose type is an array. */
|
|
8
|
+
typeArrays: string[];
|
|
9
|
+
}
|
|
10
|
+
/** Walks subschemas and collects keywords, nesting depth, and properties without a type. */
|
|
11
|
+
export declare function analyze(schema: unknown): SchemaStats;
|
|
12
|
+
/**
|
|
13
|
+
* Mirrors Cline's normalizeToolInputSchema (sdk/packages/shared/src/tools/create.ts @ 252082b):
|
|
14
|
+
* schemas with a string `type`, or with properties/required/additionalProperties, pass.
|
|
15
|
+
* Otherwise the first non-empty root oneOf/anyOf/allOf decides: oneOf/anyOf need every
|
|
16
|
+
* branch to be `type: "object"`, allOf needs at least one such branch.
|
|
17
|
+
*/
|
|
18
|
+
export declare function rootCombinatorBreaks(schema: Record<string, unknown>): boolean;
|
|
19
|
+
export declare const schemaChecks: import("./types.js").Check[];
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/checks/schema.ts"],"names":[],"mappings":"AAsBA,gGAAgG;AAChG,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,SAAS,CAOlF;AAED,UAAU,WAAW;IACnB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,kDAAkD;IAClD,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,4FAA4F;AAC5F,wBAAgB,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,WAAW,CA0BpD;AAgBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAU7E;AAMD,eAAO,MAAM,YAAY,8BAwUxB,CAAC"}
|