@plurnk/plurnk-mcp 1.4.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/.env.defaults ADDED
@@ -0,0 +1,19 @@
1
+ # --- @plurnk/plurnk-mcp : current MCP host module ---
2
+
3
+ # Bound only connection and protocol discovery. Individual MCP operations use
4
+ # the request timeout below and remain cancellable through their Plurnk run.
5
+ PLURNK_MCP_CONNECT_TIMEOUT=30000
6
+ PLURNK_MCP_REQUEST_TIMEOUT=86400000
7
+
8
+ # Each configured server becomes EXEC[<server>] and <server>://.
9
+ #
10
+ # Streamable HTTP:
11
+ # PLURNK_MCP_github=https://example.test/mcp
12
+ # PLURNK_MCP_github_HEADERS={"Authorization":"Bearer ${GITHUB_TOKEN}"}
13
+ #
14
+ # stdio: the target is one executable. Arguments are a JSON array so Plurnk
15
+ # does not invent or interpret a shell command language.
16
+ # PLURNK_MCP_atlas=node
17
+ # PLURNK_MCP_atlas_ARGS=["/absolute/path/to/atlas-server.mjs"]
18
+ # PLURNK_MCP_atlas_CWD=/absolute/working/directory
19
+ # PLURNK_MCP_atlas_ENV={"TOKEN":"${ATLAS_TOKEN}"}
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PossumTech Laboratories
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # @plurnk/plurnk-mcp
2
+
3
+ The current [Model Context Protocol](https://modelcontextprotocol.io/) host
4
+ module for [Plurnk](https://github.com/plurnk/plurnk-service).
5
+
6
+ Each configured MCP server becomes a model-facing executor and resource
7
+ authority:
8
+
9
+ ```text
10
+ <<READ(github:///):READ
11
+ <<EXEC[github](create_issue):{"title":"Bug"}:EXEC
12
+ <<FIND(github:///resources/**)::FIND
13
+ <<READ(github:///resources/https%3A%2F%2Fexample.test%2Fdocument)::READ
14
+ ```
15
+
16
+ The module requires protocol revision `2026-07-28`. It does not negotiate or
17
+ fall back to a legacy revision.
18
+
19
+ ## Configuration
20
+
21
+ Configuration is daemon-owned. One `PLURNK_MCP_<server>` variable declares
22
+ each server; the suffix case-folds to the executor and URI authority name.
23
+
24
+ Streamable HTTP:
25
+
26
+ ```text
27
+ PLURNK_MCP_github=https://example.test/mcp
28
+ PLURNK_MCP_github_HEADERS={"Authorization":"Bearer ${GITHUB_TOKEN}"}
29
+ ```
30
+
31
+ Stdio:
32
+
33
+ ```text
34
+ PLURNK_MCP_local=/absolute/path/to/executable
35
+ PLURNK_MCP_local_ARGS=["--stdio"]
36
+ PLURNK_MCP_local_CWD=/absolute/working/directory
37
+ PLURNK_MCP_local_ENV={"TOKEN":"${LOCAL_TOKEN}"}
38
+ ```
39
+
40
+ The stdio target is exactly one executable. Arguments are a JSON array; the
41
+ module never parses or invokes a shell command. `${NAME}` references read the
42
+ daemon's inherited environment at startup, so secrets do not need to be copied
43
+ into Plurnk environment files.
44
+
45
+ Portable timeout defaults and complete examples live in
46
+ [`.env.defaults`](./.env.defaults).
47
+
48
+ ## Current surface
49
+
50
+ - `READ(server:///)` returns the live tools, resources, resource templates, and
51
+ prompts catalog.
52
+ - `EXEC[server](tool)` calls a tool with one JSON object in the body.
53
+ - `server:///resources` exposes the resource catalog through ordinary Plurnk
54
+ `FIND` and `READ`.
55
+ - `server:///resources/<encoded-uri>` reads a concrete MCP resource and stores
56
+ it as an ordinary entry, after which normal projection and slicing apply.
57
+ - A tool's `readOnlyHint` selects Plurnk's read effect. Unknown or mutating
58
+ tools retain the host effect.
59
+
60
+ Prompt retrieval, resource subscriptions, current multi-round-trip input,
61
+ current task methods, and OAuth/OIDC authorization are not part of this
62
+ vertical slice. They will use the same module and connection seams; no legacy
63
+ protocol surface is retained as a fallback.
64
+
65
+ ## Verification
66
+
67
+ `npm test` type-checks the module and exercises exact current-version
68
+ negotiation, configuration, tool calls, resource reads, runtime registration,
69
+ and rejection of ambiguous shell and secret configuration.
package/SPEC.md ADDED
@@ -0,0 +1,48 @@
1
+ # Plurnk MCP host specification
2
+
3
+ ## Current protocol boundary
4
+
5
+ - The only accepted MCP revision is `2026-07-28`.
6
+ - Every client connection pins that revision and verifies a modern
7
+ `server/discover` result before registration.
8
+ - Stdio servers are invoked as an executable plus an explicit argument array.
9
+ Shell command parsing is not part of the contract.
10
+ - HTTP uses Streamable HTTP. There is no legacy SSE fallback.
11
+ - A connection or discovery failure leaves no registered runtime.
12
+ - Shutdown waits for every connection attempt to settle, then closes every
13
+ acquired connection and reports all close failures.
14
+
15
+ ## Configuration
16
+
17
+ | Variable | Contract |
18
+ |---|---|
19
+ | `PLURNK_MCP_<server>` | HTTP(S) URL or exact stdio executable |
20
+ | `PLURNK_MCP_<server>_ARGS` | JSON string array for stdio |
21
+ | `PLURNK_MCP_<server>_CWD` | Working directory for stdio |
22
+ | `PLURNK_MCP_<server>_ENV` | JSON string map for stdio |
23
+ | `PLURNK_MCP_<server>_HEADERS` | JSON string map for HTTP |
24
+ | `PLURNK_MCP_CONNECT_TIMEOUT` | Positive integer milliseconds |
25
+ | `PLURNK_MCP_REQUEST_TIMEOUT` | Positive integer milliseconds |
26
+
27
+ Server names case-fold. Duplicate names, orphan companions, transport-specific
28
+ companions on the wrong transport, missing environment references, and invalid
29
+ JSON fail startup.
30
+
31
+ ## Model-facing mapping
32
+
33
+ | MCP surface | Plurnk surface |
34
+ |---|---|
35
+ | Server | `EXEC[server]` and `server://` |
36
+ | Tool catalog | `server:///` |
37
+ | Tool call | `EXEC[server](tool)` with a JSON object body |
38
+ | Resource catalog | `server:///resources` |
39
+ | Resource read | `server:///resources/<encoded-uri>` |
40
+
41
+ The executor manifest remains the owner of ordinary result coordinates. The
42
+ MCP resource facet claims only `/`, `/resources`, and descendants. Every other
43
+ path uses the standard executor-output scheme.
44
+
45
+ Tools and resources are current in this vertical slice. Cataloged prompts are
46
+ descriptive only. Prompt retrieval, subscriptions, multi-round-trip input,
47
+ tasks, and authorization remain unavailable until their current contracts are
48
+ implemented and covered; they do not fall back to legacy behavior.
@@ -0,0 +1,16 @@
1
+ import { BaseExecutor } from "@plurnk/plurnk-execs";
2
+ import type { ChannelDecl, Effect, ExecArgs, ExecResult, RuntimeAvailability, RuntimeDecl } from "@plurnk/plurnk-execs";
3
+ import ServerConnection from "./client.ts";
4
+ export declare const runtimeDecl: (name: string) => RuntimeDecl;
5
+ export default class McpExecutor extends BaseExecutor {
6
+ #private;
7
+ constructor(metadata: {
8
+ runtime: string;
9
+ glyph: string;
10
+ }, connection: ServerConnection);
11
+ get channels(): Readonly<Record<string, ChannelDecl>>;
12
+ effect(target: string | null): Effect;
13
+ probe(signal?: AbortSignal): Promise<RuntimeAvailability>;
14
+ run({ runtime, command, target, signal, write, setState, }: ExecArgs): Promise<ExecResult>;
15
+ }
16
+ //# sourceMappingURL=McpExecutor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpExecutor.d.ts","sourceRoot":"","sources":["../src/McpExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,YAAY,EAIf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACR,WAAW,EACX,MAAM,EACN,QAAQ,EACR,UAAU,EACV,mBAAmB,EACnB,WAAW,EACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,gBAAgB,MAAM,aAAa,CAAC;AAI3C,eAAO,MAAM,WAAW,SAAU,MAAM,KAAG,WAiBzC,CAAC;AAKH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,YAAY;;IAGjD,YACI,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAC5C,UAAU,EAAE,gBAAgB,EAI/B;IAED,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAMpD;IAEQ,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAG7C;IAEc,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAyBvE;IAEK,GAAG,CAAC,EACN,OAAO,EACP,OAAO,EACP,MAAM,EACN,MAAM,EACN,KAAK,EACL,QAAQ,GACX,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CA0FhC;CACJ"}
@@ -0,0 +1,127 @@
1
+ import { BaseExecutor, ErrorDetail, ERROR_DETAIL_LIMIT, Results, } from "@plurnk/plurnk-execs";
2
+ const CHANNEL = "body";
3
+ export const runtimeDecl = (name) => ({
4
+ name,
5
+ glyph: "🔌",
6
+ example: `<<EXEC[${name}](tool_name):{"argument":"value"}:EXEC`,
7
+ documentation: `# ${name}
8
+
9
+ This configured MCP server is available as an executable tool family and an
10
+ addressable resource family.
11
+
12
+ \`\`\`plurnk
13
+ <<READ(${name}:///):READ
14
+ <<EXEC[${name}](tool_name):{"argument":"value"}:EXEC
15
+ \`\`\`
16
+
17
+ READ returns the live catalog. Tool arguments are one JSON object. Tool results
18
+ are written to the operation's \`body\` channel.
19
+ `,
20
+ });
21
+ const message = (error) => error instanceof Error ? error.message : String(error);
22
+ export default class McpExecutor extends BaseExecutor {
23
+ #connection;
24
+ constructor(metadata, connection) {
25
+ super(metadata);
26
+ this.#connection = connection;
27
+ }
28
+ get channels() {
29
+ return {
30
+ [CHANNEL]: {
31
+ mimetype: "application/json",
32
+ },
33
+ };
34
+ }
35
+ effect(target) {
36
+ if (target === null || target.length === 0)
37
+ return "read";
38
+ return this.#connection.readOnly(target) ? "read" : "host";
39
+ }
40
+ async probe(signal) {
41
+ const detailLimit = ErrorDetail.configuredLimit();
42
+ if (detailLimit === null) {
43
+ return {
44
+ available: false,
45
+ detail: `${ERROR_DETAIL_LIMIT} must be set to a non-negative integer.`,
46
+ };
47
+ }
48
+ try {
49
+ const catalog = await this.#connection.catalog(signal);
50
+ return {
51
+ available: true,
52
+ detail: [
53
+ `MCP ${catalog.protocolVersion}`,
54
+ `${catalog.tools.length} tools`,
55
+ `${catalog.resources.length} resources`,
56
+ `${catalog.prompts.length} prompts`,
57
+ ].join("; "),
58
+ };
59
+ }
60
+ catch (error) {
61
+ return {
62
+ available: false,
63
+ detail: ErrorDetail.preview(message(error), detailLimit),
64
+ };
65
+ }
66
+ }
67
+ async run({ runtime, command, target, signal, write, setState, }) {
68
+ const fail = (code, status, detail, extensions) => {
69
+ setState(CHANNEL, "errored");
70
+ return Results.failure("executor:mcp", code, status, detail, {}, {
71
+ runtime,
72
+ stage: "mcp",
73
+ ...extensions,
74
+ });
75
+ };
76
+ const detailLimit = ErrorDetail.configuredLimit();
77
+ if (detailLimit === null) {
78
+ setState(CHANNEL, "errored");
79
+ return ErrorDetail.invalidConfiguration("executor:mcp");
80
+ }
81
+ const body = command.trim();
82
+ if (target === null || target.length === 0) {
83
+ return fail("tool-required", 400, `MCP executor '${runtime}' requires a tool target.`, {
84
+ recovery: `READ ${runtime}:/// for the live catalog, then target one listed tool.`,
85
+ retryable: false,
86
+ });
87
+ }
88
+ let args = {};
89
+ if (body.length > 0) {
90
+ try {
91
+ const parsed = JSON.parse(body);
92
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
93
+ throw new TypeError("tool arguments must be an object");
94
+ }
95
+ args = parsed;
96
+ }
97
+ catch (cause) {
98
+ return fail("invalid-tool-arguments", 400, `Arguments for MCP tool '${target}' must be one JSON object.`, {
99
+ tool: target,
100
+ retryable: false,
101
+ diagnostic: ErrorDetail.preview(message(cause), detailLimit),
102
+ });
103
+ }
104
+ }
105
+ try {
106
+ const result = await this.#connection.callTool(target, args, signal);
107
+ write(CHANNEL, JSON.stringify(result), "application/json");
108
+ if (result.isError === true) {
109
+ return fail("tool-reported-error", 502, `MCP tool '${target}' on '${runtime}' reported an error.`, {
110
+ tool: target,
111
+ retryable: false,
112
+ });
113
+ }
114
+ setState(CHANNEL, "closed");
115
+ return { status: 200 };
116
+ }
117
+ catch (error) {
118
+ return fail(signal.aborted ? "cancelled" : "tool-call-failed", signal.aborted ? 499 : 502, signal.aborted
119
+ ? `MCP tool '${target}' on '${runtime}' was cancelled.`
120
+ : `MCP tool '${target}' on '${runtime}' failed: ${ErrorDetail.preview(message(error), detailLimit)}.`, {
121
+ tool: target,
122
+ retryable: !signal.aborted,
123
+ });
124
+ }
125
+ }
126
+ }
127
+ //# sourceMappingURL=McpExecutor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpExecutor.js","sourceRoot":"","sources":["../src/McpExecutor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { type EntryReadResult, type EntryFindResult, type FindStatement, type ReadStatement, type SchemeCtx } from "@plurnk/plurnk-schemes";
2
+ import ServerConnection from "./client.ts";
3
+ export default class McpResources {
4
+ #private;
5
+ constructor(server: string, connection: ServerConnection);
6
+ claims(pathname: string): boolean;
7
+ read(statement: ReadStatement, ctx: SchemeCtx): Promise<EntryReadResult>;
8
+ find(statement: FindStatement, ctx: SchemeCtx): Promise<EntryFindResult>;
9
+ }
10
+ //# sourceMappingURL=McpResources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpResources.d.ts","sourceRoot":"","sources":["../src/McpResources.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,SAAS,EACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,gBAAgB,MAAM,aAAa,CAAC;AAyF3C,MAAM,CAAC,OAAO,OAAO,YAAY;;IAI7B,YAAY,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAGvD;IAED,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAIhC;IAgEK,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC,CA4B7E;IAEK,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC,CAgB7E;CACJ"}
@@ -0,0 +1,153 @@
1
+ import { Results, } from "@plurnk/plurnk-schemes";
2
+ const ROOT = "/";
3
+ const RESOURCES = "/resources";
4
+ const RESOURCE_PREFIX = `${RESOURCES}/`;
5
+ const RESOURCE_TAG = "mcp-resource";
6
+ const CATALOG_TAG = "mcp-resource-catalog";
7
+ class ResourceAddressError extends Error {
8
+ }
9
+ const resourcePath = (uri) => `${RESOURCE_PREFIX}${encodeURIComponent(uri)}`;
10
+ const readFailure = (server, code, status, detail, extensions) => Results.failure("scheme:mcp", code, status, detail, {
11
+ content: null,
12
+ mimetype: null,
13
+ channel: null,
14
+ }, {
15
+ server,
16
+ stage: "mcp-resource",
17
+ ...extensions,
18
+ });
19
+ const findFailure = (server, code, status, detail, extensions) => Results.failure("scheme:mcp", code, status, detail, {
20
+ content: null,
21
+ mimetype: null,
22
+ results: [],
23
+ itemsTokenTotal: 0,
24
+ pathnames: [],
25
+ matches: [],
26
+ }, {
27
+ server,
28
+ stage: "mcp-resource",
29
+ ...extensions,
30
+ });
31
+ const resourceBody = (result) => {
32
+ if (result.contents.length === 1 && "text" in result.contents[0]) {
33
+ const value = result.contents[0];
34
+ return {
35
+ content: value.text,
36
+ mimetype: value.mimeType ?? "text/plain",
37
+ };
38
+ }
39
+ return {
40
+ content: JSON.stringify(result),
41
+ mimetype: "application/json",
42
+ };
43
+ };
44
+ const catalogEntry = (content, tags) => ({
45
+ channels: {
46
+ body: {
47
+ content,
48
+ mimetype: "application/json",
49
+ },
50
+ },
51
+ tags,
52
+ });
53
+ export default class McpResources {
54
+ #server;
55
+ #connection;
56
+ constructor(server, connection) {
57
+ this.#server = server;
58
+ this.#connection = connection;
59
+ }
60
+ claims(pathname) {
61
+ return pathname === ROOT
62
+ || pathname === RESOURCES
63
+ || pathname.startsWith(RESOURCE_PREFIX);
64
+ }
65
+ async #materializeCatalog(ctx) {
66
+ const catalog = await this.#connection.catalog(ctx.signal);
67
+ await ctx.entries.write(ROOT, catalogEntry(JSON.stringify({
68
+ ...catalog,
69
+ resources: catalog.resources.map((resource) => ({
70
+ ...resource,
71
+ address: `${this.#server}://${resourcePath(resource.uri)}`,
72
+ })),
73
+ }), ["mcp-catalog"]));
74
+ await ctx.entries.write(RESOURCES, catalogEntry(JSON.stringify({
75
+ resources: catalog.resources.map((resource) => ({
76
+ ...resource,
77
+ address: `${this.#server}://${resourcePath(resource.uri)}`,
78
+ })),
79
+ resourceTemplates: catalog.resourceTemplates,
80
+ }), ["mcp-resource-index"]));
81
+ await Promise.all(catalog.resources.map(async (resource) => {
82
+ const pathname = resourcePath(resource.uri);
83
+ const existing = await ctx.entries.read(pathname);
84
+ if (existing.entry?.tags.includes(RESOURCE_TAG) === true)
85
+ return;
86
+ await ctx.entries.write(pathname, catalogEntry(JSON.stringify({
87
+ ...resource,
88
+ address: `${this.#server}://${pathname}`,
89
+ }), [CATALOG_TAG]));
90
+ }));
91
+ }
92
+ async #materializeResource(pathname, ctx) {
93
+ const encoded = pathname.slice(RESOURCE_PREFIX.length);
94
+ if (encoded.length === 0 || encoded.includes("/")) {
95
+ throw new ResourceAddressError(`Invalid MCP resource address '${pathname}'.`);
96
+ }
97
+ let uri;
98
+ try {
99
+ uri = decodeURIComponent(encoded);
100
+ }
101
+ catch (cause) {
102
+ throw new ResourceAddressError(`Invalid encoded MCP resource address '${pathname}'.`, { cause });
103
+ }
104
+ const body = resourceBody(await this.#connection.readResource(uri, ctx.signal));
105
+ await ctx.entries.write(pathname, {
106
+ channels: {
107
+ body: {
108
+ content: body.content,
109
+ mimetype: body.mimetype,
110
+ },
111
+ },
112
+ tags: [RESOURCE_TAG],
113
+ });
114
+ }
115
+ async read(statement, ctx) {
116
+ const pathname = statement.target?.kind === "url"
117
+ ? statement.target.pathname ?? ROOT
118
+ : ROOT;
119
+ try {
120
+ const exactResource = pathname.startsWith(RESOURCE_PREFIX)
121
+ && !/[*?[\]{}]/.test(pathname);
122
+ if (exactResource) {
123
+ await this.#materializeResource(pathname, ctx);
124
+ }
125
+ else {
126
+ await this.#materializeCatalog(ctx);
127
+ }
128
+ return await ctx.entries.operations.read(statement);
129
+ }
130
+ catch (error) {
131
+ const invalidAddress = error instanceof ResourceAddressError;
132
+ return readFailure(this.#server, invalidAddress ? "resource-address-invalid" : "resource-read-failed", invalidAddress ? 400 : 502, invalidAddress
133
+ ? `The requested MCP resource address for '${this.#server}' is invalid.`
134
+ : `MCP server '${this.#server}' could not read the requested resource.`, {
135
+ diagnostic: error instanceof Error ? error.message : String(error),
136
+ retryable: !invalidAddress,
137
+ });
138
+ }
139
+ }
140
+ async find(statement, ctx) {
141
+ try {
142
+ await this.#materializeCatalog(ctx);
143
+ return await ctx.entries.operations.find(statement);
144
+ }
145
+ catch (error) {
146
+ return findFailure(this.#server, "resource-find-failed", 502, `MCP server '${this.#server}' could not list its resources.`, {
147
+ diagnostic: error instanceof Error ? error.message : String(error),
148
+ retryable: true,
149
+ });
150
+ }
151
+ }
152
+ }
153
+ //# sourceMappingURL=McpResources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpResources.js","sourceRoot":"","sources":["../src/McpResources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { RuntimeAvailability, RuntimeDecl } from "@plurnk/plurnk-execs";
2
+ import type { FindStatement, ReadStatement, SchemeCtx, SchemeResult } from "@plurnk/plurnk-schemes";
3
+ import McpExecutor from "./McpExecutor.ts";
4
+ interface RuntimeSchemeFacet {
5
+ claims(pathname: string): boolean;
6
+ read?(statement: ReadStatement, ctx: SchemeCtx): Promise<SchemeResult>;
7
+ find?(statement: FindStatement, ctx: SchemeCtx): Promise<SchemeResult>;
8
+ }
9
+ interface ModuleSetupSeam {
10
+ registerRuntime(registration: {
11
+ readonly namespaceOwner: string;
12
+ readonly decl: RuntimeDecl;
13
+ readonly executor: McpExecutor;
14
+ readonly availability: RuntimeAvailability;
15
+ readonly scheme?: RuntimeSchemeFacet;
16
+ }): Promise<void>;
17
+ }
18
+ export interface ModuleOptions {
19
+ readonly env?: NodeJS.ProcessEnv;
20
+ }
21
+ export default class Module {
22
+ #private;
23
+ static init(options?: ModuleOptions): Module;
24
+ private constructor();
25
+ setup(seam: ModuleSetupSeam): Promise<void>;
26
+ close(): Promise<void>;
27
+ }
28
+ export {};
29
+ //# sourceMappingURL=Module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Module.d.ts","sourceRoot":"","sources":["../src/Module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,mBAAmB,EACnB,WAAW,EACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACR,aAAa,EACb,aAAa,EACb,SAAS,EACT,YAAY,EACf,MAAM,wBAAwB,CAAC;AAGhC,OAAO,WAA4B,MAAM,kBAAkB,CAAC;AAG5D,UAAU,kBAAkB;IACxB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACvE,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC1E;AAED,UAAU,eAAe;IACrB,eAAe,CAAC,YAAY,EAAE;QAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;QAC3B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;QAC/B,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;QAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC;KACxC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACpC;AAED,MAAM,CAAC,OAAO,OAAO,MAAM;;IAIvB,MAAM,CAAC,IAAI,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAE/C;IAED,OAAO,eAEN;IAEK,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAiChD;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAU3B;CACJ"}
package/dist/Module.js ADDED
@@ -0,0 +1,55 @@
1
+ import ServerConnection from "./client.js";
2
+ import { serverConfig, serverNames } from "./config.js";
3
+ import McpExecutor, { runtimeDecl } from "./McpExecutor.js";
4
+ import McpResources from "./McpResources.js";
5
+ export default class Module {
6
+ #env;
7
+ #connections = new Map();
8
+ static init(options = {}) {
9
+ return new Module(options.env ?? process.env);
10
+ }
11
+ constructor(environ) {
12
+ this.#env = environ;
13
+ }
14
+ async setup(seam) {
15
+ const results = await Promise.allSettled(serverNames(this.#env).map(async (name) => {
16
+ const config = serverConfig(name, this.#env);
17
+ if (config === null)
18
+ throw new Error(`MCP server '${name}' disappeared during configuration.`);
19
+ const connection = new ServerConnection(config, this.#env);
20
+ this.#connections.set(name, connection);
21
+ const decl = runtimeDecl(name);
22
+ const executor = new McpExecutor({
23
+ runtime: name,
24
+ glyph: decl.glyph ?? "",
25
+ }, connection);
26
+ return {
27
+ namespaceOwner: "@plurnk/plurnk-mcp",
28
+ decl,
29
+ executor,
30
+ availability: await executor.probe(),
31
+ scheme: new McpResources(name, connection),
32
+ };
33
+ }));
34
+ const errors = results
35
+ .filter((result) => result.status === "rejected")
36
+ .map((result) => result.reason);
37
+ if (errors.length > 0)
38
+ throw new AggregateError(errors, "MCP module setup failed");
39
+ const registrations = results.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
40
+ for (const registration of registrations) {
41
+ await seam.registerRuntime(registration);
42
+ }
43
+ }
44
+ async close() {
45
+ const connections = [...this.#connections.values()];
46
+ this.#connections.clear();
47
+ const results = await Promise.allSettled(connections.map((connection) => connection.close()));
48
+ const errors = results
49
+ .filter((result) => result.status === "rejected")
50
+ .map((result) => result.reason);
51
+ if (errors.length > 0)
52
+ throw new AggregateError(errors, "MCP connection shutdown failed");
53
+ }
54
+ }
55
+ //# sourceMappingURL=Module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Module.js","sourceRoot":"","sources":["../src/Module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { Client, type CallToolResult, type DiscoverResult, type ReadResourceResult, type Tool } from "@modelcontextprotocol/client";
2
+ import { type ServerConfig } from "./config.ts";
3
+ export declare const MCP_PROTOCOL_VERSION = "2026-07-28";
4
+ export interface ServerCatalog {
5
+ readonly protocolVersion: typeof MCP_PROTOCOL_VERSION;
6
+ readonly server: ReturnType<Client["getServerVersion"]>;
7
+ readonly capabilities: DiscoverResult["capabilities"];
8
+ readonly tools: Awaited<ReturnType<Client["listTools"]>>["tools"];
9
+ readonly resources: Awaited<ReturnType<Client["listResources"]>>["resources"];
10
+ readonly resourceTemplates: Awaited<ReturnType<Client["listResourceTemplates"]>>["resourceTemplates"];
11
+ readonly prompts: Awaited<ReturnType<Client["listPrompts"]>>["prompts"];
12
+ }
13
+ export default class ServerConnection {
14
+ #private;
15
+ constructor(config: ServerConfig, environ?: NodeJS.ProcessEnv);
16
+ connect(): Promise<Client>;
17
+ readOnly(tool: string): boolean;
18
+ tools(signal?: AbortSignal): Promise<Tool[]>;
19
+ catalog(signal?: AbortSignal): Promise<ServerCatalog>;
20
+ resources(signal?: AbortSignal): Promise<{
21
+ resources: ServerCatalog["resources"];
22
+ resourceTemplates: ServerCatalog["resourceTemplates"];
23
+ }>;
24
+ callTool(name: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<CallToolResult>;
25
+ readResource(uri: string, signal?: AbortSignal): Promise<ReadResourceResult>;
26
+ close(): Promise<void>;
27
+ }
28
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,MAAM,EAEN,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,IAAI,EACZ,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EAGH,KAAK,YAAY,EACpB,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,eAAe,EAAE,OAAO,oBAAoB,CAAC;IACtD,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACxD,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,cAAc,CAAC,CAAC;IACtD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAClE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC9E,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC;IACtG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;CAC3E;AAkED,MAAM,CAAC,OAAO,OAAO,gBAAgB;;IAMjC,YAAY,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,MAAM,CAAC,UAAwB,EAGzE;IAED,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAQzB;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9B;IAEK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAOjD;IAEK,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CA2B1D;IAEK,SAAS,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;QAC3C,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;QACtC,iBAAiB,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;KACzD,CAAC,CAmBD;IAEK,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAKzG;IAEK,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAKjF;IASK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAI3B;CACJ"}
package/dist/client.js ADDED
@@ -0,0 +1,153 @@
1
+ import { Client, StreamableHTTPClientTransport, } from "@modelcontextprotocol/client";
2
+ import { StdioClientTransport, getDefaultEnvironment, } from "@modelcontextprotocol/client/stdio";
3
+ import packageJson from "../package.json" with { type: "json" };
4
+ import { connectTimeoutMs, requestTimeoutMs, } from "./config.js";
5
+ export const MCP_PROTOCOL_VERSION = "2026-07-28";
6
+ const openTransport = (config) => {
7
+ if (config.transport === "http") {
8
+ return new StreamableHTTPClientTransport(new URL(config.url), config.headers === undefined
9
+ ? undefined
10
+ : { requestInit: { headers: config.headers } });
11
+ }
12
+ return new StdioClientTransport({
13
+ command: config.command,
14
+ args: config.args,
15
+ cwd: config.cwd,
16
+ env: {
17
+ ...getDefaultEnvironment(),
18
+ ...config.env,
19
+ },
20
+ });
21
+ };
22
+ const openClient = async (config, environ) => {
23
+ const client = new Client({
24
+ name: packageJson.name,
25
+ version: packageJson.version,
26
+ }, {
27
+ versionNegotiation: {
28
+ mode: { pin: MCP_PROTOCOL_VERSION },
29
+ },
30
+ inputRequired: {
31
+ autoFulfill: false,
32
+ },
33
+ });
34
+ try {
35
+ await client.connect(openTransport(config), {
36
+ timeout: connectTimeoutMs(environ),
37
+ });
38
+ }
39
+ catch (cause) {
40
+ try {
41
+ await client.close();
42
+ }
43
+ catch (closeCause) {
44
+ throw new AggregateError([cause, closeCause], `MCP ${MCP_PROTOCOL_VERSION} connection and cleanup failed.`);
45
+ }
46
+ throw new Error(`MCP ${MCP_PROTOCOL_VERSION} connection failed.`, { cause });
47
+ }
48
+ if (client.getProtocolEra() !== "modern"
49
+ || client.getNegotiatedProtocolVersion() !== MCP_PROTOCOL_VERSION
50
+ || client.getDiscoverResult() === undefined) {
51
+ await client.close();
52
+ throw new Error(`MCP server did not negotiate required revision ${MCP_PROTOCOL_VERSION}.`);
53
+ }
54
+ return client;
55
+ };
56
+ export default class ServerConnection {
57
+ #config;
58
+ #environ;
59
+ #client;
60
+ #toolHints = new Map();
61
+ constructor(config, environ = process.env) {
62
+ this.#config = config;
63
+ this.#environ = environ;
64
+ }
65
+ connect() {
66
+ if (this.#client !== undefined)
67
+ return this.#client;
68
+ const pending = openClient(this.#config, this.#environ).catch((cause) => {
69
+ if (this.#client === pending)
70
+ this.#client = undefined;
71
+ throw cause;
72
+ });
73
+ this.#client = pending;
74
+ return pending;
75
+ }
76
+ readOnly(tool) {
77
+ return this.#toolHints.get(tool) === true;
78
+ }
79
+ async tools(signal) {
80
+ const client = await this.connect();
81
+ const { tools } = await client.listTools(undefined, this.#requestOptions(signal));
82
+ this.#toolHints = new Map(tools.map((tool) => [tool.name, tool.annotations?.readOnlyHint === true]));
83
+ return tools;
84
+ }
85
+ async catalog(signal) {
86
+ const client = await this.connect();
87
+ const discover = client.getDiscoverResult();
88
+ if (discover === undefined)
89
+ throw new Error("Modern MCP connection omitted its discovery result.");
90
+ const [tools, resources, resourceTemplates, prompts] = await Promise.all([
91
+ discover.capabilities.tools === undefined
92
+ ? Promise.resolve([])
93
+ : this.tools(signal),
94
+ discover.capabilities.resources === undefined
95
+ ? Promise.resolve([])
96
+ : client.listResources(undefined, this.#requestOptions(signal)).then((result) => result.resources),
97
+ discover.capabilities.resources === undefined
98
+ ? Promise.resolve([])
99
+ : client.listResourceTemplates(undefined, this.#requestOptions(signal)).then((result) => result.resourceTemplates),
100
+ discover.capabilities.prompts === undefined
101
+ ? Promise.resolve([])
102
+ : client.listPrompts(undefined, this.#requestOptions(signal)).then((result) => result.prompts),
103
+ ]);
104
+ return {
105
+ protocolVersion: MCP_PROTOCOL_VERSION,
106
+ server: client.getServerVersion(),
107
+ capabilities: discover.capabilities,
108
+ tools,
109
+ resources,
110
+ resourceTemplates,
111
+ prompts,
112
+ };
113
+ }
114
+ async resources(signal) {
115
+ const client = await this.connect();
116
+ const discover = client.getDiscoverResult();
117
+ if (discover?.capabilities.resources === undefined) {
118
+ return {
119
+ resources: [],
120
+ resourceTemplates: [],
121
+ };
122
+ }
123
+ const [resources, resourceTemplates] = await Promise.all([
124
+ client.listResources(undefined, this.#requestOptions(signal))
125
+ .then((result) => result.resources),
126
+ client.listResourceTemplates(undefined, this.#requestOptions(signal))
127
+ .then((result) => result.resourceTemplates),
128
+ ]);
129
+ return {
130
+ resources,
131
+ resourceTemplates,
132
+ };
133
+ }
134
+ async callTool(name, args, signal) {
135
+ return (await this.connect()).callTool({ name, arguments: args }, this.#requestOptions(signal));
136
+ }
137
+ async readResource(uri, signal) {
138
+ return (await this.connect()).readResource({ uri }, this.#requestOptions(signal));
139
+ }
140
+ #requestOptions(signal) {
141
+ return {
142
+ signal,
143
+ timeout: requestTimeoutMs(this.#environ),
144
+ };
145
+ }
146
+ async close() {
147
+ const client = this.#client;
148
+ this.#client = undefined;
149
+ if (client !== undefined)
150
+ await (await client).close();
151
+ }
152
+ }
153
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface StdioServerConfig {
2
+ readonly transport: "stdio";
3
+ readonly command: string;
4
+ readonly args: string[];
5
+ readonly cwd?: string;
6
+ readonly env?: Record<string, string>;
7
+ }
8
+ export interface HttpServerConfig {
9
+ readonly transport: "http";
10
+ readonly url: string;
11
+ readonly headers?: Record<string, string>;
12
+ }
13
+ export type ServerConfig = StdioServerConfig | HttpServerConfig;
14
+ export declare const serverNames: (environ?: NodeJS.ProcessEnv) => string[];
15
+ export declare const serverConfig: (name: string, environ?: NodeJS.ProcessEnv) => ServerConfig | null;
16
+ export declare const connectTimeoutMs: (environ?: NodeJS.ProcessEnv) => number;
17
+ export declare const requestTimeoutMs: (environ?: NodeJS.ProcessEnv) => number;
18
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7C;AAED,MAAM,MAAM,YAAY,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AA2FhE,eAAO,MAAM,WAAW,aAAa,MAAM,CAAC,UAAU,KAAiB,MAAM,EACjB,CAAC;AAE7D,eAAO,MAAM,YAAY,SACf,MAAM,YACH,MAAM,CAAC,UAAU,KAC3B,YAAY,GAAG,IAiCjB,CAAC;AAEF,eAAO,MAAM,gBAAgB,aAAa,MAAM,CAAC,UAAU,KAAiB,MAO3E,CAAC;AAEF,eAAO,MAAM,gBAAgB,aAAa,MAAM,CAAC,UAAU,KAAiB,MAO3E,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,134 @@
1
+ const PREFIX = "PLURNK_MCP_";
2
+ const COMPANION_SUFFIXES = ["_args", "_cwd", "_env", "_headers"];
3
+ const CONTROL_KEYS = new Set(["connect_timeout", "request_timeout"]);
4
+ const ENV_REFERENCE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
5
+ const parseEnvironment = (environ) => {
6
+ const targets = new Map();
7
+ const companions = new Map();
8
+ for (const [key, value] of Object.entries(environ)) {
9
+ if (value === undefined || !key.startsWith(PREFIX))
10
+ continue;
11
+ const suffix = key.slice(PREFIX.length);
12
+ if (suffix.length === 0)
13
+ continue;
14
+ const folded = suffix.toLowerCase();
15
+ if (CONTROL_KEYS.has(folded))
16
+ continue;
17
+ const companion = COMPANION_SUFFIXES.find((candidate) => folded.endsWith(candidate));
18
+ if (companion !== undefined) {
19
+ const name = folded.slice(0, -companion.length);
20
+ const bySuffix = companions.get(name) ?? new Map();
21
+ if (bySuffix.has(companion)) {
22
+ throw new Error(`Duplicate MCP server companion for '${name}${companion}'.`);
23
+ }
24
+ bySuffix.set(companion, value);
25
+ companions.set(name, bySuffix);
26
+ continue;
27
+ }
28
+ if (targets.has(folded)) {
29
+ throw new Error(`Duplicate MCP server '${folded}': multiple ${PREFIX}* keys case-fold to the same name.`);
30
+ }
31
+ targets.set(folded, value);
32
+ }
33
+ for (const name of companions.keys()) {
34
+ if (!targets.has(name))
35
+ throw new Error(`MCP server companion '${name}' has no ${PREFIX}<server> target.`);
36
+ }
37
+ return { targets, companions };
38
+ };
39
+ const expandReferences = (value, environ, field) => value.replaceAll(ENV_REFERENCE, (_match, name) => {
40
+ const resolved = environ[name];
41
+ if (resolved === undefined)
42
+ throw new Error(`${field} references missing environment variable ${name}.`);
43
+ return resolved;
44
+ });
45
+ const jsonStrings = (raw, field, environ) => {
46
+ if (raw === undefined || raw.length === 0)
47
+ return [];
48
+ let parsed;
49
+ try {
50
+ parsed = JSON.parse(raw);
51
+ }
52
+ catch (cause) {
53
+ throw new Error(`${field} must be a JSON array of strings.`, { cause });
54
+ }
55
+ if (!Array.isArray(parsed) || !parsed.every((value) => typeof value === "string")) {
56
+ throw new Error(`${field} must be a JSON array of strings.`);
57
+ }
58
+ return parsed.map((value) => expandReferences(value, environ, field));
59
+ };
60
+ const jsonRecord = (raw, field, environ) => {
61
+ if (raw === undefined || raw.length === 0)
62
+ return undefined;
63
+ let parsed;
64
+ try {
65
+ parsed = JSON.parse(raw);
66
+ }
67
+ catch (cause) {
68
+ throw new Error(`${field} must be a JSON object with string values.`, { cause });
69
+ }
70
+ if (typeof parsed !== "object"
71
+ || parsed === null
72
+ || Array.isArray(parsed)
73
+ || !Object.values(parsed).every((value) => typeof value === "string")) {
74
+ throw new Error(`${field} must be a JSON object with string values.`);
75
+ }
76
+ return Object.fromEntries(Object.entries(parsed).map(([key, value]) => [
77
+ key,
78
+ expandReferences(value, environ, field),
79
+ ]));
80
+ };
81
+ export const serverNames = (environ = process.env) => [...parseEnvironment(environ).targets.keys()].toSorted();
82
+ export const serverConfig = (name, environ = process.env) => {
83
+ const { targets, companions } = parseEnvironment(environ);
84
+ const folded = name.toLowerCase();
85
+ const target = targets.get(folded);
86
+ if (target === undefined)
87
+ return null;
88
+ if (target.length === 0)
89
+ throw new Error(`${PREFIX}${folded} must not be empty.`);
90
+ const fields = companions.get(folded);
91
+ const fieldName = (suffix) => `${PREFIX}${folded.toUpperCase()}${suffix.toUpperCase()}`;
92
+ if (/^https?:\/\//i.test(target)) {
93
+ if (fields?.has("_args") || fields?.has("_cwd") || fields?.has("_env")) {
94
+ throw new Error(`HTTP MCP server '${folded}' may declare only a _HEADERS companion.`);
95
+ }
96
+ return {
97
+ transport: "http",
98
+ url: target,
99
+ headers: jsonRecord(fields?.get("_headers"), fieldName("_headers"), environ),
100
+ };
101
+ }
102
+ if (/\s/.test(target)) {
103
+ throw new Error(`${PREFIX}${folded} must contain one executable; put arguments in ${fieldName("_args")}.`);
104
+ }
105
+ if (fields?.has("_headers")) {
106
+ throw new Error(`stdio MCP server '${folded}' may not declare a _HEADERS companion.`);
107
+ }
108
+ return {
109
+ transport: "stdio",
110
+ command: target,
111
+ args: jsonStrings(fields?.get("_args"), fieldName("_args"), environ),
112
+ cwd: fields?.has("_cwd")
113
+ ? expandReferences(fields.get("_cwd"), environ, fieldName("_cwd"))
114
+ : undefined,
115
+ env: jsonRecord(fields?.get("_env"), fieldName("_env"), environ),
116
+ };
117
+ };
118
+ export const connectTimeoutMs = (environ = process.env) => {
119
+ const raw = environ.PLURNK_MCP_CONNECT_TIMEOUT;
120
+ const value = Number(raw);
121
+ if (!Number.isInteger(value) || value < 1) {
122
+ throw new Error(`PLURNK_MCP_CONNECT_TIMEOUT must be a positive integer; got ${JSON.stringify(raw)}.`);
123
+ }
124
+ return value;
125
+ };
126
+ export const requestTimeoutMs = (environ = process.env) => {
127
+ const raw = environ.PLURNK_MCP_REQUEST_TIMEOUT;
128
+ const value = Number(raw);
129
+ if (!Number.isInteger(value) || value < 1) {
130
+ throw new Error(`PLURNK_MCP_REQUEST_TIMEOUT must be a positive integer; got ${JSON.stringify(raw)}.`);
131
+ }
132
+ return value;
133
+ };
134
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { default as Module } from "./Module.ts";
2
+ export { default } from "./Module.ts";
3
+ export { MCP_PROTOCOL_VERSION } from "./client.ts";
4
+ export { connectTimeoutMs, requestTimeoutMs, serverConfig, serverNames, } from "./config.ts";
5
+ export type { HttpServerConfig, ServerConfig, StdioServerConfig, } from "./config.ts";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EACH,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,WAAW,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EACR,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GACpB,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { default as Module } from "./Module.js";
2
+ export { default } from "./Module.js";
3
+ export { MCP_PROTOCOL_VERSION } from "./client.js";
4
+ export { connectTimeoutMs, requestTimeoutMs, serverConfig, serverNames, } from "./config.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EACH,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,WAAW,GACd,MAAM,aAAa,CAAC"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@plurnk/plurnk-mcp",
3
+ "version": "1.4.0",
4
+ "description": "Current Model Context Protocol host module for Plurnk.",
5
+ "keywords": [
6
+ "plurnk",
7
+ "exec",
8
+ "runtime",
9
+ "executor",
10
+ "mcp",
11
+ "model-context-protocol"
12
+ ],
13
+ "homepage": "https://github.com/plurnk/plurnk-service/tree/main/plurnk-mcp#readme",
14
+ "bugs": {
15
+ "url": "https://repo.possumtech.com/plurnk/plurnk-service/issues"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/plurnk/plurnk-service.git",
20
+ "directory": "plurnk-mcp"
21
+ },
22
+ "engines": {
23
+ "node": ">=26"
24
+ },
25
+ "license": "MIT",
26
+ "author": "@wikitopian",
27
+ "type": "module",
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "exports": {
32
+ ".": {
33
+ "plurnk-dev": "./src/index.ts",
34
+ "types": "./dist/index.d.ts",
35
+ "default": "./dist/index.js"
36
+ },
37
+ "./package.json": "./package.json"
38
+ },
39
+ "files": [
40
+ "dist/**/*",
41
+ "README.md",
42
+ "SPEC.md",
43
+ "docs/**/*",
44
+ ".env.defaults"
45
+ ],
46
+ "scripts": {
47
+ "test:lint": "tsc --noEmit",
48
+ "test:unit": "node --conditions=plurnk-dev --env-file-if-exists=../plurnk-execs/.env.defaults --test \"src/**/*.test.ts\"",
49
+ "test": "npm run test:lint && npm run test:unit",
50
+ "build:clean": "rm -rf dist",
51
+ "build:dist": "tsc -p tsconfig.build.json",
52
+ "build": "npm run build:clean && npm run build:dist",
53
+ "prepack": "npm run build",
54
+ "prepublishOnly": "npm audit --audit-level=moderate && npm test"
55
+ },
56
+ "dependencies": {
57
+ "@modelcontextprotocol/client": "2.0.0"
58
+ },
59
+ "devDependencies": {
60
+ "@modelcontextprotocol/server": "2.0.0"
61
+ },
62
+ "peerDependencies": {
63
+ "@plurnk/plurnk-execs": "^1.4.0",
64
+ "@plurnk/plurnk-schemes": "^1.4.0"
65
+ }
66
+ }