clinkx 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/README.md +70 -0
- package/conf/adapters/claude.json +33 -0
- package/conf/adapters/codex.json +33 -0
- package/conf/adapters/gemini.json +33 -0
- package/conf/adapters/glm.json +39 -0
- package/conf/adapters/hapi/claude.json +36 -0
- package/conf/adapters/hapi/codex.json +36 -0
- package/conf/adapters/hapi/gemini.json +36 -0
- package/conf/adapters/hapi/glm.json +40 -0
- package/conf/prompts/codereviewer.txt +8 -0
- package/conf/prompts/debug.txt +6 -0
- package/conf/prompts/default.txt +8 -0
- package/conf/prompts/json.txt +5 -0
- package/conf/prompts/planner.txt +8 -0
- package/dist/artifacts.d.ts +9 -0
- package/dist/artifacts.js +24 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/concurrency.d.ts +15 -0
- package/dist/concurrency.js +39 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/config.d.ts +103 -0
- package/dist/config.js +40 -0
- package/dist/config.js.map +1 -0
- package/dist/continuation.d.ts +15 -0
- package/dist/continuation.js +42 -0
- package/dist/continuation.js.map +1 -0
- package/dist/env.d.ts +10 -0
- package/dist/env.js +52 -0
- package/dist/env.js.map +1 -0
- package/dist/errors.d.ts +68 -0
- package/dist/errors.js +88 -0
- package/dist/errors.js.map +1 -0
- package/dist/handler.d.ts +21 -0
- package/dist/handler.js +45 -0
- package/dist/handler.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.js +30 -0
- package/dist/logger.js.map +1 -0
- package/dist/parsers/claude-json.d.ts +2 -0
- package/dist/parsers/claude-json.js +58 -0
- package/dist/parsers/claude-json.js.map +1 -0
- package/dist/parsers/codex-jsonl.d.ts +2 -0
- package/dist/parsers/codex-jsonl.js +75 -0
- package/dist/parsers/codex-jsonl.js.map +1 -0
- package/dist/parsers/extract.d.ts +25 -0
- package/dist/parsers/extract.js +87 -0
- package/dist/parsers/extract.js.map +1 -0
- package/dist/parsers/gemini-json.d.ts +2 -0
- package/dist/parsers/gemini-json.js +72 -0
- package/dist/parsers/gemini-json.js.map +1 -0
- package/dist/parsers/json-extract.d.ts +2 -0
- package/dist/parsers/json-extract.js +19 -0
- package/dist/parsers/json-extract.js.map +1 -0
- package/dist/parsers/summary.d.ts +7 -0
- package/dist/parsers/summary.js +29 -0
- package/dist/parsers/summary.js.map +1 -0
- package/dist/parsers/text.d.ts +2 -0
- package/dist/parsers/text.js +14 -0
- package/dist/parsers/text.js.map +1 -0
- package/dist/parsers/types.d.ts +25 -0
- package/dist/parsers/types.js +2 -0
- package/dist/parsers/types.js.map +1 -0
- package/dist/parsers/utils.d.ts +11 -0
- package/dist/parsers/utils.js +116 -0
- package/dist/parsers/utils.js.map +1 -0
- package/dist/paths.d.ts +17 -0
- package/dist/paths.js +87 -0
- package/dist/paths.js.map +1 -0
- package/dist/pipeline.d.ts +37 -0
- package/dist/pipeline.js +232 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/progress.d.ts +28 -0
- package/dist/progress.js +78 -0
- package/dist/progress.js.map +1 -0
- package/dist/prompt-mode.d.ts +15 -0
- package/dist/prompt-mode.js +23 -0
- package/dist/prompt-mode.js.map +1 -0
- package/dist/prompt.d.ts +25 -0
- package/dist/prompt.js +108 -0
- package/dist/prompt.js.map +1 -0
- package/dist/registry.d.ts +27 -0
- package/dist/registry.js +163 -0
- package/dist/registry.js.map +1 -0
- package/dist/result-contract.d.ts +13 -0
- package/dist/result-contract.js +80 -0
- package/dist/result-contract.js.map +1 -0
- package/dist/run-dir.d.ts +12 -0
- package/dist/run-dir.js +32 -0
- package/dist/run-dir.js.map +1 -0
- package/dist/runner.d.ts +39 -0
- package/dist/runner.js +220 -0
- package/dist/runner.js.map +1 -0
- package/dist/safety.d.ts +22 -0
- package/dist/safety.js +47 -0
- package/dist/safety.js.map +1 -0
- package/dist/schema.d.ts +69 -0
- package/dist/schema.js +91 -0
- package/dist/schema.js.map +1 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.js +109 -0
- package/dist/server.js.map +1 -0
- package/package.json +34 -0
package/dist/safety.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ExecutionError } from "./errors.js";
|
|
2
|
+
import { logger } from "./logger.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the final CLI args array, optionally merging unsafe_args.
|
|
5
|
+
*
|
|
6
|
+
* Policy (v1.1): the env gate CLINKX_ENABLE_UNSAFE=1 is the sole security
|
|
7
|
+
* boundary. When it is set and the adapter declares non-empty unsafeArgs,
|
|
8
|
+
* they are always included — the per-request `unsafe` flag is no longer
|
|
9
|
+
* required (retained for backward compat but ignored when the env gate
|
|
10
|
+
* is open).
|
|
11
|
+
*
|
|
12
|
+
* Returns the safe args array, optionally merged with unsafe_args.
|
|
13
|
+
*/
|
|
14
|
+
export function resolveArgs(args, unsafeArgs, requestUnsafe) {
|
|
15
|
+
const envEnabled = process.env["CLINKX_ENABLE_UNSAFE"] === "1";
|
|
16
|
+
if (envEnabled && unsafeArgs.length > 0) {
|
|
17
|
+
logger.debug("unsafe_args auto-included (env gate open, unsafeArgs present)");
|
|
18
|
+
return [...args, ...unsafeArgs];
|
|
19
|
+
}
|
|
20
|
+
if (requestUnsafe && !envEnabled) {
|
|
21
|
+
logger.warn("unsafe=true requested but CLINKX_ENABLE_UNSAFE is not set — ignoring unsafe_args");
|
|
22
|
+
}
|
|
23
|
+
return [...args];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build debug metadata object. Returns metadata only when debug=true.
|
|
27
|
+
* Never appends to model output — caller must place in a separate content block.
|
|
28
|
+
*/
|
|
29
|
+
export function buildDebugMetadata(debug, data) {
|
|
30
|
+
if (!debug) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return { _debug: { ...data, timestamp: new Date().toISOString() } };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Guard against adapters that require a TTY.
|
|
37
|
+
* PTY emulation is not supported in v1 — throw ExecutionError with actionable message.
|
|
38
|
+
*/
|
|
39
|
+
export function assertNoTtyRequired(adapterName, requiresTty) {
|
|
40
|
+
if (requiresTty) {
|
|
41
|
+
throw new ExecutionError(`Adapter "${adapterName}" requires a TTY (requires_tty=true), ` +
|
|
42
|
+
"which is not supported in ClinkX v1. " +
|
|
43
|
+
"Either set requires_tty=false in the adapter config, " +
|
|
44
|
+
"or wait for v1.1 which will add PTY support.");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CACzB,IAAuB,EACvB,UAA6B,EAC7B,aAAsB;IAEtB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,GAAG,CAAC;IAE/D,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,IAAI,EAAE,GAAG,UAAU,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,aAAa,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,kFAAkF,CAAC,CAAC;IAClG,CAAC;IAED,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAc,EACd,IAA6B;IAE7B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAmB,EAAE,WAAoB;IAC3E,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAI,cAAc,CACtB,YAAY,WAAW,wCAAwC;YAC7D,uCAAuC;YACvC,uDAAuD;YACvD,8CAA8C,CACjD,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Frozen clink tool input schema (v1 contract).
|
|
4
|
+
*
|
|
5
|
+
* Field names match PAL canonical names for drop-in compatibility.
|
|
6
|
+
* `absolute_file_paths` (not `files`) per PAL parity requirement.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ClinkInputSchema: z.ZodObject<{
|
|
9
|
+
/** The task or question for the subagent. */
|
|
10
|
+
prompt: z.ZodString;
|
|
11
|
+
/** Which CLI to use (resolved against adapter registry). */
|
|
12
|
+
cli_name: z.ZodOptional<z.ZodString>;
|
|
13
|
+
/** Role selector — maps to adapter roles config. */
|
|
14
|
+
role: z.ZodDefault<z.ZodString>;
|
|
15
|
+
/** Absolute file paths to reference (PAL-canonical name). */
|
|
16
|
+
absolute_file_paths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
17
|
+
/** Absolute image paths. */
|
|
18
|
+
images: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
19
|
+
/** Explicit continuation context appended after role/capability/file sections. */
|
|
20
|
+
context: z.ZodOptional<z.ZodString>;
|
|
21
|
+
/** Optional ID for last-response caching (PAL compat). */
|
|
22
|
+
continuation_id: z.ZodOptional<z.ZodString>;
|
|
23
|
+
/**
|
|
24
|
+
* Request timeout override (seconds).
|
|
25
|
+
*
|
|
26
|
+
* NOTE: This field is accepted for backward compatibility, but intentionally
|
|
27
|
+
* not advertised in the MCP tools/list JSON schema to reduce agent-driven
|
|
28
|
+
* overrides of user adapter config.
|
|
29
|
+
*/
|
|
30
|
+
timeout_seconds: z.ZodOptional<z.ZodNumber>;
|
|
31
|
+
/** Legacy flag (retained for compat). Unsafe args are auto-included when CLINKX_ENABLE_UNSAFE=1. */
|
|
32
|
+
unsafe: z.ZodDefault<z.ZodBoolean>;
|
|
33
|
+
/** Enable debug metadata in response. */
|
|
34
|
+
debug: z.ZodDefault<z.ZodBoolean>;
|
|
35
|
+
/** Keep run artifacts after completion (requires debug=true). */
|
|
36
|
+
debug_keep_artifacts: z.ZodDefault<z.ZodBoolean>;
|
|
37
|
+
}, "strict", z.ZodTypeAny, {
|
|
38
|
+
prompt: string;
|
|
39
|
+
role: string;
|
|
40
|
+
unsafe: boolean;
|
|
41
|
+
debug: boolean;
|
|
42
|
+
debug_keep_artifacts: boolean;
|
|
43
|
+
timeout_seconds?: number | undefined;
|
|
44
|
+
cli_name?: string | undefined;
|
|
45
|
+
absolute_file_paths?: string[] | undefined;
|
|
46
|
+
images?: string[] | undefined;
|
|
47
|
+
context?: string | undefined;
|
|
48
|
+
continuation_id?: string | undefined;
|
|
49
|
+
}, {
|
|
50
|
+
prompt: string;
|
|
51
|
+
timeout_seconds?: number | undefined;
|
|
52
|
+
cli_name?: string | undefined;
|
|
53
|
+
role?: string | undefined;
|
|
54
|
+
absolute_file_paths?: string[] | undefined;
|
|
55
|
+
images?: string[] | undefined;
|
|
56
|
+
context?: string | undefined;
|
|
57
|
+
continuation_id?: string | undefined;
|
|
58
|
+
unsafe?: boolean | undefined;
|
|
59
|
+
debug?: boolean | undefined;
|
|
60
|
+
debug_keep_artifacts?: boolean | undefined;
|
|
61
|
+
}>;
|
|
62
|
+
export type ClinkInput = z.infer<typeof ClinkInputSchema>;
|
|
63
|
+
/**
|
|
64
|
+
* Convert the clink zod schema to JSON Schema for MCP tools/list.
|
|
65
|
+
*
|
|
66
|
+
* Uses zod-to-json-schema with target "jsonSchema7" for broad
|
|
67
|
+
* MCP client compatibility.
|
|
68
|
+
*/
|
|
69
|
+
export declare function clinkJsonSchema(): Record<string, unknown>;
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
3
|
+
/**
|
|
4
|
+
* Frozen clink tool input schema (v1 contract).
|
|
5
|
+
*
|
|
6
|
+
* Field names match PAL canonical names for drop-in compatibility.
|
|
7
|
+
* `absolute_file_paths` (not `files`) per PAL parity requirement.
|
|
8
|
+
*/
|
|
9
|
+
export const ClinkInputSchema = z
|
|
10
|
+
.object({
|
|
11
|
+
/** The task or question for the subagent. */
|
|
12
|
+
prompt: z.string().describe("The task or question for the subagent"),
|
|
13
|
+
/** Which CLI to use (resolved against adapter registry). */
|
|
14
|
+
cli_name: z
|
|
15
|
+
.string()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe("Which CLI to use"),
|
|
18
|
+
/** Role selector — maps to adapter roles config. */
|
|
19
|
+
role: z
|
|
20
|
+
.string()
|
|
21
|
+
.default("default")
|
|
22
|
+
.describe('Role for the subagent. Use "default" for standard role instructions, or select a specific role.'),
|
|
23
|
+
/** Absolute file paths to reference (PAL-canonical name). */
|
|
24
|
+
absolute_file_paths: z
|
|
25
|
+
.array(z.string())
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("Absolute file paths to reference"),
|
|
28
|
+
/** Absolute image paths. */
|
|
29
|
+
images: z
|
|
30
|
+
.array(z.string())
|
|
31
|
+
.optional()
|
|
32
|
+
.describe("Absolute image paths"),
|
|
33
|
+
/** Explicit continuation context appended after role/capability/file sections. */
|
|
34
|
+
context: z
|
|
35
|
+
.string()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("Explicit continuation context (appended after role/capability/file sections)"),
|
|
38
|
+
/** Optional ID for last-response caching (PAL compat). */
|
|
39
|
+
continuation_id: z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe("Optional ID for last-response caching"),
|
|
43
|
+
/**
|
|
44
|
+
* Request timeout override (seconds).
|
|
45
|
+
*
|
|
46
|
+
* NOTE: This field is accepted for backward compatibility, but intentionally
|
|
47
|
+
* not advertised in the MCP tools/list JSON schema to reduce agent-driven
|
|
48
|
+
* overrides of user adapter config.
|
|
49
|
+
*/
|
|
50
|
+
timeout_seconds: z
|
|
51
|
+
.number()
|
|
52
|
+
.positive()
|
|
53
|
+
.optional()
|
|
54
|
+
.describe("Request timeout override (seconds)"),
|
|
55
|
+
/** Legacy flag (retained for compat). Unsafe args are auto-included when CLINKX_ENABLE_UNSAFE=1. */
|
|
56
|
+
unsafe: z
|
|
57
|
+
.boolean()
|
|
58
|
+
.default(false)
|
|
59
|
+
.describe("Legacy flag, retained for compatibility. Unsafe args are auto-included when CLINKX_ENABLE_UNSAFE=1."),
|
|
60
|
+
/** Enable debug metadata in response. */
|
|
61
|
+
debug: z.boolean().default(false).describe("Include debug metadata"),
|
|
62
|
+
/** Keep run artifacts after completion (requires debug=true). */
|
|
63
|
+
debug_keep_artifacts: z
|
|
64
|
+
.boolean()
|
|
65
|
+
.default(false)
|
|
66
|
+
.describe("Keep run artifacts after completion"),
|
|
67
|
+
})
|
|
68
|
+
.strict();
|
|
69
|
+
/**
|
|
70
|
+
* Convert the clink zod schema to JSON Schema for MCP tools/list.
|
|
71
|
+
*
|
|
72
|
+
* Uses zod-to-json-schema with target "jsonSchema7" for broad
|
|
73
|
+
* MCP client compatibility.
|
|
74
|
+
*/
|
|
75
|
+
export function clinkJsonSchema() {
|
|
76
|
+
const schema = zodToJsonSchema(ClinkInputSchema, {
|
|
77
|
+
target: "jsonSchema7",
|
|
78
|
+
$refStrategy: "none",
|
|
79
|
+
});
|
|
80
|
+
// Do not advertise timeout_seconds in tools/list schema.
|
|
81
|
+
// We still accept it in the runtime zod parse for backward compatibility.
|
|
82
|
+
// Note: additionalProperties: false remains in the schema, which means a client
|
|
83
|
+
// doing outbound schema validation would reject timeout_seconds. This is acceptable
|
|
84
|
+
// because MCP clients don't validate outbound requests against the tool schema.
|
|
85
|
+
const props = schema["properties"];
|
|
86
|
+
if (props != null) {
|
|
87
|
+
delete props["timeout_seconds"];
|
|
88
|
+
}
|
|
89
|
+
return schema;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC;KAC9B,MAAM,CAAC;IACN,6CAA6C;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;IAEpE,4DAA4D;IAC5D,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,kBAAkB,CAAC;IAE/B,oDAAoD;IACpD,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,OAAO,CAAC,SAAS,CAAC;SAClB,QAAQ,CAAC,iGAAiG,CAAC;IAE9G,6DAA6D;IAC7D,mBAAmB,EAAE,CAAC;SACnB,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,kCAAkC,CAAC;IAE/C,4BAA4B;IAC5B,MAAM,EAAE,CAAC;SACN,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,sBAAsB,CAAC;IAEnC,kFAAkF;IAClF,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,8EAA8E,CAC/E;IAEH,0DAA0D;IAC1D,eAAe,EAAE,CAAC;SACf,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,uCAAuC,CAAC;IAEpD;;;;;;OAMG;IACH,eAAe,EAAE,CAAC;SACf,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,QAAQ,CAAC,oCAAoC,CAAC;IAEjD,oGAAoG;IACpG,MAAM,EAAE,CAAC;SACN,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,qGAAqG,CAAC;IAElH,yCAAyC;IACzC,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IAEpE,iEAAiE;IACjE,oBAAoB,EAAE,CAAC;SACpB,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,qCAAqC,CAAC;CACnD,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAG,eAAe,CAAC,gBAAgB,EAAE;QAC/C,MAAM,EAAE,aAAa;QACrB,YAAY,EAAE,MAAM;KACrB,CAA4B,CAAC;IAE9B,yDAAyD;IACzD,0EAA0E;IAC1E,gFAAgF;IAChF,oFAAoF;IACpF,gFAAgF;IAChF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAwC,CAAC;IAC1E,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create and configure the ClinkX MCP server.
|
|
4
|
+
*
|
|
5
|
+
* Registers two handlers:
|
|
6
|
+
* - tools/list: returns the single `clink` tool with its JSON schema
|
|
7
|
+
* - tools/call: validates + dispatches to the clink handler pipeline
|
|
8
|
+
*
|
|
9
|
+
* Does NOT connect transport — caller is responsible for that.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createServer(): Server;
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import { clinkJsonSchema } from "./schema.js";
|
|
4
|
+
import { handleClink } from "./handler.js";
|
|
5
|
+
import { handleToolError, CancellationError } from "./errors.js";
|
|
6
|
+
import { logger } from "./logger.js";
|
|
7
|
+
import { extractProgressToken } from "./progress.js";
|
|
8
|
+
import { AdapterRegistry } from "./registry.js";
|
|
9
|
+
/**
|
|
10
|
+
* Create and configure the ClinkX MCP server.
|
|
11
|
+
*
|
|
12
|
+
* Registers two handlers:
|
|
13
|
+
* - tools/list: returns the single `clink` tool with its JSON schema
|
|
14
|
+
* - tools/call: validates + dispatches to the clink handler pipeline
|
|
15
|
+
*
|
|
16
|
+
* Does NOT connect transport — caller is responsible for that.
|
|
17
|
+
*/
|
|
18
|
+
export function createServer() {
|
|
19
|
+
const server = new Server({ name: "clinkx", version: "1.0.0" }, {
|
|
20
|
+
capabilities: { tools: {} },
|
|
21
|
+
instructions: "ClinkX bridges requests to external CLI subagents (e.g. Gemini, Codex, Claude) " +
|
|
22
|
+
"as subprocesses and returns their output. Use the clink tool to delegate tasks " +
|
|
23
|
+
"to any configured CLI. Multiple clink calls can run in parallel for independent tasks.",
|
|
24
|
+
});
|
|
25
|
+
// Eagerly load adapter names + role names for tool description & schema enum (once, not per-request)
|
|
26
|
+
let cliSuffix = "";
|
|
27
|
+
let cliNames = [];
|
|
28
|
+
let roleNames = [];
|
|
29
|
+
try {
|
|
30
|
+
const registry = AdapterRegistry.load();
|
|
31
|
+
cliNames = registry.getAdapterNames();
|
|
32
|
+
roleNames = registry.getAllRoleNames();
|
|
33
|
+
if (cliNames.length > 0) {
|
|
34
|
+
cliSuffix = ` Available CLIs: ${cliNames.join(", ")}.`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
logger.warn({ err }, "failed to load adapter registry for tool description");
|
|
39
|
+
}
|
|
40
|
+
// tools/list — advertise the clink tool with dynamic CLI names
|
|
41
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
42
|
+
const schema = clinkJsonSchema();
|
|
43
|
+
// Inject enum arrays into cli_name and role properties (Fix 1)
|
|
44
|
+
const props = schema["properties"];
|
|
45
|
+
if (props != null) {
|
|
46
|
+
if (cliNames.length > 0 && props["cli_name"] != null) {
|
|
47
|
+
props["cli_name"]["enum"] = cliNames;
|
|
48
|
+
props["cli_name"]["description"] =
|
|
49
|
+
`Which CLI to use. Available: ${cliNames.join(", ")}`;
|
|
50
|
+
}
|
|
51
|
+
if (roleNames.length > 0 && props["role"] != null) {
|
|
52
|
+
const roleEnum = [...new Set(["default", ...roleNames.filter(r => r !== "none")])].sort();
|
|
53
|
+
props["role"]["enum"] = roleEnum;
|
|
54
|
+
props["role"]["description"] =
|
|
55
|
+
`Role for the subagent — use "default" unless a specific role is needed. Available: ${roleEnum.join(", ")}.`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
tools: [
|
|
60
|
+
{
|
|
61
|
+
name: "clink",
|
|
62
|
+
description: "Execute a configured local CLI as a subagent and return the model's final output." +
|
|
63
|
+
" Multiple clink calls can run in parallel for independent tasks." +
|
|
64
|
+
" Pass file paths via absolute_file_paths rather than inlining content." +
|
|
65
|
+
cliSuffix,
|
|
66
|
+
inputSchema: schema,
|
|
67
|
+
annotations: {
|
|
68
|
+
// readOnlyHint: true enables MCP clients to dispatch multiple clink calls
|
|
69
|
+
// in parallel. Despite subprocesses potentially writing files, this matches
|
|
70
|
+
// PAL's behavior — the MCP spec treats annotations as hints, not contracts.
|
|
71
|
+
readOnlyHint: true,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
// tools/call — dispatch clink invocations with cancellation support
|
|
78
|
+
server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
79
|
+
const { name, arguments: args } = request.params;
|
|
80
|
+
if (name !== "clink") {
|
|
81
|
+
logger.warn({ tool: name }, "unknown tool requested");
|
|
82
|
+
return {
|
|
83
|
+
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
84
|
+
isError: true,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const progressToken = extractProgressToken(request.params);
|
|
88
|
+
try {
|
|
89
|
+
return await handleClink(args, {
|
|
90
|
+
...(extra.signal != null ? { signal: extra.signal } : {}),
|
|
91
|
+
...(progressToken != null
|
|
92
|
+
? { progress: { server, token: progressToken } }
|
|
93
|
+
: {}),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
if (err instanceof CancellationError) {
|
|
98
|
+
// MCP spec: do NOT send a response for cancelled requests.
|
|
99
|
+
// Re-throw so the SDK handles it properly.
|
|
100
|
+
throw err;
|
|
101
|
+
}
|
|
102
|
+
// handleToolError re-throws McpError for InvalidParamsError (-32602),
|
|
103
|
+
// returns { isError: true } for everything else.
|
|
104
|
+
return handleToolError(err);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return server;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EACpC;QACE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAC3B,YAAY,EACV,iFAAiF;YACjF,iFAAiF;YACjF,wFAAwF;KAC3F,CACF,CAAC;IAEF,qGAAqG;IACrG,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,QAAQ,GAAa,EAAE,CAAC;IAC5B,IAAI,SAAS,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC;QACxC,QAAQ,GAAG,QAAQ,CAAC,eAAe,EAAE,CAAC;QACtC,SAAS,GAAG,QAAQ,CAAC,eAAe,EAAE,CAAC;QACvC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,SAAS,GAAG,oBAAoB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QACzD,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,sDAAsD,CAAC,CAAC;IAC/E,CAAC;IAED,+DAA+D;IAC/D,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;QAEjC,+DAA+D;QAC/D,MAAM,KAAK,GAAI,MAAkC,CAAC,YAAY,CAEjD,CAAC;QACd,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrD,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;gBACrC,KAAK,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;oBAC9B,gCAAgC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1D,CAAC;YACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBAClD,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC1F,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;gBACjC,KAAK,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC;oBAC1B,sFAAsF,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;YACjH,CAAC;QACH,CAAC;QAED,OAAO;YACL,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,OAAO;oBACb,WAAW,EACT,mFAAmF;wBACnF,kEAAkE;wBAClE,wEAAwE;wBACxE,SAAS;oBACX,WAAW,EAAE,MAAM;oBACnB,WAAW,EAAE;wBACX,0EAA0E;wBAC1E,4EAA4E;wBAC5E,4EAA4E;wBAC5E,YAAY,EAAE,IAAI;qBACnB;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,oEAAoE;IACpE,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAEjD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,wBAAwB,CAAC,CAAC;YACtD,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC;gBACnE,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,aAAa,GAAG,oBAAoB,CACxC,OAAO,CAAC,MAA4C,CACrD,CAAC;QAEF,IAAI,CAAC;YACH,OAAO,MAAM,WAAW,CAAC,IAAI,EAAE;gBAC7B,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,GAAG,CAAC,aAAa,IAAI,IAAI;oBACvB,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE;oBAChD,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAI,GAAG,YAAY,iBAAiB,EAAE,CAAC;gBACrC,2DAA2D;gBAC3D,2CAA2C;gBAC3C,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,sEAAsE;YACtE,iDAAiD;YACjD,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clinkx",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "ClinkX MCP STDIO server — CLI-to-CLI bridge tool",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=24.0.0"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"bin": {
|
|
11
|
+
"clinkx": "dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"conf"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"start": "node dist/index.js",
|
|
20
|
+
"test": "vitest run"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
24
|
+
"pino": "^9.6.0",
|
|
25
|
+
"zod": "^3.24.0",
|
|
26
|
+
"zod-to-json-schema": "^3.24.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^22.0.0",
|
|
30
|
+
"typescript": "^5.7.0",
|
|
31
|
+
"vitest": "^3.0.0"
|
|
32
|
+
},
|
|
33
|
+
"license": "MIT"
|
|
34
|
+
}
|