@zuwiki/mcp 0.1.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/LICENSE +7 -0
- package/README.md +189 -0
- package/dist/api/categories.d.ts +4 -0
- package/dist/api/categories.js +14 -0
- package/dist/api/categories.js.map +1 -0
- package/dist/api/http.d.ts +8 -0
- package/dist/api/http.js +119 -0
- package/dist/api/http.js.map +1 -0
- package/dist/api/organizations.d.ts +14 -0
- package/dist/api/organizations.js +15 -0
- package/dist/api/organizations.js.map +1 -0
- package/dist/api/pages.d.ts +16 -0
- package/dist/api/pages.js +35 -0
- package/dist/api/pages.js.map +1 -0
- package/dist/api/types.d.ts +69 -0
- package/dist/api/types.js +13 -0
- package/dist/api/types.js.map +1 -0
- package/dist/api/wikis.d.ts +12 -0
- package/dist/api/wikis.js +25 -0
- package/dist/api/wikis.js.map +1 -0
- package/dist/auth/client.d.ts +54 -0
- package/dist/auth/client.js +162 -0
- package/dist/auth/client.js.map +1 -0
- package/dist/auth/discovery.d.ts +14 -0
- package/dist/auth/discovery.js +26 -0
- package/dist/auth/discovery.js.map +1 -0
- package/dist/auth/flow.d.ts +21 -0
- package/dist/auth/flow.js +188 -0
- package/dist/auth/flow.js.map +1 -0
- package/dist/auth/pkce.d.ts +7 -0
- package/dist/auth/pkce.js +20 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/registration.d.ts +21 -0
- package/dist/auth/registration.js +28 -0
- package/dist/auth/registration.js.map +1 -0
- package/dist/auth/tokens.d.ts +25 -0
- package/dist/auth/tokens.js +51 -0
- package/dist/auth/tokens.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +128 -0
- package/dist/cli.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.js +53 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/register.d.ts +12 -0
- package/dist/tools/register.js +244 -0
- package/dist/tools/register.js.map +1 -0
- package/dist/tools/shared.d.ts +5 -0
- package/dist/tools/shared.js +38 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/transports/http.d.ts +9 -0
- package/dist/transports/http.js +150 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/transports/stdio.d.ts +7 -0
- package/dist/transports/stdio.js +20 -0
- package/dist/transports/stdio.js.map +1 -0
- package/package.json +41 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { startStdio } from "./transports/stdio.js";
|
|
3
|
+
import { startHttp } from "./transports/http.js";
|
|
4
|
+
const DEFAULT_BASE_URL = "https://zuwiki.com";
|
|
5
|
+
function parseArgs(argv) {
|
|
6
|
+
const opts = {
|
|
7
|
+
http: false,
|
|
8
|
+
host: process.env.ZUWIKI_HTTP_HOST ?? "127.0.0.1",
|
|
9
|
+
port: parseIntEnv(process.env.ZUWIKI_HTTP_PORT, 3333),
|
|
10
|
+
baseUrl: process.env.ZUWIKI_BASE_URL ?? DEFAULT_BASE_URL,
|
|
11
|
+
organizationId: process.env.ZUWIKI_ORGANIZATION_ID ?? null,
|
|
12
|
+
credentialsPath: process.env.ZUWIKI_CREDENTIALS_PATH,
|
|
13
|
+
organizationsPath: process.env.ZUWIKI_ORGANIZATIONS_PATH,
|
|
14
|
+
path: process.env.ZUWIKI_HTTP_PATH ?? "/mcp",
|
|
15
|
+
};
|
|
16
|
+
for (let i = 0; i < argv.length; i++) {
|
|
17
|
+
const arg = argv[i];
|
|
18
|
+
if (arg === "--help" || arg === "-h") {
|
|
19
|
+
printHelp();
|
|
20
|
+
process.exit(0);
|
|
21
|
+
}
|
|
22
|
+
else if (arg === "--http") {
|
|
23
|
+
opts.http = true;
|
|
24
|
+
}
|
|
25
|
+
else if (arg === "--stdio") {
|
|
26
|
+
opts.http = false;
|
|
27
|
+
}
|
|
28
|
+
else if (arg === "--host") {
|
|
29
|
+
opts.host = requireValue(argv, ++i, arg);
|
|
30
|
+
}
|
|
31
|
+
else if (arg === "--port") {
|
|
32
|
+
opts.port = parseRequiredInt(requireValue(argv, ++i, arg), arg);
|
|
33
|
+
}
|
|
34
|
+
else if (arg === "--base-url") {
|
|
35
|
+
opts.baseUrl = requireValue(argv, ++i, arg);
|
|
36
|
+
}
|
|
37
|
+
else if (arg === "--organization" || arg === "--org") {
|
|
38
|
+
opts.organizationId = requireValue(argv, ++i, arg);
|
|
39
|
+
}
|
|
40
|
+
else if (arg === "--credentials") {
|
|
41
|
+
opts.credentialsPath = requireValue(argv, ++i, arg);
|
|
42
|
+
}
|
|
43
|
+
else if (arg === "--organizations-path") {
|
|
44
|
+
opts.organizationsPath = requireValue(argv, ++i, arg);
|
|
45
|
+
}
|
|
46
|
+
else if (arg === "--path") {
|
|
47
|
+
opts.path = requireValue(argv, ++i, arg);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
process.stderr.write(`Unknown argument: ${arg}\n`);
|
|
51
|
+
printHelp();
|
|
52
|
+
process.exit(2);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return opts;
|
|
56
|
+
}
|
|
57
|
+
function requireValue(argv, index, flag) {
|
|
58
|
+
const value = argv[index];
|
|
59
|
+
if (typeof value !== "string") {
|
|
60
|
+
process.stderr.write(`Missing value for ${flag}.\n`);
|
|
61
|
+
process.exit(2);
|
|
62
|
+
}
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
function parseIntEnv(value, fallback) {
|
|
66
|
+
if (!value)
|
|
67
|
+
return fallback;
|
|
68
|
+
const n = Number(value);
|
|
69
|
+
if (!Number.isFinite(n) || !Number.isInteger(n))
|
|
70
|
+
return fallback;
|
|
71
|
+
return n;
|
|
72
|
+
}
|
|
73
|
+
function parseRequiredInt(value, flag) {
|
|
74
|
+
const n = Number(value);
|
|
75
|
+
if (!Number.isFinite(n) || !Number.isInteger(n)) {
|
|
76
|
+
process.stderr.write(`Value for ${flag} must be an integer.\n`);
|
|
77
|
+
process.exit(2);
|
|
78
|
+
}
|
|
79
|
+
return n;
|
|
80
|
+
}
|
|
81
|
+
function printHelp() {
|
|
82
|
+
process.stderr.write([
|
|
83
|
+
"Zuwiki MCP Server",
|
|
84
|
+
"",
|
|
85
|
+
"Usage:",
|
|
86
|
+
" zuwiki-mcp [options]",
|
|
87
|
+
"",
|
|
88
|
+
"Options:",
|
|
89
|
+
" --http Use streamable HTTP transport instead of stdio",
|
|
90
|
+
" --host <host> HTTP host (default: 127.0.0.1)",
|
|
91
|
+
" --port <port> HTTP port (default: 3333)",
|
|
92
|
+
" --path <path> HTTP path (default: /mcp)",
|
|
93
|
+
" --base-url <url> Zuwiki base URL (default: https://zuwiki.com)",
|
|
94
|
+
" --organization <id> Active organization id",
|
|
95
|
+
" --credentials <path> Path to the credentials file",
|
|
96
|
+
" --organizations-path <p> Override the API path for the organizations list",
|
|
97
|
+
" --help Show this help",
|
|
98
|
+
"",
|
|
99
|
+
"In stdio mode the OAuth browser flow runs on the first start.",
|
|
100
|
+
"In HTTP mode the MCP client must send a bearer token on every request via the Authorization header.",
|
|
101
|
+
"",
|
|
102
|
+
].join("\n"));
|
|
103
|
+
}
|
|
104
|
+
async function main() {
|
|
105
|
+
const opts = parseArgs(process.argv.slice(2));
|
|
106
|
+
if (opts.http) {
|
|
107
|
+
await startHttp({
|
|
108
|
+
baseUrl: opts.baseUrl,
|
|
109
|
+
host: opts.host,
|
|
110
|
+
port: opts.port,
|
|
111
|
+
organizationId: opts.organizationId,
|
|
112
|
+
organizationsPath: opts.organizationsPath,
|
|
113
|
+
path: opts.path,
|
|
114
|
+
});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
await startStdio({
|
|
118
|
+
baseUrl: opts.baseUrl,
|
|
119
|
+
organizationId: opts.organizationId,
|
|
120
|
+
credentialsPath: opts.credentialsPath,
|
|
121
|
+
organizationsPath: opts.organizationsPath,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
main().catch((err) => {
|
|
125
|
+
process.stderr.write(`Startup error: ${err.message}\n`);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
});
|
|
128
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAajD,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAE9C,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,IAAI,GAAe;QACvB,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,WAAW;QACjD,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC;QACrD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,gBAAgB;QACxD,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,IAAI;QAC1D,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB;QACpD,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;QACxD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM;KAC7C,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACrC,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,CAAC;aAAM,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QACpB,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QAClE,CAAC;aAAM,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,GAAG,KAAK,gBAAgB,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACvD,IAAI,CAAC,cAAc,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QACrD,CAAC;aAAM,IAAI,GAAG,KAAK,eAAe,EAAE,CAAC;YACnC,IAAI,CAAC,eAAe,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QACtD,CAAC;aAAM,IAAI,GAAG,KAAK,sBAAsB,EAAE,CAAC;YAC1C,IAAI,CAAC,iBAAiB,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;YACnD,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CAAC,IAAc,EAAE,KAAa,EAAE,IAAY;IAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,IAAI,KAAK,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,KAAyB,EAAE,QAAgB;IAC9D,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC5B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC;IACjE,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,IAAY;IACnD,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,wBAAwB,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB;QACE,mBAAmB;QACnB,EAAE;QACF,QAAQ;QACR,wBAAwB;QACxB,EAAE;QACF,UAAU;QACV,2EAA2E;QAC3E,2DAA2D;QAC3D,sDAAsD;QACtD,sDAAsD;QACtD,0EAA0E;QAC1E,mDAAmD;QACnD,yDAAyD;QACzD,6EAA6E;QAC7E,2CAA2C;QAC3C,EAAE;QACF,+DAA+D;QAC/D,qGAAqG;QACrG,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9C,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,SAAS,CAAC;YACd,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,UAAU,CAAC;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,eAAe,EAAE,IAAI,CAAC,eAAe;QACrC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;KAC1C,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAmB,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;IACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { AuthManager, OrganizationState } from "./auth/client.js";
|
|
3
|
+
export interface BuildServerOptions {
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
authManager?: AuthManager;
|
|
6
|
+
organizationId?: string | null;
|
|
7
|
+
organizationsPath?: string;
|
|
8
|
+
/** If set, the token is read from this callback on every request instead of from the AuthManager. */
|
|
9
|
+
perRequestToken?: () => string | null;
|
|
10
|
+
}
|
|
11
|
+
export interface BuiltServer {
|
|
12
|
+
server: McpServer;
|
|
13
|
+
organizationState: OrganizationState;
|
|
14
|
+
}
|
|
15
|
+
export declare function buildServer(opts: BuildServerOptions): BuiltServer;
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { OrganizationState } from "./auth/client.js";
|
|
3
|
+
import { registerTools } from "./tools/register.js";
|
|
4
|
+
export function buildServer(opts) {
|
|
5
|
+
const server = new McpServer({
|
|
6
|
+
name: "zuwiki-mcp",
|
|
7
|
+
version: "0.1.0",
|
|
8
|
+
}, {
|
|
9
|
+
capabilities: {
|
|
10
|
+
tools: { listChanged: false },
|
|
11
|
+
},
|
|
12
|
+
instructions: "Zuwiki MCP Server. Use the zuwiki_ tools to read and edit wikis, categories and pages. First pick an organization to work in via zuwiki_list_organizations and zuwiki_set_active_organization, then explore the existing structure with zuwiki_list_wikis and zuwiki_get_wiki_editor.",
|
|
13
|
+
});
|
|
14
|
+
const organizationState = new OrganizationState(opts.organizationId ?? null);
|
|
15
|
+
const contextFactory = (extra) => {
|
|
16
|
+
const apiContext = {
|
|
17
|
+
baseUrl: opts.baseUrl,
|
|
18
|
+
organizationId: organizationState.get(),
|
|
19
|
+
async getAccessToken() {
|
|
20
|
+
if (opts.perRequestToken) {
|
|
21
|
+
const token = opts.perRequestToken();
|
|
22
|
+
if (!token) {
|
|
23
|
+
throw new Error("No bearer token on the current request. Send an Authorization header.");
|
|
24
|
+
}
|
|
25
|
+
return token;
|
|
26
|
+
}
|
|
27
|
+
const fromExtra = extra.authInfo?.token;
|
|
28
|
+
if (fromExtra)
|
|
29
|
+
return fromExtra;
|
|
30
|
+
if (opts.authManager)
|
|
31
|
+
return opts.authManager.ensureAccessToken();
|
|
32
|
+
throw new Error("No token source configured.");
|
|
33
|
+
},
|
|
34
|
+
async invalidateAndRefreshToken() {
|
|
35
|
+
if (opts.perRequestToken) {
|
|
36
|
+
throw new Error("Cannot refresh: the bearer token is supplied per request by the HTTP client. The client must send a new token.");
|
|
37
|
+
}
|
|
38
|
+
if (opts.authManager)
|
|
39
|
+
return opts.authManager.invalidateAndRefresh();
|
|
40
|
+
throw new Error("No token source configured.");
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
return apiContext;
|
|
44
|
+
};
|
|
45
|
+
registerTools({
|
|
46
|
+
server,
|
|
47
|
+
contextFactory,
|
|
48
|
+
organizationState,
|
|
49
|
+
organizationsPath: opts.organizationsPath,
|
|
50
|
+
});
|
|
51
|
+
return { server, organizationState };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAe,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,aAAa,EAA0B,MAAM,qBAAqB,CAAC;AAiB5E,MAAM,UAAU,WAAW,CAAC,IAAwB;IAClD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;SAC9B;QACD,YAAY,EACV,uRAAuR;KAC1R,CACF,CAAC;IAEF,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC;IAE7E,MAAM,cAAc,GAAsB,CAAC,KAAK,EAAE,EAAE;QAClD,MAAM,UAAU,GAAe;YAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,cAAc,EAAE,iBAAiB,CAAC,GAAG,EAAE;YACvC,KAAK,CAAC,cAAc;gBAClB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;oBACzB,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;oBACrC,IAAI,CAAC,KAAK,EAAE,CAAC;wBACX,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAC;oBACJ,CAAC;oBACD,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC;gBACxC,IAAI,SAAS;oBAAE,OAAO,SAAS,CAAC;gBAChC,IAAI,IAAI,CAAC,WAAW;oBAAE,OAAO,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE,CAAC;gBAClE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YACjD,CAAC;YACD,KAAK,CAAC,yBAAyB;gBAC7B,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;oBACzB,MAAM,IAAI,KAAK,CACb,gHAAgH,CACjH,CAAC;gBACJ,CAAC;gBACD,IAAI,IAAI,CAAC,WAAW;oBAAE,OAAO,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAC;gBACrE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YACjD,CAAC;SACF,CAAC;QACF,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;IAEF,aAAa,CAAC;QACZ,MAAM;QACN,cAAc;QACd,iBAAiB;QACjB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;KAC1C,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
3
|
+
import type { ApiContext } from "../api/types.js";
|
|
4
|
+
import { OrganizationState } from "../auth/client.js";
|
|
5
|
+
export type ApiContextFactory = (extra: RequestHandlerExtra<any, any>) => ApiContext;
|
|
6
|
+
export interface RegisterToolsOptions {
|
|
7
|
+
server: McpServer;
|
|
8
|
+
contextFactory: ApiContextFactory;
|
|
9
|
+
organizationState: OrganizationState;
|
|
10
|
+
organizationsPath?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function registerTools(opts: RegisterToolsOptions): void;
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { createWiki, deleteWiki, getWiki, getWikiEditor, listWikis, updateWiki, } from "../api/wikis.js";
|
|
3
|
+
import { createCategory, deleteCategory, renameCategory, } from "../api/categories.js";
|
|
4
|
+
import { createPage, deletePage, getPageContent, getPageHistory, getPageSettings, renamePage, restorePageHistory, setPageStatus, updatePageContent, updatePageSettings, } from "../api/pages.js";
|
|
5
|
+
import { listOrganizations } from "../api/organizations.js";
|
|
6
|
+
import { runTool } from "./shared.js";
|
|
7
|
+
const visibilityEnum = z.enum([
|
|
8
|
+
"PUBLIC",
|
|
9
|
+
"PRIVATE_ACCOUNT",
|
|
10
|
+
"PRIVATE_PASSWORD",
|
|
11
|
+
"PRIVATE_EMAIL_DOMAIN",
|
|
12
|
+
]);
|
|
13
|
+
const statusEnum = z.enum(["DRAFT", "PUBLISHED"]);
|
|
14
|
+
export function registerTools(opts) {
|
|
15
|
+
const { server, contextFactory, organizationState } = opts;
|
|
16
|
+
// Organization Tools
|
|
17
|
+
server.registerTool("zuwiki_list_organizations", {
|
|
18
|
+
title: "List organizations",
|
|
19
|
+
description: "Lists every organization the currently signed in Zuwiki user is a member of. Use this when no active organization is set yet or when you want to switch. Returns the id and name of each organization.",
|
|
20
|
+
inputSchema: {},
|
|
21
|
+
}, async (_args, extra) => {
|
|
22
|
+
return runTool(async () => {
|
|
23
|
+
const ctx = contextFactory(extra);
|
|
24
|
+
return listOrganizations(ctx, opts.organizationsPath);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
server.registerTool("zuwiki_set_active_organization", {
|
|
28
|
+
title: "Set active organization",
|
|
29
|
+
description: "Sets the organization whose wikis will be operated on. All subsequent tool calls use this id as the x-organization-id header. The value persists for the lifetime of this server instance only.",
|
|
30
|
+
inputSchema: {
|
|
31
|
+
organizationId: z
|
|
32
|
+
.string()
|
|
33
|
+
.min(1)
|
|
34
|
+
.describe("ID of the organization whose wikis should be operated on."),
|
|
35
|
+
},
|
|
36
|
+
}, async ({ organizationId }) => {
|
|
37
|
+
organizationState.set(organizationId);
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: "text",
|
|
42
|
+
text: `Active organization is now ${organizationId}.`,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
server.registerTool("zuwiki_get_active_organization", {
|
|
48
|
+
title: "Get active organization",
|
|
49
|
+
description: "Returns the organization id currently used for wiki operations. Returns null if none has been set yet.",
|
|
50
|
+
inputSchema: {},
|
|
51
|
+
}, async () => ({
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: "text",
|
|
55
|
+
text: JSON.stringify({ organizationId: organizationState.get() }, null, 2),
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
}));
|
|
59
|
+
// Wiki Read Tools
|
|
60
|
+
server.registerTool("zuwiki_list_wikis", {
|
|
61
|
+
title: "List wikis",
|
|
62
|
+
description: "Lists all wikis in the active organization. Use this tool to find the wikiId for further calls.",
|
|
63
|
+
inputSchema: {},
|
|
64
|
+
}, async (_args, extra) => runTool(async () => listWikis(contextFactory(extra))));
|
|
65
|
+
server.registerTool("zuwiki_get_wiki", {
|
|
66
|
+
title: "Get wiki details",
|
|
67
|
+
description: "Returns metadata of a wiki such as title and slug. For the full structure including categories and pages use zuwiki_get_wiki_editor instead.",
|
|
68
|
+
inputSchema: {
|
|
69
|
+
wikiId: z.string().min(1).describe("ID of the wiki"),
|
|
70
|
+
},
|
|
71
|
+
}, async ({ wikiId }, extra) => runTool(async () => getWiki(contextFactory(extra), wikiId)));
|
|
72
|
+
server.registerTool("zuwiki_get_wiki_editor", {
|
|
73
|
+
title: "Get wiki structure tree",
|
|
74
|
+
description: "Returns a snapshot of the entire wiki structure: all categories, root pages, nested pages and root links. This is the fastest way to get an overview of how a wiki is organized before editing individual pages.",
|
|
75
|
+
inputSchema: {
|
|
76
|
+
wikiId: z.string().min(1).describe("ID of the wiki"),
|
|
77
|
+
},
|
|
78
|
+
}, async ({ wikiId }, extra) => runTool(async () => getWikiEditor(contextFactory(extra), wikiId)));
|
|
79
|
+
// Wiki Write Tools
|
|
80
|
+
server.registerTool("zuwiki_create_wiki", {
|
|
81
|
+
title: "Create wiki",
|
|
82
|
+
description: "Creates a new wiki in the active organization. The slug is derived from the title by the server.",
|
|
83
|
+
inputSchema: {
|
|
84
|
+
title: z.string().min(1).describe("Display name of the new wiki"),
|
|
85
|
+
},
|
|
86
|
+
}, async ({ title }, extra) => runTool(async () => createWiki(contextFactory(extra), title)));
|
|
87
|
+
server.registerTool("zuwiki_update_wiki", {
|
|
88
|
+
title: "Update wiki",
|
|
89
|
+
description: "Updates the title and/or slug of a wiki. At least one of the fields must be provided.",
|
|
90
|
+
inputSchema: {
|
|
91
|
+
wikiId: z.string().min(1),
|
|
92
|
+
title: z.string().min(1).optional(),
|
|
93
|
+
slug: z.string().min(1).optional(),
|
|
94
|
+
},
|
|
95
|
+
}, async ({ wikiId, title, slug }, extra) => runTool(async () => {
|
|
96
|
+
if (title === undefined && slug === undefined) {
|
|
97
|
+
throw new Error("At least one of title or slug must be provided.");
|
|
98
|
+
}
|
|
99
|
+
return updateWiki(contextFactory(extra), wikiId, { title, slug });
|
|
100
|
+
}));
|
|
101
|
+
server.registerTool("zuwiki_delete_wiki", {
|
|
102
|
+
title: "Delete wiki",
|
|
103
|
+
description: "Deletes an entire wiki including all categories, pages and history entries. This operation cannot be undone.",
|
|
104
|
+
inputSchema: {
|
|
105
|
+
wikiId: z.string().min(1),
|
|
106
|
+
},
|
|
107
|
+
}, async ({ wikiId }, extra) => runTool(async () => deleteWiki(contextFactory(extra), wikiId)));
|
|
108
|
+
// Category Write Tools
|
|
109
|
+
server.registerTool("zuwiki_create_category", {
|
|
110
|
+
title: "Create category",
|
|
111
|
+
description: "Creates a new category inside a wiki. Categories group pages and appear as containers in the sidebar.",
|
|
112
|
+
inputSchema: {
|
|
113
|
+
wikiId: z.string().min(1),
|
|
114
|
+
name: z.string().min(1).describe("Display name of the category"),
|
|
115
|
+
},
|
|
116
|
+
}, async ({ wikiId, name }, extra) => runTool(async () => createCategory(contextFactory(extra), wikiId, name)));
|
|
117
|
+
server.registerTool("zuwiki_rename_category", {
|
|
118
|
+
title: "Rename category",
|
|
119
|
+
description: "Renames an existing category.",
|
|
120
|
+
inputSchema: {
|
|
121
|
+
wikiId: z.string().min(1),
|
|
122
|
+
categoryId: z.string().min(1),
|
|
123
|
+
name: z.string().min(1),
|
|
124
|
+
},
|
|
125
|
+
}, async ({ wikiId, categoryId, name }, extra) => runTool(async () => renameCategory(contextFactory(extra), wikiId, categoryId, name)));
|
|
126
|
+
server.registerTool("zuwiki_delete_category", {
|
|
127
|
+
title: "Delete category",
|
|
128
|
+
description: "Deletes a category. Pages inside the category lose their category assignment and become root pages.",
|
|
129
|
+
inputSchema: {
|
|
130
|
+
wikiId: z.string().min(1),
|
|
131
|
+
categoryId: z.string().min(1),
|
|
132
|
+
},
|
|
133
|
+
}, async ({ wikiId, categoryId }, extra) => runTool(async () => deleteCategory(contextFactory(extra), wikiId, categoryId)));
|
|
134
|
+
// Page Metadata Tools
|
|
135
|
+
server.registerTool("zuwiki_create_page", {
|
|
136
|
+
title: "Create page",
|
|
137
|
+
description: "Creates a new page inside a wiki. If categoryId is provided, the page is placed inside that category. If null or omitted, the page is created as a root page.",
|
|
138
|
+
inputSchema: {
|
|
139
|
+
wikiId: z.string().min(1),
|
|
140
|
+
title: z.string().min(1),
|
|
141
|
+
categoryId: z.string().nullable().optional(),
|
|
142
|
+
},
|
|
143
|
+
}, async ({ wikiId, title, categoryId }, extra) => runTool(async () => createPage(contextFactory(extra), wikiId, {
|
|
144
|
+
title,
|
|
145
|
+
categoryId: categoryId ?? null,
|
|
146
|
+
})));
|
|
147
|
+
server.registerTool("zuwiki_rename_page", {
|
|
148
|
+
title: "Rename page",
|
|
149
|
+
description: "Changes the title of a page. Content and history are preserved.",
|
|
150
|
+
inputSchema: {
|
|
151
|
+
wikiId: z.string().min(1),
|
|
152
|
+
pageId: z.string().min(1),
|
|
153
|
+
title: z.string().min(1),
|
|
154
|
+
},
|
|
155
|
+
}, async ({ wikiId, pageId, title }, extra) => runTool(async () => renamePage(contextFactory(extra), wikiId, pageId, title)));
|
|
156
|
+
server.registerTool("zuwiki_delete_page", {
|
|
157
|
+
title: "Delete page",
|
|
158
|
+
description: "Deletes a page including its history. This operation cannot be undone.",
|
|
159
|
+
inputSchema: {
|
|
160
|
+
wikiId: z.string().min(1),
|
|
161
|
+
pageId: z.string().min(1),
|
|
162
|
+
},
|
|
163
|
+
}, async ({ wikiId, pageId }, extra) => runTool(async () => deletePage(contextFactory(extra), wikiId, pageId)));
|
|
164
|
+
// Page Content Tools
|
|
165
|
+
server.registerTool("zuwiki_get_page_content", {
|
|
166
|
+
title: "Read page content",
|
|
167
|
+
description: "Reads the current Markdown content of a page. The response contains a content field with the raw Markdown.",
|
|
168
|
+
inputSchema: {
|
|
169
|
+
wikiId: z.string().min(1),
|
|
170
|
+
pageId: z.string().min(1),
|
|
171
|
+
},
|
|
172
|
+
}, async ({ wikiId, pageId }, extra) => runTool(async () => getPageContent(contextFactory(extra), wikiId, pageId)));
|
|
173
|
+
server.registerTool("zuwiki_update_page_content", {
|
|
174
|
+
title: "Save page content",
|
|
175
|
+
description: "Overwrites the Markdown content of a page. The server automatically creates a history entry on every save, so older revisions can be restored later via zuwiki_get_page_history and zuwiki_restore_page_history.",
|
|
176
|
+
inputSchema: {
|
|
177
|
+
wikiId: z.string().min(1),
|
|
178
|
+
pageId: z.string().min(1),
|
|
179
|
+
content: z.string().describe("Complete new Markdown content of the page"),
|
|
180
|
+
},
|
|
181
|
+
}, async ({ wikiId, pageId, content }, extra) => runTool(async () => updatePageContent(contextFactory(extra), wikiId, pageId, content)));
|
|
182
|
+
// Page Settings Tools
|
|
183
|
+
server.registerTool("zuwiki_get_page_settings", {
|
|
184
|
+
title: "Read page settings",
|
|
185
|
+
description: "Reads the settings of a page such as slug, visibility, SEO fields and icon.",
|
|
186
|
+
inputSchema: {
|
|
187
|
+
wikiId: z.string().min(1),
|
|
188
|
+
pageId: z.string().min(1),
|
|
189
|
+
},
|
|
190
|
+
}, async ({ wikiId, pageId }, extra) => runTool(async () => getPageSettings(contextFactory(extra), wikiId, pageId)));
|
|
191
|
+
server.registerTool("zuwiki_update_page_settings", {
|
|
192
|
+
title: "Update page settings",
|
|
193
|
+
description: "Updates arbitrary settings of a page. All fields are optional, only provided values are changed. pageVisibility controls the access level.",
|
|
194
|
+
inputSchema: {
|
|
195
|
+
wikiId: z.string().min(1),
|
|
196
|
+
pageId: z.string().min(1),
|
|
197
|
+
title: z.string().min(1).optional(),
|
|
198
|
+
slug: z.string().min(1).optional(),
|
|
199
|
+
hidden: z.boolean().optional(),
|
|
200
|
+
pageVisibility: visibilityEnum.optional(),
|
|
201
|
+
seoTitle: z.string().optional(),
|
|
202
|
+
seoDescription: z.string().optional(),
|
|
203
|
+
seoKeywords: z.string().optional(),
|
|
204
|
+
icon: z.string().optional(),
|
|
205
|
+
},
|
|
206
|
+
}, async (args, extra) => {
|
|
207
|
+
return runTool(async () => {
|
|
208
|
+
const { wikiId, pageId, ...patch } = args;
|
|
209
|
+
const clean = Object.fromEntries(Object.entries(patch).filter(([, v]) => v !== undefined));
|
|
210
|
+
if (Object.keys(clean).length === 0) {
|
|
211
|
+
throw new Error("At least one settings field must be provided.");
|
|
212
|
+
}
|
|
213
|
+
return updatePageSettings(contextFactory(extra), wikiId, pageId, clean);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
server.registerTool("zuwiki_set_page_status", {
|
|
217
|
+
title: "Set page status",
|
|
218
|
+
description: "Sets the publication status of a page. DRAFT means the page is only visible to editors, PUBLISHED makes it available according to its pageVisibility.",
|
|
219
|
+
inputSchema: {
|
|
220
|
+
wikiId: z.string().min(1),
|
|
221
|
+
pageId: z.string().min(1),
|
|
222
|
+
status: statusEnum,
|
|
223
|
+
},
|
|
224
|
+
}, async ({ wikiId, pageId, status }, extra) => runTool(async () => setPageStatus(contextFactory(extra), wikiId, pageId, status)));
|
|
225
|
+
// Page History Tools
|
|
226
|
+
server.registerTool("zuwiki_get_page_history", {
|
|
227
|
+
title: "Read page history",
|
|
228
|
+
description: "Returns every history entry of a page including timestamp and author. Use the historyId of an entry together with zuwiki_restore_page_history to restore that revision.",
|
|
229
|
+
inputSchema: {
|
|
230
|
+
wikiId: z.string().min(1),
|
|
231
|
+
pageId: z.string().min(1),
|
|
232
|
+
},
|
|
233
|
+
}, async ({ wikiId, pageId }, extra) => runTool(async () => getPageHistory(contextFactory(extra), wikiId, pageId)));
|
|
234
|
+
server.registerTool("zuwiki_restore_page_history", {
|
|
235
|
+
title: "Restore historical revision",
|
|
236
|
+
description: "Restores a previous content version of a page. The current content is saved as a new history entry first.",
|
|
237
|
+
inputSchema: {
|
|
238
|
+
wikiId: z.string().min(1),
|
|
239
|
+
pageId: z.string().min(1),
|
|
240
|
+
historyId: z.string().min(1),
|
|
241
|
+
},
|
|
242
|
+
}, async ({ wikiId, pageId, historyId }, extra) => runTool(async () => restorePageHistory(contextFactory(extra), wikiId, pageId, historyId)));
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare function jsonResult(value: unknown): CallToolResult;
|
|
3
|
+
export declare function errorResult(message: string): CallToolResult;
|
|
4
|
+
export declare function formatApiError(err: unknown): string;
|
|
5
|
+
export declare function runTool<T>(fn: () => Promise<T>): Promise<CallToolResult>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ApiError } from "../api/types.js";
|
|
2
|
+
export function jsonResult(value) {
|
|
3
|
+
const text = typeof value === "string" ? value : JSON.stringify(value, null, 2);
|
|
4
|
+
return {
|
|
5
|
+
content: [{ type: "text", text }],
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function errorResult(message) {
|
|
9
|
+
return {
|
|
10
|
+
isError: true,
|
|
11
|
+
content: [{ type: "text", text: message }],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function formatApiError(err) {
|
|
15
|
+
if (err instanceof ApiError) {
|
|
16
|
+
if (err.code === "insufficient_scope") {
|
|
17
|
+
return `Request rejected because of insufficient scope. The current token does not carry the required permission. ${err.message}`;
|
|
18
|
+
}
|
|
19
|
+
if (err.code === "forbidden_or_not_member") {
|
|
20
|
+
return `403 received. Either the user is not a member of the active organization or the action is not allowed. ${err.message}`;
|
|
21
|
+
}
|
|
22
|
+
if (err.code === "no_active_organization") {
|
|
23
|
+
return err.message;
|
|
24
|
+
}
|
|
25
|
+
return err.message;
|
|
26
|
+
}
|
|
27
|
+
return err.message ?? String(err);
|
|
28
|
+
}
|
|
29
|
+
export async function runTool(fn) {
|
|
30
|
+
try {
|
|
31
|
+
const value = await fn();
|
|
32
|
+
return jsonResult(value ?? { ok: true });
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
return errorResult(formatApiError(err));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,MAAM,IAAI,GACR,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACrE,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;KAClC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YACtC,OAAO,6GAA6G,GAAG,CAAC,OAAO,EAAE,CAAC;QACpI,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,yBAAyB,EAAE,CAAC;YAC3C,OAAO,0GAA0G,GAAG,CAAC,OAAO,EAAE,CAAC;QACjI,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,wBAAwB,EAAE,CAAC;YAC1C,OAAO,GAAG,CAAC,OAAO,CAAC;QACrB,CAAC;QACD,OAAO,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;IACD,OAAQ,GAAa,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,EAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,EAAE,EAAE,CAAC;QACzB,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,WAAW,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC"}
|