@clien-ai/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.
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Canonical exit codes for `clien-mcp`.
3
+ *
4
+ * Agents that script around the CLI use these to decide retry/branch behavior
5
+ * (e.g. don't retry on `INVALID_ARGS`, do retry on `NETWORK_FAIL`). Keep the
6
+ * numbers stable across versions — the README documents them publicly.
7
+ *
8
+ * If you add a new code, add a row to the exit-code table in mcp/README.md.
9
+ */
10
+ export const EXIT_CODES = {
11
+ /** Success. */
12
+ SUCCESS: 0,
13
+ /** Generic / uncategorized failure. */
14
+ GENERIC_ERROR: 1,
15
+ /** Authentication failed (refresh token rejected, OAuth flow aborted, etc.). */
16
+ AUTH_FAIL: 2,
17
+ /** Filesystem operation failed (permission denied, disk full, ENOTDIR, ...). */
18
+ FS_FAIL: 3,
19
+ /** Network operation failed (DNS, connection refused, timeout). */
20
+ NETWORK_FAIL: 4,
21
+ /** CLI argument validation failed (unknown flag, missing value, etc.). */
22
+ INVALID_ARGS: 5,
23
+ };
24
+ /**
25
+ * Classify a thrown error into one of the canonical exit codes. Falls back to
26
+ * GENERIC_ERROR when no rule matches. Used by cli.ts's top-level catch so
27
+ * agents can distinguish failure classes without parsing message strings.
28
+ */
29
+ /**
30
+ * Network/transient OAuth codes — these signal "retry or check connectivity",
31
+ * not "credentials are bad". Includes lock-file contention, port unavailability
32
+ * during loopback bind (someone else has 7873/7874/7875), and Supabase
33
+ * server-side failures (5xx replayed as oauth_5NN by postForm).
34
+ */
35
+ const NETWORK_OAUTH_CODES = new Set([
36
+ 'oauth_network_error',
37
+ 'oauth_timeout',
38
+ 'lock_unavailable',
39
+ 'port_unavailable',
40
+ ]);
41
+ /**
42
+ * Auth-class OAuth codes — credentials are genuinely bad, re-OAuth needed.
43
+ * Explicit positive list rather than a `startsWith('oauth_')` catch-all so a
44
+ * future code defaults to GENERIC_ERROR (loud, surfaces the gap) rather than
45
+ * being silently mis-classified as AUTH_FAIL.
46
+ */
47
+ const AUTH_OAUTH_CODES = new Set([
48
+ 'invalid_grant',
49
+ 'refresh_token_already_used',
50
+ 'refresh_token_not_found',
51
+ 'access_denied',
52
+ 'oauth_invalid_response',
53
+ 'oauth_400',
54
+ 'oauth_401',
55
+ 'oauth_403',
56
+ 'state_mismatch',
57
+ 'invalid_callback',
58
+ ]);
59
+ /** Node fs errno codes that map to FS_FAIL. */
60
+ const FS_ERRNO_CODES = new Set([
61
+ 'ENOENT',
62
+ 'EACCES',
63
+ 'EPERM',
64
+ 'ENOTDIR',
65
+ 'EEXIST',
66
+ 'ENOSPC',
67
+ 'EROFS',
68
+ ]);
69
+ export function classifyError(err) {
70
+ if (!err)
71
+ return EXIT_CODES.GENERIC_ERROR;
72
+ // OAuthError exposes a `code` field — see auth/oauth.ts:OAuthError
73
+ const code = err.code;
74
+ if (typeof code === 'string') {
75
+ if (NETWORK_OAUTH_CODES.has(code))
76
+ return EXIT_CODES.NETWORK_FAIL;
77
+ if (AUTH_OAUTH_CODES.has(code))
78
+ return EXIT_CODES.AUTH_FAIL;
79
+ if (FS_ERRNO_CODES.has(code))
80
+ return EXIT_CODES.FS_FAIL;
81
+ // Supabase replays HTTP 5xx as `oauth_5NN`. Treat as transient/network
82
+ // even though the code namespace is OAuth — the failure mode is a server
83
+ // hiccup, not a credential problem. Agents should retry, not re-auth.
84
+ if (/^oauth_5\d{2}$/.test(code))
85
+ return EXIT_CODES.NETWORK_FAIL;
86
+ }
87
+ // Node fetch surfaces network failures as TypeError with cause
88
+ const name = err.name;
89
+ if (name === 'AbortError' || name === 'TimeoutError') {
90
+ return EXIT_CODES.NETWORK_FAIL;
91
+ }
92
+ if (err instanceof TypeError && /fetch failed/i.test(err.message)) {
93
+ return EXIT_CODES.NETWORK_FAIL;
94
+ }
95
+ return EXIT_CODES.GENERIC_ERROR;
96
+ }
97
+ //# sourceMappingURL=exit-codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../../src/util/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,eAAe;IACf,OAAO,EAAE,CAAC;IACV,uCAAuC;IACvC,aAAa,EAAE,CAAC;IAChB,gFAAgF;IAChF,SAAS,EAAE,CAAC;IACZ,gFAAgF;IAChF,OAAO,EAAE,CAAC;IACV,mEAAmE;IACnE,YAAY,EAAE,CAAC;IACf,0EAA0E;IAC1E,YAAY,EAAE,CAAC;CACP,CAAA;AAKV;;;;GAIG;AACH;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,qBAAqB;IACrB,eAAe;IACf,kBAAkB;IAClB,kBAAkB;CACnB,CAAC,CAAA;AAEF;;;;;GAKG;AACH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,eAAe;IACf,4BAA4B;IAC5B,yBAAyB;IACzB,eAAe;IACf,wBAAwB;IACxB,WAAW;IACX,WAAW;IACX,WAAW;IACX,gBAAgB;IAChB,kBAAkB;CACnB,CAAC,CAAA;AAEF,+CAA+C;AAC/C,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,OAAO;CACR,CAAC,CAAA;AAEF,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,IAAI,CAAC,GAAG;QAAE,OAAO,UAAU,CAAC,aAAa,CAAA;IAEzC,mEAAmE;IACnE,MAAM,IAAI,GAAI,GAAyB,CAAC,IAAI,CAAA;IAC5C,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,UAAU,CAAC,YAAY,CAAA;QACjE,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,UAAU,CAAC,SAAS,CAAA;QAC3D,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,UAAU,CAAC,OAAO,CAAA;QACvD,uEAAuE;QACvE,yEAAyE;QACzE,sEAAsE;QACtE,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,UAAU,CAAC,YAAY,CAAA;IACjE,CAAC;IAED,+DAA+D;IAC/D,MAAM,IAAI,GAAI,GAAyB,CAAC,IAAI,CAAA;IAC5C,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QACrD,OAAO,UAAU,CAAC,YAAY,CAAA;IAChC,CAAC;IACD,IAAI,GAAG,YAAY,SAAS,IAAI,eAAe,CAAC,IAAI,CAAE,GAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7E,OAAO,UAAU,CAAC,YAAY,CAAA;IAChC,CAAC;IAED,OAAO,UAAU,CAAC,aAAa,CAAA;AACjC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@clien-ai/mcp",
3
+ "version": "0.1.0",
4
+ "description": "Clien.ai MCP server — deep product research from Claude Code.",
5
+ "keywords": [
6
+ "mcp",
7
+ "modelcontextprotocol",
8
+ "claude-code",
9
+ "clien.ai",
10
+ "product-research"
11
+ ],
12
+ "homepage": "https://clien.ai",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/AlexOmey/clien-ai.git",
16
+ "directory": "mcp"
17
+ },
18
+ "license": "UNLICENSED",
19
+ "type": "module",
20
+ "main": "./dist/server.js",
21
+ "bin": {
22
+ "clien-mcp": "./dist/cli.js"
23
+ },
24
+ "files": [
25
+ "dist/",
26
+ "README.md"
27
+ ],
28
+ "scripts": {
29
+ "build": "tsc",
30
+ "start": "tsx src/cli.ts",
31
+ "typecheck": "tsc --noEmit",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest"
34
+ },
35
+ "dependencies": {
36
+ "@modelcontextprotocol/sdk": "^1.29.0",
37
+ "open": "^10.1.0",
38
+ "proper-lockfile": "^4.1.2",
39
+ "zod": "^4.0.5"
40
+ },
41
+ "optionalDependencies": {
42
+ "keytar": "^7.9.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^20",
46
+ "@types/proper-lockfile": "^4.1.4",
47
+ "tsx": "^4.20.4",
48
+ "typescript": "^5",
49
+ "vitest": "^3.2.4"
50
+ },
51
+ "engines": {
52
+ "node": ">=20.0.0"
53
+ }
54
+ }