@causari/mcp-server 0.1.2 → 0.1.4
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 +34 -0
- package/NOTICE +1 -1
- package/README.md +3 -3
- package/dist/{chunk-P2UAUQ4G.js → chunk-HQIPIA5N.js} +20 -6
- package/dist/{chunk-7XWPOH6R.js → chunk-KBU67SEH.js} +1201 -85
- package/dist/cli.js +32 -23
- package/dist/index.d.ts +247 -3
- package/dist/index.js +10 -3
- package/dist/smoke.js +142 -168
- package/package.json +7 -5
- package/dist/cli.d.ts +0 -17
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/server.d.ts +0 -12
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -64
- package/dist/server.js.map +0 -1
- package/dist/smoke.d.ts +0 -6
- package/dist/smoke.d.ts.map +0 -1
- package/dist/smoke.js.map +0 -1
- package/dist/tools.d.ts +0 -27
- package/dist/tools.d.ts.map +0 -1
- package/dist/tools.js +0 -306
- package/dist/tools.js.map +0 -1
- package/dist/validate.d.ts +0 -53
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js +0 -126
- package/dist/validate.js.map +0 -1
- package/dist/version.d.ts +0 -13
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -13
- package/dist/version.js.map +0 -1
- package/dist/worker.d.ts +0 -25
- package/dist/worker.d.ts.map +0 -1
- package/dist/worker.js +0 -261
- package/dist/worker.js.map +0 -1
package/dist/validate.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Input validation for MCP tool arguments.
|
|
3
|
-
*
|
|
4
|
-
* MCP clients are LLM-driven and can send malformed arguments — wrong types,
|
|
5
|
-
* NaN, out-of-range numbers, empty required strings. The JSON schema advertised
|
|
6
|
-
* in tools/list is advisory; clients are not required to enforce it. So we
|
|
7
|
-
* validate at the handler boundary and return a clear, agent-readable error
|
|
8
|
-
* instead of letting a bad value reach the query engine.
|
|
9
|
-
*
|
|
10
|
-
* Validators throw {@link ValidationError}; tool handlers let it propagate to
|
|
11
|
-
* the transport layer, which converts it into an MCP isError tool result with
|
|
12
|
-
* a remediation hint.
|
|
13
|
-
*/
|
|
14
|
-
const DOMAINS = [
|
|
15
|
-
'technology', 'humanities', 'systems', 'science', 'economy',
|
|
16
|
-
'geopolitics', 'philosophy', 'environment', 'culture', 'health', 'other',
|
|
17
|
-
];
|
|
18
|
-
/** Thrown when a tool argument fails validation. Message is agent-facing. */
|
|
19
|
-
export class ValidationError extends Error {
|
|
20
|
-
constructor(message) {
|
|
21
|
-
super(message);
|
|
22
|
-
this.name = 'ValidationError';
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Require a non-empty string. Trims; rejects empty/whitespace-only.
|
|
27
|
-
*/
|
|
28
|
-
export function requireString(value, field) {
|
|
29
|
-
if (typeof value !== 'string') {
|
|
30
|
-
throw new ValidationError(`"${field}" must be a string, got ${typeName(value)}.`);
|
|
31
|
-
}
|
|
32
|
-
const trimmed = value.trim();
|
|
33
|
-
if (trimmed.length === 0) {
|
|
34
|
-
throw new ValidationError(`"${field}" must not be empty.`);
|
|
35
|
-
}
|
|
36
|
-
return trimmed;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Optional finite number within [min, max]. Returns undefined when absent.
|
|
40
|
-
* Rejects NaN, Infinity, and non-number types so they never reach the query layer.
|
|
41
|
-
*/
|
|
42
|
-
export function optionalNumber(value, field, opts = {}) {
|
|
43
|
-
if (value === undefined || value === null)
|
|
44
|
-
return undefined;
|
|
45
|
-
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
46
|
-
throw new ValidationError(`"${field}" must be a finite number, got ${typeName(value)}.`);
|
|
47
|
-
}
|
|
48
|
-
if (opts.integer && !Number.isInteger(value)) {
|
|
49
|
-
throw new ValidationError(`"${field}" must be an integer, got ${value}.`);
|
|
50
|
-
}
|
|
51
|
-
if (opts.min !== undefined && value < opts.min) {
|
|
52
|
-
throw new ValidationError(`"${field}" must be >= ${opts.min}, got ${value}.`);
|
|
53
|
-
}
|
|
54
|
-
if (opts.max !== undefined && value > opts.max) {
|
|
55
|
-
throw new ValidationError(`"${field}" must be <= ${opts.max}, got ${value}.`);
|
|
56
|
-
}
|
|
57
|
-
return value;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Optional array of domain enum values. Returns undefined when absent.
|
|
61
|
-
* Rejects non-arrays and unknown domain strings.
|
|
62
|
-
*/
|
|
63
|
-
export function optionalDomains(value, field = 'domains') {
|
|
64
|
-
if (value === undefined || value === null)
|
|
65
|
-
return undefined;
|
|
66
|
-
if (!Array.isArray(value)) {
|
|
67
|
-
throw new ValidationError(`"${field}" must be an array of domain strings.`);
|
|
68
|
-
}
|
|
69
|
-
for (const d of value) {
|
|
70
|
-
if (typeof d !== 'string' || !DOMAINS.includes(d)) {
|
|
71
|
-
throw new ValidationError(`"${field}" contains invalid domain ${JSON.stringify(d)}. ` +
|
|
72
|
-
`Valid domains: ${DOMAINS.join(', ')}.`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return value;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Required non-empty array of non-empty strings. Used for free-text list inputs
|
|
79
|
-
* (e.g. predict_scenarios.conditions).
|
|
80
|
-
*/
|
|
81
|
-
export function requireStringArray(value, field) {
|
|
82
|
-
if (!Array.isArray(value)) {
|
|
83
|
-
throw new ValidationError(`"${field}" must be an array of strings.`);
|
|
84
|
-
}
|
|
85
|
-
if (value.length === 0) {
|
|
86
|
-
throw new ValidationError(`"${field}" must contain at least one item.`);
|
|
87
|
-
}
|
|
88
|
-
const out = [];
|
|
89
|
-
for (const item of value) {
|
|
90
|
-
if (typeof item !== 'string' || item.trim().length === 0) {
|
|
91
|
-
throw new ValidationError(`"${field}" items must be non-empty strings.`);
|
|
92
|
-
}
|
|
93
|
-
out.push(item.trim());
|
|
94
|
-
}
|
|
95
|
-
return out;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Optional one-of enum string. Returns the value if valid, undefined if absent.
|
|
99
|
-
*/
|
|
100
|
-
export function optionalEnum(value, field, allowed) {
|
|
101
|
-
if (value === undefined || value === null)
|
|
102
|
-
return undefined;
|
|
103
|
-
if (typeof value !== 'string' || !allowed.includes(value)) {
|
|
104
|
-
throw new ValidationError(`"${field}" must be one of: ${allowed.join(', ')}. Got ${JSON.stringify(value)}.`);
|
|
105
|
-
}
|
|
106
|
-
return value;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Optional non-empty string. Returns undefined when absent, but rejects
|
|
110
|
-
* present-but-empty (a likely client bug worth surfacing).
|
|
111
|
-
*/
|
|
112
|
-
export function optionalString(value, field) {
|
|
113
|
-
if (value === undefined || value === null)
|
|
114
|
-
return undefined;
|
|
115
|
-
return requireString(value, field);
|
|
116
|
-
}
|
|
117
|
-
function typeName(value) {
|
|
118
|
-
if (value === null)
|
|
119
|
-
return 'null';
|
|
120
|
-
if (Array.isArray(value))
|
|
121
|
-
return 'array';
|
|
122
|
-
if (typeof value === 'number' && Number.isNaN(value))
|
|
123
|
-
return 'NaN';
|
|
124
|
-
return typeof value;
|
|
125
|
-
}
|
|
126
|
-
//# sourceMappingURL=validate.js.map
|
package/dist/validate.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,OAAO,GAAG;IACd,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS;IAC3D,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO;CAChE,CAAC;AAIX,6EAA6E;AAC7E,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,KAAa;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,2BAA2B,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,sBAAsB,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAc,EACd,KAAa,EACb,OAA0D,EAAE;IAE5D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,kCAAkC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3F,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,6BAA6B,KAAK,GAAG,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/C,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,GAAG,SAAS,KAAK,GAAG,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/C,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,GAAG,SAAS,KAAK,GAAG,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc,EAAE,KAAK,GAAG,SAAS;IAC/D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,uCAAuC,CAAC,CAAC;IAC9E,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAgB,CAAC,EAAE,CAAC;YACjE,MAAM,IAAI,eAAe,CACvB,IAAI,KAAK,6BAA6B,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;gBAC3D,kBAAkB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACxC,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,KAAsB,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAc,EAAE,KAAa;IAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,gCAAgC,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,mCAAmC,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,oCAAoC,CAAC,CAAC;QAC3E,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAc,EACd,KAAa,EACb,OAAqB;IAErB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAU,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,eAAe,CACvB,IAAI,KAAK,qBAAqB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAClF,CAAC;IACJ,CAAC;IACD,OAAO,KAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,KAAa;IAC1D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5D,OAAO,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnE,OAAO,OAAO,KAAK,CAAC;AACtB,CAAC"}
|
package/dist/version.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Single source of truth for the server version.
|
|
3
|
-
*
|
|
4
|
-
* Kept in sync with package.json "version" manually on release. Imported by
|
|
5
|
-
* cli/server/worker so the version is reported identically across stdio +
|
|
6
|
-
* HTTP transports, the health endpoint, and the discovery manifest.
|
|
7
|
-
*/
|
|
8
|
-
export declare const VERSION = "0.1.2";
|
|
9
|
-
/** Protocol version this server implements (MCP spec revision). */
|
|
10
|
-
export declare const MCP_PROTOCOL_VERSION = "2024-11-05";
|
|
11
|
-
/** Stable server identifier reported in serverInfo + health. */
|
|
12
|
-
export declare const SERVER_NAME = "causari-mcp-server";
|
|
13
|
-
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,mEAAmE;AACnE,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAEjD,gEAAgE;AAChE,eAAO,MAAM,WAAW,uBAAuB,CAAC"}
|
package/dist/version.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Single source of truth for the server version.
|
|
3
|
-
*
|
|
4
|
-
* Kept in sync with package.json "version" manually on release. Imported by
|
|
5
|
-
* cli/server/worker so the version is reported identically across stdio +
|
|
6
|
-
* HTTP transports, the health endpoint, and the discovery manifest.
|
|
7
|
-
*/
|
|
8
|
-
export const VERSION = '0.1.2';
|
|
9
|
-
/** Protocol version this server implements (MCP spec revision). */
|
|
10
|
-
export const MCP_PROTOCOL_VERSION = '2024-11-05';
|
|
11
|
-
/** Stable server identifier reported in serverInfo + health. */
|
|
12
|
-
export const SERVER_NAME = 'causari-mcp-server';
|
|
13
|
-
//# sourceMappingURL=version.js.map
|
package/dist/version.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,mEAAmE;AACnE,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAY,CAAC;AAEjD,gEAAgE;AAChE,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,CAAC"}
|
package/dist/worker.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Causari MCP Server — Cloudflare Worker HTTP transport.
|
|
3
|
-
*
|
|
4
|
-
* Implements the MCP "Streamable HTTP" transport as a stateless JSON-RPC endpoint.
|
|
5
|
-
* Each POST /mcp is one request-response cycle — no session state required since
|
|
6
|
-
* all Causari tools are read-only queries against the in-memory CKGStore.
|
|
7
|
-
*
|
|
8
|
-
* Routes:
|
|
9
|
-
* POST /mcp — MCP JSON-RPC endpoint
|
|
10
|
-
* GET / — Info page (server stats + install docs)
|
|
11
|
-
* GET /health — Health check
|
|
12
|
-
* GET /.well-known/mcp.json — MCP server discovery manifest
|
|
13
|
-
* OPTIONS * — CORS preflight
|
|
14
|
-
*
|
|
15
|
-
* Auth: if CAUSARI_API_KEY env var is set, require Authorization: Bearer <key>.
|
|
16
|
-
* Rate limiting: handled by Cloudflare Workers platform.
|
|
17
|
-
*/
|
|
18
|
-
interface Env {
|
|
19
|
-
CAUSARI_API_KEY?: string;
|
|
20
|
-
}
|
|
21
|
-
declare const _default: {
|
|
22
|
-
fetch(request: Request, env: Env): Promise<Response>;
|
|
23
|
-
};
|
|
24
|
-
export default _default;
|
|
25
|
-
//# sourceMappingURL=worker.d.ts.map
|
package/dist/worker.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAgBH,UAAU,GAAG;IACX,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;;mBA6PsB,OAAO,OAAO,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;;AAD5D,wBA2BE"}
|
package/dist/worker.js
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Causari MCP Server — Cloudflare Worker HTTP transport.
|
|
3
|
-
*
|
|
4
|
-
* Implements the MCP "Streamable HTTP" transport as a stateless JSON-RPC endpoint.
|
|
5
|
-
* Each POST /mcp is one request-response cycle — no session state required since
|
|
6
|
-
* all Causari tools are read-only queries against the in-memory CKGStore.
|
|
7
|
-
*
|
|
8
|
-
* Routes:
|
|
9
|
-
* POST /mcp — MCP JSON-RPC endpoint
|
|
10
|
-
* GET / — Info page (server stats + install docs)
|
|
11
|
-
* GET /health — Health check
|
|
12
|
-
* GET /.well-known/mcp.json — MCP server discovery manifest
|
|
13
|
-
* OPTIONS * — CORS preflight
|
|
14
|
-
*
|
|
15
|
-
* Auth: if CAUSARI_API_KEY env var is set, require Authorization: Bearer <key>.
|
|
16
|
-
* Rate limiting: handled by Cloudflare Workers platform.
|
|
17
|
-
*/
|
|
18
|
-
import { CKGStore, loadSeed } from '@causari/ckg';
|
|
19
|
-
import { ALL_TOOLS } from './tools.js';
|
|
20
|
-
import { ValidationError } from './validate.js';
|
|
21
|
-
import { VERSION, MCP_PROTOCOL_VERSION, SERVER_NAME } from './version.js';
|
|
22
|
-
// Module-level singleton — initialized once per Worker isolate, shared across requests.
|
|
23
|
-
const store = new CKGStore(loadSeed());
|
|
24
|
-
const ckgStats = store.stats();
|
|
25
|
-
// Reject oversized bodies before parsing — tool args are tiny; anything large is abuse.
|
|
26
|
-
const MAX_BODY_BYTES = 64 * 1024;
|
|
27
|
-
// ── CORS ─────────────────────────────────────────────────────────────────────
|
|
28
|
-
const CORS_HEADERS = {
|
|
29
|
-
'Access-Control-Allow-Origin': '*',
|
|
30
|
-
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
31
|
-
'Access-Control-Allow-Headers': 'Content-Type, Authorization, Mcp-Session-Id',
|
|
32
|
-
'Access-Control-Max-Age': '86400',
|
|
33
|
-
};
|
|
34
|
-
function corsJson(body, status = 200) {
|
|
35
|
-
return new Response(JSON.stringify(body), {
|
|
36
|
-
status,
|
|
37
|
-
headers: { 'Content-Type': 'application/json', ...CORS_HEADERS },
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
function jsonRpcError(id, code, message) {
|
|
41
|
-
return corsJson({ jsonrpc: '2.0', id: id ?? null, error: { code, message } });
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* A tool-level error — returned inside a successful JSON-RPC result with isError:true,
|
|
45
|
-
* per the MCP spec, so the agent can read the message and self-correct rather than
|
|
46
|
-
* seeing a transport-level failure.
|
|
47
|
-
*/
|
|
48
|
-
function toolError(id, text) {
|
|
49
|
-
return corsJson({
|
|
50
|
-
jsonrpc: '2.0',
|
|
51
|
-
id: id ?? null,
|
|
52
|
-
result: { content: [{ type: 'text', text }], isError: true },
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
// ── Auth ─────────────────────────────────────────────────────────────────────
|
|
56
|
-
function checkAuth(req, env) {
|
|
57
|
-
if (!env.CAUSARI_API_KEY)
|
|
58
|
-
return true; // no key configured = open
|
|
59
|
-
const header = req.headers.get('Authorization') ?? '';
|
|
60
|
-
const token = header.startsWith('Bearer ') ? header.slice(7) : '';
|
|
61
|
-
// NOTE: plain `===` is not constant-time. Acceptable for the current single
|
|
62
|
-
// shared key on Workers' isolated runtime; upgrade to crypto.subtle.timingSafeEqual
|
|
63
|
-
// when per-tenant keys + rate limiting land (Pro tier, see README roadmap).
|
|
64
|
-
return token === env.CAUSARI_API_KEY;
|
|
65
|
-
}
|
|
66
|
-
// ── MCP JSON-RPC handler ──────────────────────────────────────────────────────
|
|
67
|
-
async function handleMcp(req, env) {
|
|
68
|
-
if (!checkAuth(req, env)) {
|
|
69
|
-
return jsonRpcError(null, -32000, 'Unauthorized — provide Authorization: Bearer <api_key>');
|
|
70
|
-
}
|
|
71
|
-
// Content-Type must be JSON. Browsers/CDNs sometimes send text/plain; accept it
|
|
72
|
-
// leniently only if it parses, but reject obviously-wrong types early.
|
|
73
|
-
const contentType = req.headers.get('Content-Type') ?? '';
|
|
74
|
-
if (contentType && !contentType.includes('application/json') && !contentType.includes('text/plain')) {
|
|
75
|
-
return jsonRpcError(null, -32700, `Unsupported Content-Type "${contentType}" — send application/json`);
|
|
76
|
-
}
|
|
77
|
-
// Size guard — reject oversized bodies before reading them into memory.
|
|
78
|
-
const declaredLength = Number(req.headers.get('Content-Length') ?? '0');
|
|
79
|
-
if (Number.isFinite(declaredLength) && declaredLength > MAX_BODY_BYTES) {
|
|
80
|
-
return jsonRpcError(null, -32600, `Request body too large (max ${MAX_BODY_BYTES} bytes)`);
|
|
81
|
-
}
|
|
82
|
-
const raw = await req.text();
|
|
83
|
-
if (raw.length > MAX_BODY_BYTES) {
|
|
84
|
-
return jsonRpcError(null, -32600, `Request body too large (max ${MAX_BODY_BYTES} bytes)`);
|
|
85
|
-
}
|
|
86
|
-
let body;
|
|
87
|
-
try {
|
|
88
|
-
body = JSON.parse(raw);
|
|
89
|
-
}
|
|
90
|
-
catch {
|
|
91
|
-
return jsonRpcError(null, -32700, 'Parse error — request body must be JSON');
|
|
92
|
-
}
|
|
93
|
-
// Reject batch requests explicitly — this stateless server handles one call per POST.
|
|
94
|
-
if (Array.isArray(body)) {
|
|
95
|
-
return jsonRpcError(null, -32600, 'Batch requests are not supported — send one JSON-RPC request per POST');
|
|
96
|
-
}
|
|
97
|
-
if (typeof body !== 'object' || body === null || typeof body.method !== 'string') {
|
|
98
|
-
return jsonRpcError(body?.id ?? null, -32600, 'Invalid request — missing or non-string "method"');
|
|
99
|
-
}
|
|
100
|
-
const { method, params, id } = body;
|
|
101
|
-
try {
|
|
102
|
-
if (method === 'initialize') {
|
|
103
|
-
return corsJson({
|
|
104
|
-
jsonrpc: '2.0',
|
|
105
|
-
id,
|
|
106
|
-
result: {
|
|
107
|
-
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
108
|
-
capabilities: { tools: {} },
|
|
109
|
-
serverInfo: { name: SERVER_NAME, version: VERSION },
|
|
110
|
-
instructions: 'Causari MCP Server provides access to a curated Causal Knowledge Graph with ' +
|
|
111
|
-
`${ckgStats.eventCount} events and ${ckgStats.causalLinkCount} causal links across technology history. ` +
|
|
112
|
-
'Use causal_chain to trace cause-effect relationships, query_events for discovery, ' +
|
|
113
|
-
'historical_resonance for analogies, and predict_scenarios for strategic planning.',
|
|
114
|
-
},
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
if (method === 'notifications/initialized') {
|
|
118
|
-
// Notification — no response body per spec
|
|
119
|
-
return new Response(null, { status: 204, headers: CORS_HEADERS });
|
|
120
|
-
}
|
|
121
|
-
if (method === 'tools/list') {
|
|
122
|
-
return corsJson({
|
|
123
|
-
jsonrpc: '2.0',
|
|
124
|
-
id,
|
|
125
|
-
result: {
|
|
126
|
-
tools: ALL_TOOLS.map((t) => ({
|
|
127
|
-
name: t.name,
|
|
128
|
-
description: t.description,
|
|
129
|
-
inputSchema: t.inputSchema,
|
|
130
|
-
})),
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
if (method === 'tools/call') {
|
|
135
|
-
const toolName = (params?.name ?? '');
|
|
136
|
-
const rawArgs = params?.arguments;
|
|
137
|
-
// Arguments must be an object (or absent). Reject arrays/scalars early.
|
|
138
|
-
if (rawArgs !== undefined && (typeof rawArgs !== 'object' || rawArgs === null || Array.isArray(rawArgs))) {
|
|
139
|
-
return toolError(id, 'Invalid params: "arguments" must be an object');
|
|
140
|
-
}
|
|
141
|
-
const toolArgs = (rawArgs ?? {});
|
|
142
|
-
const tool = ALL_TOOLS.find((t) => t.name === toolName);
|
|
143
|
-
if (!tool) {
|
|
144
|
-
return toolError(id, `Unknown tool: ${toolName || '(none)'}. Available: ${ALL_TOOLS.map((t) => t.name).join(', ')}`);
|
|
145
|
-
}
|
|
146
|
-
try {
|
|
147
|
-
const result = tool.handler(toolArgs, store);
|
|
148
|
-
return corsJson({
|
|
149
|
-
jsonrpc: '2.0',
|
|
150
|
-
id,
|
|
151
|
-
result: {
|
|
152
|
-
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
catch (err) {
|
|
157
|
-
// ValidationError = caller's bad args → return as a tool error result (isError)
|
|
158
|
-
// so the agent sees the remediation message and can retry, not a transport fault.
|
|
159
|
-
if (err instanceof ValidationError) {
|
|
160
|
-
return toolError(id, `Invalid arguments: ${err.message}`);
|
|
161
|
-
}
|
|
162
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
163
|
-
return toolError(id, `Tool execution failed: ${message}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
if (method === 'ping') {
|
|
167
|
-
return corsJson({ jsonrpc: '2.0', id, result: {} });
|
|
168
|
-
}
|
|
169
|
-
return jsonRpcError(id, -32601, `Method not found: ${method}`);
|
|
170
|
-
}
|
|
171
|
-
catch (err) {
|
|
172
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
173
|
-
return jsonRpcError(id, -32603, `Internal error: ${message}`);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
// ── Health ────────────────────────────────────────────────────────────────────
|
|
177
|
-
function handleHealth() {
|
|
178
|
-
return corsJson({
|
|
179
|
-
status: 'ok',
|
|
180
|
-
server: SERVER_NAME,
|
|
181
|
-
version: VERSION,
|
|
182
|
-
ckg: {
|
|
183
|
-
events: ckgStats.eventCount,
|
|
184
|
-
links: ckgStats.causalLinkCount,
|
|
185
|
-
},
|
|
186
|
-
transport: 'http-stateless',
|
|
187
|
-
protocol: MCP_PROTOCOL_VERSION,
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
// ── Discovery manifest ────────────────────────────────────────────────────────
|
|
191
|
-
function handleDiscovery(url) {
|
|
192
|
-
const base = `${url.protocol}//${url.host}`;
|
|
193
|
-
return corsJson({
|
|
194
|
-
name: 'Causari MCP Server',
|
|
195
|
-
description: 'Causal Knowledge Graph — trace cause-effect chains across tech history',
|
|
196
|
-
version: VERSION,
|
|
197
|
-
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
198
|
-
endpoint: `${base}/mcp`,
|
|
199
|
-
tools: ALL_TOOLS.map((t) => ({ name: t.name, description: t.description })),
|
|
200
|
-
contact: 'https://causari.ai',
|
|
201
|
-
docs: 'https://github.com/causari/mcp-server',
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
// ── Root info page ────────────────────────────────────────────────────────────
|
|
205
|
-
function handleRoot(url) {
|
|
206
|
-
const base = `${url.protocol}//${url.host}`;
|
|
207
|
-
const body = `# Causari MCP Server
|
|
208
|
-
|
|
209
|
-
Causal Knowledge Graph — ${ckgStats.eventCount} events · ${ckgStats.causalLinkCount} causal links
|
|
210
|
-
|
|
211
|
-
## Endpoints
|
|
212
|
-
|
|
213
|
-
POST ${base}/mcp — MCP JSON-RPC (Streamable HTTP transport)
|
|
214
|
-
GET ${base}/health — Health + CKG stats
|
|
215
|
-
GET ${base}/.well-known/mcp.json — Discovery manifest
|
|
216
|
-
|
|
217
|
-
## Tools
|
|
218
|
-
|
|
219
|
-
${ALL_TOOLS.map((t) => `- ${t.name}: ${t.description.slice(0, 80)}...`).join('\n')}
|
|
220
|
-
|
|
221
|
-
## Configure in Claude Desktop
|
|
222
|
-
|
|
223
|
-
{
|
|
224
|
-
"mcpServers": {
|
|
225
|
-
"causari": {
|
|
226
|
-
"url": "${base}/mcp"
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
## Docs
|
|
232
|
-
https://causari.ai · https://github.com/causari/mcp-server
|
|
233
|
-
`;
|
|
234
|
-
return new Response(body, {
|
|
235
|
-
headers: { 'Content-Type': 'text/plain; charset=utf-8', ...CORS_HEADERS },
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
// ── Main fetch handler ────────────────────────────────────────────────────────
|
|
239
|
-
export default {
|
|
240
|
-
async fetch(request, env) {
|
|
241
|
-
const url = new URL(request.url);
|
|
242
|
-
const method = request.method.toUpperCase();
|
|
243
|
-
if (method === 'OPTIONS') {
|
|
244
|
-
return new Response(null, { status: 204, headers: CORS_HEADERS });
|
|
245
|
-
}
|
|
246
|
-
if (url.pathname === '/health' && method === 'GET') {
|
|
247
|
-
return handleHealth();
|
|
248
|
-
}
|
|
249
|
-
if (url.pathname === '/.well-known/mcp.json' && method === 'GET') {
|
|
250
|
-
return handleDiscovery(url);
|
|
251
|
-
}
|
|
252
|
-
if (url.pathname === '/mcp' && method === 'POST') {
|
|
253
|
-
return handleMcp(request, env);
|
|
254
|
-
}
|
|
255
|
-
if (url.pathname === '/' && method === 'GET') {
|
|
256
|
-
return handleRoot(url);
|
|
257
|
-
}
|
|
258
|
-
return new Response('Not Found', { status: 404, headers: CORS_HEADERS });
|
|
259
|
-
},
|
|
260
|
-
};
|
|
261
|
-
//# sourceMappingURL=worker.js.map
|
package/dist/worker.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE1E,wFAAwF;AACxF,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;AACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;AAE/B,wFAAwF;AACxF,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,CAAC;AAejC,gFAAgF;AAEhF,MAAM,YAAY,GAAG;IACnB,6BAA6B,EAAE,GAAG;IAClC,8BAA8B,EAAE,oBAAoB;IACpD,8BAA8B,EAAE,6CAA6C;IAC7E,wBAAwB,EAAE,OAAO;CAClC,CAAC;AAEF,SAAS,QAAQ,CAAC,IAAa,EAAE,MAAM,GAAG,GAAG;IAC3C,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QACxC,MAAM;QACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,YAAY,EAAE;KACjE,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,EAAsC,EAAE,IAAY,EAAE,OAAe;IACzF,OAAO,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;AAChF,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS,CAAC,EAAsC,EAAE,IAAY;IACrE,OAAO,QAAQ,CAAC;QACd,OAAO,EAAE,KAAK;QACd,EAAE,EAAE,EAAE,IAAI,IAAI;QACd,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE;KAC7D,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAEhF,SAAS,SAAS,CAAC,GAAY,EAAE,GAAQ;IACvC,IAAI,CAAC,GAAG,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC,CAAC,2BAA2B;IAClE,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;IACtD,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,4EAA4E;IAC5E,oFAAoF;IACpF,4EAA4E;IAC5E,OAAO,KAAK,KAAK,GAAG,CAAC,eAAe,CAAC;AACvC,CAAC;AAED,iFAAiF;AAEjF,KAAK,UAAU,SAAS,CAAC,GAAY,EAAE,GAAQ;IAC7C,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,wDAAwD,CAAC,CAAC;IAC9F,CAAC;IAED,gFAAgF;IAChF,uEAAuE;IACvE,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAC1D,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACpG,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,6BAA6B,WAAW,2BAA2B,CAAC,CAAC;IACzG,CAAC;IAED,wEAAwE;IACxE,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,CAAC;IACxE,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,cAAc,EAAE,CAAC;QACvE,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,+BAA+B,cAAc,SAAS,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,GAAG,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;QAChC,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,+BAA+B,cAAc,SAAS,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,IAAoB,CAAC;IACzB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,yCAAyC,CAAC,CAAC;IAC/E,CAAC;IAED,sFAAsF;IACtF,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,uEAAuE,CAAC,CAAC;IAC7G,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACjF,OAAO,YAAY,CAAC,IAAI,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,KAAK,EAAE,kDAAkD,CAAC,CAAC;IACpG,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;IAEpC,IAAI,CAAC;QACH,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;gBACd,OAAO,EAAE,KAAK;gBACd,EAAE;gBACF,MAAM,EAAE;oBACN,eAAe,EAAE,oBAAoB;oBACrC,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;oBAC3B,UAAU,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE;oBACnD,YAAY,EACV,8EAA8E;wBAC9E,GAAG,QAAQ,CAAC,UAAU,eAAe,QAAQ,CAAC,eAAe,2CAA2C;wBACxG,oFAAoF;wBACpF,mFAAmF;iBACtF;aACF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,MAAM,KAAK,2BAA2B,EAAE,CAAC;YAC3C,2CAA2C;YAC3C,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;gBACd,OAAO,EAAE,KAAK;gBACd,EAAE;gBACF,MAAM,EAAE;oBACN,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,WAAW,EAAE,CAAC,CAAC,WAAW;wBAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;qBAC3B,CAAC,CAAC;iBACJ;aACF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAW,CAAC;YAChD,MAAM,OAAO,GAAG,MAAM,EAAE,SAAS,CAAC;YAClC,wEAAwE;YACxE,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;gBACzG,OAAO,SAAS,CAAC,EAAE,EAAE,+CAA+C,CAAC,CAAC;YACxE,CAAC;YACD,MAAM,QAAQ,GAAG,CAAC,OAAO,IAAI,EAAE,CAA4B,CAAC;YAE5D,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;YACxD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,SAAS,CACd,EAAE,EACF,iBAAiB,QAAQ,IAAI,QAAQ,gBAAgB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/F,CAAC;YACJ,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBAC7C,OAAO,QAAQ,CAAC;oBACd,OAAO,EAAE,KAAK;oBACd,EAAE;oBACF,MAAM,EAAE;wBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;qBACnE;iBACF,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,gFAAgF;gBAChF,kFAAkF;gBAClF,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;oBACnC,OAAO,SAAS,CAAC,EAAE,EAAE,sBAAsB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC5D,CAAC;gBACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACjE,OAAO,SAAS,CAAC,EAAE,EAAE,0BAA0B,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,OAAO,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,YAAY,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,qBAAqB,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,YAAY,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,mBAAmB,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF,SAAS,YAAY;IACnB,OAAO,QAAQ,CAAC;QACd,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,WAAW;QACnB,OAAO,EAAE,OAAO;QAChB,GAAG,EAAE;YACH,MAAM,EAAE,QAAQ,CAAC,UAAU;YAC3B,KAAK,EAAE,QAAQ,CAAC,eAAe;SAChC;QACD,SAAS,EAAE,gBAAgB;QAC3B,QAAQ,EAAE,oBAAoB;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,iFAAiF;AAEjF,SAAS,eAAe,CAAC,GAAQ;IAC/B,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;IAC5C,OAAO,QAAQ,CAAC;QACd,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,wEAAwE;QACrF,OAAO,EAAE,OAAO;QAChB,eAAe,EAAE,oBAAoB;QACrC,QAAQ,EAAE,GAAG,IAAI,MAAM;QACvB,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3E,OAAO,EAAE,oBAAoB;QAC7B,IAAI,EAAE,uCAAuC;KAC9C,CAAC,CAAC;AACL,CAAC;AAED,iFAAiF;AAEjF,SAAS,UAAU,CAAC,GAAQ;IAC1B,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG;;2BAEY,QAAQ,CAAC,UAAU,aAAa,QAAQ,CAAC,eAAe;;;;OAI5E,IAAI;OACJ,IAAI;OACJ,IAAI;;;;EAIT,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;gBAOlE,IAAI;;;;;;;CAOnB,CAAC;IACA,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;QACxB,OAAO,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,GAAG,YAAY,EAAE;KAC1E,CAAC,CAAC;AACL,CAAC;AAED,iFAAiF;AAEjF,eAAe;IACb,KAAK,CAAC,KAAK,CAAC,OAAgB,EAAE,GAAQ;QACpC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAE5C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACnD,OAAO,YAAY,EAAE,CAAC;QACxB,CAAC;QAED,IAAI,GAAG,CAAC,QAAQ,KAAK,uBAAuB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACjE,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QAED,IAAI,GAAG,CAAC,QAAQ,KAAK,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACjD,OAAO,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YAC7C,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QAED,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3E,CAAC;CACF,CAAC"}
|