can1357/oh-my-pi · error

Unsupported MCP server transport: ${server.type}

Error message

Unsupported MCP server transport: ${server.type}

What it means

When translating ACP MCP server configs into internal server configs, #toInternalConfig handles the supported transports (stdio, and the http/sse style with url+headers). A server entry with type "acp" — an experimental internal-only channel that is deliberately not advertised in mcpCapabilities — reaches this throw as a defensive rejection. Spec-compliant ACP clients can never legitimately send it.

Source

Thrown at packages/coding-agent/src/modes/acp/acp-agent.ts:2714

			};
		}
		if (server.type === "http") {
			return {
				type: "http",
				url: server.url,
				headers: this.#toNameValueMap(server.headers),
			};
		}
		if (server.type === "sse") {
			return {
				type: "sse",
				url: server.url,
				headers: this.#toNameValueMap(server.headers),
			};
		}
		// The experimental ACP-channel transport (`type: "acp"`) is not advertised in
		// `mcpCapabilities`, so a spec-compliant client never sends it; reject defensively.
		throw new Error(`Unsupported MCP server transport: ${server.type}`);
	}

	#toNameValueMap(values: Array<{ name: string; value: string }>): { [name: string]: string } {
		const mapped: { [name: string]: string } = {};
		for (const value of values) {
			mapped[value.name] = value.value;
		}
		return mapped;
	}

	async #closeManagedSession(sessionId: string, record: ManagedSessionRecord): Promise<void> {
		record.closedError ??= this.#createPromptLifecycleError("ACP session closed before queued prompt could run");
		this.#sessions.delete(sessionId);
		await this.#cancelPromptForClose(record);
		await this.#disposeSessionRecord(record);
	}

	async #cancelPromptForClose(record: ManagedSessionRecord): Promise<void> {

View on GitHub (pinned to 9690622007)

Solutions

  1. Remove servers with type "acp" from the ACP client's MCP config — that transport is internal-only and not available over ACP.
  2. Reconfigure that server over a supported transport (stdio command, or HTTP/SSE url+headers).
  3. Upgrade/fix the client so it filters server types to those advertised in mcpCapabilities before sending.

Example fix

// before
{ "name": "memory", "type": "acp" }
// after
{ "name": "memory", "type": "http", "url": "http://localhost:3000/mcp", "headers": [] }
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = new Set(["stdio", "http", "sse"]);
const filtered = servers.filter(s => SUPPORTED.has(s.type));
if (filtered.length !== servers.length) logger.warn("dropped unsupported MCP transports", { dropped: servers.length - filtered.length });

Type guard

function isSupportedTransport(t: string): boolean {
  return t === "stdio" || t === "http" || t === "sse";
}

Try / catch

try {
  await configureMcpServers(servers);
} catch (err) {
  if (err.message.startsWith("Unsupported MCP server transport")) {
    const ok = servers.filter(s => isSupportedTransport(s.type));
    await configureMcpServers(ok);
  } else throw err;
}

Prevention

When it happens

Trigger: Sending an ACP MCP-config request containing a server whose type is "acp" (or any type not handled by the preceding branches of #toInternalConfig).

Common situations: Copy-pasting an internal/ompi config that uses the experimental acp transport into an ACP client's settings; a non-standard client forwarding internal server definitions verbatim.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/f50e303cd06b4476. Report an issue: GitHub.