Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,3 +441,11 @@ export ZCODE_TUI_NOTIFICATION_METHOD=auto # auto|osc9|bel|native|off
export ZCODE_TUI_NOTIFICATION_CONDITION=always # unfocused|always
zcode
```

## Official MCP Availability

When the bundled runtime has no official MCP trusted-origin registry, official
HTTP MCP services are reported as disabled with an `official_auth_unavailable`
diagnostic. Other plugin components remain available. This does not disable
certificate, origin, or permission checks, and does not suppress services when
the runtime provides the required registry. No user configuration is rewritten.
2 changes: 2 additions & 0 deletions scripts/check-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
patchRuntimeHttpNoContent,
patchRuntimeLoginModelDefaults,
patchRuntimeNetworkRetryClassification,
patchRuntimeOfficialMcpAvailability,
patchRuntimeStreamEofFinishGuard,
parseRuntimePatchReports,
runtimePatchPlan,
Expand Down Expand Up @@ -70,6 +71,7 @@ if (!metadataCapabilities
throw new Error("The extracted runtime capability manifest is missing or stale; run `bun run sync` again.");
}
if (patchRuntimeLoginModelDefaults(runtimeSource) !== runtimeSource
|| (patchEnabled("official-mcp-availability") && patchRuntimeOfficialMcpAvailability(runtimeSource) !== runtimeSource)
|| (patchEnabled("goal-failure-pause") && patchRuntimeGoalFailurePause(runtimeSource) !== runtimeSource)
|| patchRuntimeHttpNoContent(runtimeSource) !== runtimeSource
|| !hasRuntimeHttpNoContentGuard(runtimeSource)
Expand Down
25 changes: 25 additions & 0 deletions scripts/sync-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,26 @@ export function patchRuntimeCliHelpContract(runtime: string): string {
return patched;
}

/** Report missing official authentication support without weakening origin checks. */
export function patchRuntimeOfficialMcpAvailability(runtime: string): string {
const marker = "zcode_cli_official_mcp_unavailable";
if (runtime.includes(marker)) return runtime;
const anchor = /await this\.closeRecord\(([A-Za-z_$][\w$]*)\),([A-Za-z_$][\w$]*)\.enabled===!1\)\{let ([A-Za-z_$][\w$]*)=this\.createStatus\(\2,"disabled"\);/gu;
let matches = 0;
const patched = runtime.replace(anchor, (_, name: string, config: string, status: string) => {
matches += 1;
const unavailable = `${config}.type==="http"&&${config}.auth?.type==="zcode_official"`
+ `&&${config}.auth.provider==="jwt_token"&&${config}.official!==void 0`
+ "&&!this.officialMcpAuth?.trustedOrigins";
return `await this.closeRecord(${name}),${config}.enabled===!1||(${unavailable})){`
+ `let ${status}=this.createStatus(${config},"disabled",${config}.enabled===!1?void 0:`
+ `{error:"Official MCP authentication is unavailable in this runtime (${marker}).",`
+ 'failureKind:"official_auth_unavailable"});';
});
if (matches !== 1) throw new Error("ZCode runtime is incompatible with the official MCP availability patch.");
return patched;
}

/** Keep short Agent calls inline, but detach long-running agents from the foreground turn. */
export function patchRuntimeAgentAutoBackground(runtime: string): string {
const marker = "autoBackgroundMs:this.config.subagents?.autoBackgroundMs??1e3,outputRootDir:";
Expand Down Expand Up @@ -1303,6 +1323,11 @@ const terminalProjectionMarkers = [
] as const;

export const runtimePatchPlan: readonly RuntimePatchDefinition[] = [
{
id: "official-mcp-availability",
requirement: "optional",
apply: patchRuntimeOfficialMcpAvailability
},
{
id: "tui-bridge",
requirement: "required",
Expand Down
57 changes: 57 additions & 0 deletions test/runtime-mcp-availability.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { describe, expect, test } from "bun:test";
import { patchRuntimeOfficialMcpAvailability } from "../scripts/sync-runtime.ts";

// This fixture preserves the minified upstream connection branch, with no network transport.
const source = `class Adapter {
records = new Map();
closed = [];
connected = [];
officialMcpAuth;
createStatus(config,status,extra){return {status,...extra}}
async closeRecord(name){this.closed.push(name)}
async connectServer(t,r,n={}){if(await this.closeRecord(t),r.enabled===!1){let m=this.createStatus(r,"disabled");return this.records.set(t,{config:r,status:m,tools:[]}),m}this.connected.push(t);return {status:"connected"}}
}`;

function adapter() {
return new (new Function(`${patchRuntimeOfficialMcpAvailability(source)};return Adapter;`)())();
}

const official = {
type: "http", auth: { type: "zcode_official", provider: "jwt_token" },
official: { provider: "fixture" }, url: "https://example.invalid/mcp"
};

describe("official MCP runtime availability (offline)", () => {
test("skips unavailable official HTTP services with an actionable status", async () => {
const runtime = adapter();
const result = await runtime.connectServer("image_search", official);
expect(result).toMatchObject({ status: "disabled", failureKind: "official_auth_unavailable" });
expect(result.error).toContain("authentication is unavailable");
expect(runtime.connected).toEqual([]);
expect(runtime.closed).toEqual(["image_search"]);
expect(official).not.toHaveProperty("enabled");
});

test("allows revalidation after the runtime gains trusted-origin support", async () => {
const runtime = adapter();
await runtime.connectServer("image_search", official);
runtime.officialMcpAuth = { trustedOrigins: {} };
expect(await runtime.connectServer("image_search", official)).toEqual({ status: "connected" });
expect(runtime.connected).toEqual(["image_search"]);
});

test("preserves explicit disablement and other transports/auth paths", async () => {
const runtime = adapter();
expect(await runtime.connectServer("disabled", { ...official, enabled: false })).toEqual({ status: "disabled" });
for (const config of [{ type: "http" }, { ...official, type: "stdio" }, { ...official, official: undefined }]) {
expect(await runtime.connectServer("other", config)).toEqual({ status: "connected" });
}
});

test("is idempotent and rejects missing or ambiguous patch anchors", () => {
const patched = patchRuntimeOfficialMcpAvailability(source);
expect(patchRuntimeOfficialMcpAvailability(patched)).toBe(patched);
expect(() => patchRuntimeOfficialMcpAvailability("changed upstream")).toThrow("incompatible");
expect(() => patchRuntimeOfficialMcpAvailability(source + source)).toThrow("incompatible");
});
});