@zenalexa/unicli 0.210.0 → 0.211.2

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.
Files changed (81) hide show
  1. package/AGENTS.md +21 -7
  2. package/README.md +680 -83
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +5 -0
  5. package/dist/cli.js.map +1 -1
  6. package/dist/commands/agents.d.ts +14 -3
  7. package/dist/commands/agents.d.ts.map +1 -1
  8. package/dist/commands/agents.js +369 -140
  9. package/dist/commands/agents.js.map +1 -1
  10. package/dist/commands/mcp.d.ts +3 -4
  11. package/dist/commands/mcp.d.ts.map +1 -1
  12. package/dist/commands/mcp.js +47 -62
  13. package/dist/commands/mcp.js.map +1 -1
  14. package/dist/commands/schema.d.ts +12 -0
  15. package/dist/commands/schema.d.ts.map +1 -0
  16. package/dist/commands/schema.js +72 -0
  17. package/dist/commands/schema.js.map +1 -0
  18. package/dist/commands/search.d.ts +12 -0
  19. package/dist/commands/search.d.ts.map +1 -0
  20. package/dist/commands/search.js +47 -0
  21. package/dist/commands/search.js.map +1 -0
  22. package/dist/discovery/aliases.d.ts +31 -0
  23. package/dist/discovery/aliases.d.ts.map +1 -0
  24. package/dist/discovery/aliases.js +477 -0
  25. package/dist/discovery/aliases.js.map +1 -0
  26. package/dist/discovery/loader.d.ts.map +1 -1
  27. package/dist/discovery/loader.js +25 -0
  28. package/dist/discovery/loader.js.map +1 -1
  29. package/dist/discovery/search.d.ts +73 -0
  30. package/dist/discovery/search.d.ts.map +1 -0
  31. package/dist/discovery/search.js +355 -0
  32. package/dist/discovery/search.js.map +1 -0
  33. package/dist/manifest-compact.txt +15 -0
  34. package/dist/manifest-search.json +1 -0
  35. package/dist/manifest.json +433 -244
  36. package/dist/mcp/oauth.d.ts +33 -0
  37. package/dist/mcp/oauth.d.ts.map +1 -0
  38. package/dist/mcp/oauth.js +220 -0
  39. package/dist/mcp/oauth.js.map +1 -0
  40. package/dist/mcp/schema.d.ts +65 -0
  41. package/dist/mcp/schema.d.ts.map +1 -0
  42. package/dist/mcp/schema.js +136 -0
  43. package/dist/mcp/schema.js.map +1 -0
  44. package/dist/mcp/server.d.ts +23 -10
  45. package/dist/mcp/server.d.ts.map +1 -1
  46. package/dist/mcp/server.js +350 -182
  47. package/dist/mcp/server.js.map +1 -1
  48. package/dist/mcp/sse-transport.d.ts +34 -0
  49. package/dist/mcp/sse-transport.d.ts.map +1 -0
  50. package/dist/mcp/sse-transport.js +182 -0
  51. package/dist/mcp/sse-transport.js.map +1 -0
  52. package/dist/mcp/streamable-http.d.ts +64 -0
  53. package/dist/mcp/streamable-http.d.ts.map +1 -0
  54. package/dist/mcp/streamable-http.js +312 -0
  55. package/dist/mcp/streamable-http.js.map +1 -0
  56. package/dist/permissions/sensitive-paths.js +2 -2
  57. package/dist/permissions/sensitive-paths.js.map +1 -1
  58. package/package.json +7 -7
  59. package/src/adapters/1688/_site.json +9 -0
  60. package/src/adapters/barchart/_site.json +10 -0
  61. package/src/adapters/jd/_site.json +9 -0
  62. package/src/adapters/linkedin/_site.json +10 -0
  63. package/src/adapters/macos/finder-copy.yaml +40 -0
  64. package/src/adapters/macos/finder-move.yaml +40 -0
  65. package/src/adapters/macos/finder-new-folder.yaml +36 -0
  66. package/src/adapters/macos/safari-history.yaml +23 -0
  67. package/src/adapters/macos/safari-url.yaml +22 -0
  68. package/src/adapters/macos/screen-recording.yaml +32 -0
  69. package/src/adapters/macos/wallpaper.yaml +33 -0
  70. package/src/adapters/reuters/_site.json +9 -0
  71. package/src/adapters/sinablog/_site.json +9 -0
  72. package/src/adapters/smzdm/_site.json +9 -0
  73. package/src/adapters/weixin/_site.json +9 -0
  74. package/src/adapters/1688/manifest.yaml +0 -7
  75. package/src/adapters/barchart/manifest.yaml +0 -8
  76. package/src/adapters/jd/manifest.yaml +0 -7
  77. package/src/adapters/linkedin/manifest.yaml +0 -8
  78. package/src/adapters/reuters/manifest.yaml +0 -7
  79. package/src/adapters/sinablog/manifest.yaml +0 -7
  80. package/src/adapters/smzdm/manifest.yaml +0 -7
  81. package/src/adapters/weixin/manifest.yaml +0 -7
@@ -0,0 +1,33 @@
1
+ /**
2
+ * OAuth 2.1 Authorization Code + PKCE for MCP HTTP transport.
3
+ *
4
+ * S256-only, public clients (no client_secret), in-memory storage.
5
+ * Zero external dependencies — uses Node.js crypto + http built-ins.
6
+ */
7
+ import type { IncomingMessage, ServerResponse } from "node:http";
8
+ interface AuthCode {
9
+ clientId: string;
10
+ codeChallenge: string;
11
+ redirectUri: string;
12
+ expiresAt: number;
13
+ }
14
+ interface Token {
15
+ clientId: string;
16
+ expiresAt: number;
17
+ }
18
+ declare function generateHex(bytes: number): string;
19
+ declare function sha256Base64url(input: string): string;
20
+ declare function pruneExpired(): void;
21
+ /** Returns `true` if the request was an OAuth route and has been handled. */
22
+ export declare function handleOAuthRoute(req: IncomingMessage, res: ServerResponse): boolean;
23
+ /** Returns a function that blocks unauthorized requests (returns `true` = blocked). */
24
+ export declare function createOAuthMiddleware(): (req: IncomingMessage, res: ServerResponse) => boolean;
25
+ export declare const _test: {
26
+ readonly authCodes: Map<string, AuthCode>;
27
+ readonly tokens: Map<string, Token>;
28
+ readonly sha256Base64url: typeof sha256Base64url;
29
+ readonly generateHex: typeof generateHex;
30
+ readonly pruneExpired: typeof pruneExpired;
31
+ };
32
+ export {};
33
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/mcp/oauth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,UAAU,QAAQ;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,UAAU,KAAK;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAQD,iBAAS,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1C;AACD,iBAAS,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C;AAiCD,iBAAS,YAAY,IAAI,IAAI,CAI5B;AAwID,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAqBT;AAED,uFAAuF;AACvF,wBAAgB,qBAAqB,IAAI,CACvC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,KAChB,OAAO,CAmBX;AAGD,eAAO,MAAM,KAAK;;;;;;CAMR,CAAC"}
@@ -0,0 +1,220 @@
1
+ /**
2
+ * OAuth 2.1 Authorization Code + PKCE for MCP HTTP transport.
3
+ *
4
+ * S256-only, public clients (no client_secret), in-memory storage.
5
+ * Zero external dependencies — uses Node.js crypto + http built-ins.
6
+ */
7
+ import { createHash, randomBytes } from "node:crypto";
8
+ const authCodes = new Map();
9
+ const tokens = new Map();
10
+ const AUTH_CODE_TTL_MS = 60_000;
11
+ const TOKEN_TTL_S = 3_600;
12
+ const TOKEN_TTL_MS = TOKEN_TTL_S * 1_000;
13
+ function generateHex(bytes) {
14
+ return randomBytes(bytes).toString("hex");
15
+ }
16
+ function sha256Base64url(input) {
17
+ return createHash("sha256").update(input).digest("base64url");
18
+ }
19
+ function parseQuery(url) {
20
+ const i = url.indexOf("?");
21
+ return new URLSearchParams(i >= 0 ? url.slice(i + 1) : "");
22
+ }
23
+ function readBody(req) {
24
+ return new Promise((resolve, reject) => {
25
+ const chunks = [];
26
+ let size = 0;
27
+ req.on("data", (c) => {
28
+ size += c.length;
29
+ if (size > 65_536) {
30
+ req.destroy();
31
+ reject(new Error("Body too large"));
32
+ return;
33
+ }
34
+ chunks.push(c);
35
+ });
36
+ req.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
37
+ req.on("error", reject);
38
+ });
39
+ }
40
+ function json(res, status, body) {
41
+ res.writeHead(status, {
42
+ "Content-Type": "application/json",
43
+ "Cache-Control": "no-store",
44
+ });
45
+ res.end(JSON.stringify(body));
46
+ }
47
+ function pruneExpired() {
48
+ const now = Date.now();
49
+ for (const [k, v] of authCodes)
50
+ if (v.expiresAt <= now)
51
+ authCodes.delete(k);
52
+ for (const [k, v] of tokens)
53
+ if (v.expiresAt <= now)
54
+ tokens.delete(k);
55
+ }
56
+ // ── Authorization Endpoint ─────────────────────────────────────────────────
57
+ const HTML = (cid, ch, ru) => `<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Uni-CLI MCP Auth</title>` +
58
+ `<style>body{font-family:system-ui,sans-serif;max-width:420px;margin:80px auto;text-align:center}` +
59
+ `button{padding:12px 32px;font-size:16px;cursor:pointer;border:none;border-radius:6px;` +
60
+ `background:#2563eb;color:#fff}code{background:#f1f5f9;padding:2px 6px;border-radius:3px}</style>` +
61
+ `</head><body><h2>Authorize MCP Client</h2><p>Client <code>${cid}</code> requests access.</p>` +
62
+ `<form method="POST" action="/oauth/authorize"><input type="hidden" name="client_id" value="${cid}">` +
63
+ `<input type="hidden" name="code_challenge" value="${ch}"><input type="hidden" name="redirect_uri" ` +
64
+ `value="${ru}"><button type="submit">Grant Access</button></form></body></html>`;
65
+ function handleAuthorizeGet(req, res) {
66
+ const p = parseQuery(req.url ?? "");
67
+ const clientId = p.get("client_id"), challenge = p.get("code_challenge");
68
+ const method = p.get("code_challenge_method"), redirect = p.get("redirect_uri");
69
+ if (!clientId || !challenge || !redirect)
70
+ return json(res, 400, {
71
+ error: "invalid_request",
72
+ error_description: "Missing client_id, code_challenge, or redirect_uri",
73
+ });
74
+ if (method && method !== "S256")
75
+ return json(res, 400, {
76
+ error: "invalid_request",
77
+ error_description: "Only S256 code_challenge_method is supported",
78
+ });
79
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
80
+ res.end(HTML(clientId, challenge, redirect));
81
+ }
82
+ async function handleAuthorizePost(req, res) {
83
+ const p = new URLSearchParams(await readBody(req));
84
+ const clientId = p.get("client_id"), challenge = p.get("code_challenge"), redirect = p.get("redirect_uri");
85
+ if (!clientId || !challenge || !redirect)
86
+ return json(res, 400, {
87
+ error: "invalid_request",
88
+ error_description: "Missing required parameters",
89
+ });
90
+ pruneExpired();
91
+ const code = generateHex(32);
92
+ authCodes.set(code, {
93
+ clientId,
94
+ codeChallenge: challenge,
95
+ redirectUri: redirect,
96
+ expiresAt: Date.now() + AUTH_CODE_TTL_MS,
97
+ });
98
+ res.writeHead(302, {
99
+ Location: `${redirect}${redirect.includes("?") ? "&" : "?"}code=${code}`,
100
+ });
101
+ res.end();
102
+ }
103
+ // ── Token Endpoint ─────────────────────────────────────────────────────────
104
+ async function handleToken(req, res) {
105
+ const p = new URLSearchParams(await readBody(req));
106
+ const grant = p.get("grant_type"), code = p.get("code");
107
+ const verifier = p.get("code_verifier"), clientId = p.get("client_id");
108
+ if (grant !== "authorization_code")
109
+ return json(res, 400, {
110
+ error: "unsupported_grant_type",
111
+ error_description: "Only authorization_code is supported",
112
+ });
113
+ if (!code || !verifier || !clientId)
114
+ return json(res, 400, {
115
+ error: "invalid_request",
116
+ error_description: "Missing code, code_verifier, or client_id",
117
+ });
118
+ pruneExpired();
119
+ const entry = authCodes.get(code);
120
+ if (!entry)
121
+ return json(res, 400, {
122
+ error: "invalid_grant",
123
+ error_description: "Invalid or expired authorization code",
124
+ });
125
+ authCodes.delete(code); // single-use
126
+ if (entry.expiresAt <= Date.now())
127
+ return json(res, 400, {
128
+ error: "invalid_grant",
129
+ error_description: "Authorization code has expired",
130
+ });
131
+ if (entry.clientId !== clientId)
132
+ return json(res, 400, {
133
+ error: "invalid_grant",
134
+ error_description: "Client ID mismatch",
135
+ });
136
+ if (sha256Base64url(verifier) !== entry.codeChallenge)
137
+ return json(res, 400, {
138
+ error: "invalid_grant",
139
+ error_description: "PKCE verification failed",
140
+ });
141
+ const accessToken = generateHex(32);
142
+ tokens.set(accessToken, { clientId, expiresAt: Date.now() + TOKEN_TTL_MS });
143
+ json(res, 200, {
144
+ access_token: accessToken,
145
+ token_type: "Bearer",
146
+ expires_in: TOKEN_TTL_S,
147
+ });
148
+ }
149
+ // ── Bearer Validation ──────────────────────────────────────────────────────
150
+ function validateBearer(req) {
151
+ const h = req.headers.authorization;
152
+ if (!h)
153
+ return false;
154
+ const parts = h.split(" ");
155
+ if (parts.length !== 2 || parts[0] !== "Bearer")
156
+ return false;
157
+ const entry = tokens.get(parts[1]);
158
+ if (!entry)
159
+ return false;
160
+ if (entry.expiresAt <= Date.now()) {
161
+ tokens.delete(parts[1]);
162
+ return false;
163
+ }
164
+ return true;
165
+ }
166
+ // ── Public API ─────────────────────────────────────────────────────────────
167
+ /** Returns `true` if the request was an OAuth route and has been handled. */
168
+ export function handleOAuthRoute(req, res) {
169
+ const path = (req.url ?? "").split("?")[0];
170
+ if (path === "/oauth/authorize") {
171
+ if (req.method === "GET") {
172
+ handleAuthorizeGet(req, res);
173
+ return true;
174
+ }
175
+ if (req.method === "POST") {
176
+ handleAuthorizePost(req, res).catch(() => {
177
+ if (!res.writableEnded)
178
+ json(res, 500, { error: "server_error" });
179
+ });
180
+ return true;
181
+ }
182
+ }
183
+ if (path === "/oauth/token" && req.method === "POST") {
184
+ handleToken(req, res).catch(() => {
185
+ if (!res.writableEnded)
186
+ json(res, 500, { error: "server_error" });
187
+ });
188
+ return true;
189
+ }
190
+ return false;
191
+ }
192
+ /** Returns a function that blocks unauthorized requests (returns `true` = blocked). */
193
+ export function createOAuthMiddleware() {
194
+ return (req, res) => {
195
+ if (validateBearer(req))
196
+ return false;
197
+ res.writeHead(401, {
198
+ "Content-Type": "application/json",
199
+ "WWW-Authenticate": 'Bearer realm="unicli-mcp"',
200
+ });
201
+ res.end(JSON.stringify({
202
+ jsonrpc: "2.0",
203
+ id: null,
204
+ error: {
205
+ code: -32600,
206
+ message: "Unauthorized: valid Bearer token required",
207
+ },
208
+ }));
209
+ return true;
210
+ };
211
+ }
212
+ // Test helpers — exported for unit tests only
213
+ export const _test = {
214
+ authCodes,
215
+ tokens,
216
+ sha256Base64url,
217
+ generateHex,
218
+ pruneExpired,
219
+ };
220
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/mcp/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Shared JSON Schema builders for MCP tools and CLI schema command.
3
+ *
4
+ * Single source of truth for:
5
+ * - Adapter arg → JSON Schema type mapping
6
+ * - Input/output schema generation from AdapterCommand metadata
7
+ * - Tool name normalization (site + command → MCP tool name)
8
+ * - Description truncation within token budgets
9
+ */
10
+ import type { AdapterCommand } from "../types.js";
11
+ export interface JsonSchemaProperty {
12
+ type: string;
13
+ description?: string;
14
+ default?: unknown;
15
+ enum?: string[];
16
+ additionalProperties?: boolean;
17
+ items?: JsonSchemaProperty;
18
+ properties?: Record<string, JsonSchemaProperty>;
19
+ }
20
+ export interface JsonSchemaObject {
21
+ type: "object" | "array";
22
+ properties?: Record<string, JsonSchemaProperty>;
23
+ required?: string[];
24
+ additionalProperties?: boolean;
25
+ items?: JsonSchemaProperty;
26
+ }
27
+ /**
28
+ * Map adapter `arg.type` to JSON Schema primitive.
29
+ * Defaults to "string" for unknown/missing — safer than failing the build.
30
+ */
31
+ export declare function jsonTypeFor(t: string | undefined): string;
32
+ /**
33
+ * Build JSON Schema for a command's input from its `args` definition.
34
+ * Always includes a `limit` parameter (default 20) for result capping.
35
+ */
36
+ export declare function buildInputSchema(cmd: AdapterCommand): JsonSchemaObject;
37
+ /**
38
+ * Build JSON Schema for a command's output.
39
+ *
40
+ * Two formats:
41
+ * - `wrapped` (MCP): `{count: int, results: [{...columns}]}`
42
+ * - `flat` (CLI schema): `[{...columns}]`
43
+ *
44
+ * MCP clients expect the wrapped format; the CLI `unicli schema` command
45
+ * exposes the flat array format for simpler consumption.
46
+ */
47
+ export declare function buildOutputSchema(cmd: AdapterCommand, format?: "wrapped" | "flat"): JsonSchemaObject;
48
+ /**
49
+ * Build normalized MCP tool name: `unicli_<site>_<command>`.
50
+ *
51
+ * Non-alphanumeric chars collapse to `_`. This normalization is NOT
52
+ * reversible — callers must use a lookup table for reverse mapping.
53
+ */
54
+ export declare function buildToolName(site: string, command: string): string;
55
+ /**
56
+ * Approximate token count. Uses `words × 1.3` — closely tracks
57
+ * tiktoken cl100k for English + mixed-case identifiers.
58
+ */
59
+ export declare function approxTokens(text: string): number;
60
+ /**
61
+ * Truncate description to fit within a token budget.
62
+ * Cuts at word boundary, appends "…" when truncated.
63
+ */
64
+ export declare function truncateDescription(desc: string, maxTokens?: number): string;
65
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/mcp/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAYzD;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,gBAAgB,CA6BtE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,cAAc,EACnB,MAAM,GAAE,SAAS,GAAG,MAAkB,GACrC,gBAAgB,CA0BlB;AAID;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnE;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAK,GAAG,MAAM,CAUxE"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Shared JSON Schema builders for MCP tools and CLI schema command.
3
+ *
4
+ * Single source of truth for:
5
+ * - Adapter arg → JSON Schema type mapping
6
+ * - Input/output schema generation from AdapterCommand metadata
7
+ * - Tool name normalization (site + command → MCP tool name)
8
+ * - Description truncation within token budgets
9
+ */
10
+ // ── Type Mapping ────────────────────────────────────────────────────────────
11
+ /**
12
+ * Map adapter `arg.type` to JSON Schema primitive.
13
+ * Defaults to "string" for unknown/missing — safer than failing the build.
14
+ */
15
+ export function jsonTypeFor(t) {
16
+ switch (t) {
17
+ case "int":
18
+ return "integer";
19
+ case "float":
20
+ return "number";
21
+ case "bool":
22
+ return "boolean";
23
+ case "str":
24
+ default:
25
+ return "string";
26
+ }
27
+ }
28
+ // ── Schema Builders ─────────────────────────────────────────────────────────
29
+ /**
30
+ * Build JSON Schema for a command's input from its `args` definition.
31
+ * Always includes a `limit` parameter (default 20) for result capping.
32
+ */
33
+ export function buildInputSchema(cmd) {
34
+ const props = {
35
+ limit: {
36
+ type: "integer",
37
+ description: "Cap result count (default 20)",
38
+ default: 20,
39
+ },
40
+ };
41
+ const required = [];
42
+ for (const a of cmd.adapterArgs ?? []) {
43
+ if (a.name === "limit")
44
+ continue;
45
+ const prop = {
46
+ type: jsonTypeFor(a.type),
47
+ description: a.description,
48
+ };
49
+ if (a.default !== undefined)
50
+ prop.default = a.default;
51
+ if (a.choices)
52
+ prop.enum = a.choices;
53
+ props[a.name] = prop;
54
+ if (a.required)
55
+ required.push(a.name);
56
+ }
57
+ const schema = {
58
+ type: "object",
59
+ properties: props,
60
+ additionalProperties: false,
61
+ };
62
+ if (required.length > 0)
63
+ schema.required = required;
64
+ return schema;
65
+ }
66
+ /**
67
+ * Build JSON Schema for a command's output.
68
+ *
69
+ * Two formats:
70
+ * - `wrapped` (MCP): `{count: int, results: [{...columns}]}`
71
+ * - `flat` (CLI schema): `[{...columns}]`
72
+ *
73
+ * MCP clients expect the wrapped format; the CLI `unicli schema` command
74
+ * exposes the flat array format for simpler consumption.
75
+ */
76
+ export function buildOutputSchema(cmd, format = "wrapped") {
77
+ const itemProps = {};
78
+ for (const col of cmd.columns ?? []) {
79
+ itemProps[col] = { type: "string", description: `Column: ${col}` };
80
+ }
81
+ const itemSchema = {
82
+ type: "object",
83
+ ...(Object.keys(itemProps).length > 0 ? { properties: itemProps } : {}),
84
+ };
85
+ if (format === "flat") {
86
+ return { type: "array", items: itemSchema };
87
+ }
88
+ return {
89
+ type: "object",
90
+ properties: {
91
+ count: { type: "integer", description: "Number of results returned" },
92
+ results: {
93
+ type: "array",
94
+ description: "Result rows",
95
+ items: itemSchema,
96
+ },
97
+ },
98
+ };
99
+ }
100
+ // ── Tool Name ───────────────────────────────────────────────────────────────
101
+ /**
102
+ * Build normalized MCP tool name: `unicli_<site>_<command>`.
103
+ *
104
+ * Non-alphanumeric chars collapse to `_`. This normalization is NOT
105
+ * reversible — callers must use a lookup table for reverse mapping.
106
+ */
107
+ export function buildToolName(site, command) {
108
+ return `unicli_${site}_${command}`.replace(/[^a-zA-Z0-9_]/g, "_");
109
+ }
110
+ // ── Description Truncation ──────────────────────────────────────────────────
111
+ /**
112
+ * Approximate token count. Uses `words × 1.3` — closely tracks
113
+ * tiktoken cl100k for English + mixed-case identifiers.
114
+ */
115
+ export function approxTokens(text) {
116
+ const words = text.split(/\s+/).filter(Boolean).length;
117
+ return Math.ceil(words * 1.3);
118
+ }
119
+ /**
120
+ * Truncate description to fit within a token budget.
121
+ * Cuts at word boundary, appends "…" when truncated.
122
+ */
123
+ export function truncateDescription(desc, maxTokens = 68) {
124
+ if (approxTokens(desc) <= maxTokens)
125
+ return desc;
126
+ const words = desc.split(/\s+/).filter(Boolean);
127
+ let result = "";
128
+ for (const word of words) {
129
+ const candidate = result ? `${result} ${word}` : word;
130
+ if (approxTokens(candidate + " …") > maxTokens)
131
+ break;
132
+ result = candidate;
133
+ }
134
+ return result ? `${result} …` : words[0] + " …";
135
+ }
136
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/mcp/schema.ts"],"names":[],"mappings":"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"}
@@ -3,24 +3,37 @@
3
3
  * MCP (Model Context Protocol) server for Uni-CLI.
4
4
  *
5
5
  * Two registration modes:
6
- * 1. **Expanded (default)** — one tool per adapter command
6
+ * 1. **Smart default** — 3 tools: `unicli_run`, `unicli_list`,
7
+ * `unicli_discover`. Keeps the MCP handshake under 200 tokens.
8
+ * 2. **Expanded (`--expanded`)** — one tool per adapter command
7
9
  * (`unicli_<site>_<command>`) with JSON Schema derived from `args` +
8
- * `columns`. This is the production mode the v0.208 plan calls out:
9
- * MCP clients see the full Uni-CLI surface area without an extra
10
- * list_adapters → run_command roundtrip.
11
- * 2. **Lazy (`--lazy`)** — only `list_adapters` + `run_command` are
12
- * registered. Useful when an MCP client has a hard tool-count limit
13
- * or wants the smallest possible handshake.
10
+ * `columns`. MCP clients see the full Uni-CLI surface area.
14
11
  *
15
- * Two transports:
12
+ * Three transports:
16
13
  * - **stdio (default)** — newline-delimited JSON over stdin/stdout
17
14
  * - **http (`--transport http [--port 19826]`)** — POST /mcp accepts a
18
- * single JSON-RPC envelope and returns a single JSON response. No
19
- * SSE streaming yet additive in a future release.
15
+ * single JSON-RPC envelope and returns a single JSON response.
16
+ * - **sse (`--transport sse [--port 19826]`)** Streamable HTTP with
17
+ * Server-Sent Events. GET /mcp/sse opens the event stream, POST
18
+ * /mcp/message?sessionId=xxx delivers JSON-RPC requests.
20
19
  *
21
20
  * Auth pass-through is automatic: every adapter the CLI loads (including
22
21
  * cookie-based ones) is exposed by name; the runtime resolves cookies on
23
22
  * each call via the same code path as the CLI.
24
23
  */
24
+ interface McpToolResult {
25
+ content: Array<{
26
+ type: "text";
27
+ text: string;
28
+ }>;
29
+ isError?: boolean;
30
+ _meta?: Record<string, unknown>;
31
+ }
32
+ /**
33
+ * Annotate a tool result with `_meta.anthropic/maxResultSizeChars` when the
34
+ * serialized payload exceeds MAX_RESULT_SIZE_CHARS (10 KB). This tells
35
+ * Claude Code to accept large payloads without truncation.
36
+ */
37
+ export declare function annotateIfLarge(result: McpToolResult): McpToolResult;
25
38
  export {};
26
39
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA2DH,UAAU,aAAa;IACrB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAmYD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CASpE"}