nanocoai/nanoclaw · error · Error

unsupported transport "sse"

Error message

unsupported transport "sse"

What it means

parseMcpServerConfig explicitly rejects the deprecated SSE transport: only stdio and http (with streamable-http accepted as an alias for http) are supported. SSE servers must be migrated to streamable-http.

Source

Thrown at src/container-config.ts:134

// The Agent Plugins fixed cwd shapes: ./p, ${PLUGIN_ROOT}[/p], ${PLUGIN_DATA}[/p].
const CWD_FORM_RE = /^(?:\.\/|\$\{PLUGIN_ROOT\}(?:\/|$)|\$\{PLUGIN_DATA\}(?:\/|$))/;

/**
 * Parse one CLI or approval payload into the persisted MCP config shape.
 * Duplicated in container/agent-runner/src/mcp-tools/self-mod.ts
 * (parseMcpServerInput) — no shared modules across the host/container
 * boundary; keep the two in sync.
 */
export function parseMcpServerConfig(input: Record<string, unknown>): McpServerConfig {
  const command = typeof input.command === 'string' && input.command.trim() ? input.command : undefined;
  const url = typeof input.url === 'string' && input.url.trim() ? input.url.trim() : undefined;

  // A declared transport is honored; absence keeps the legacy CLI inference
  // (url → http, command → stdio). "streamable-http" is the Agent Plugins
  // spelling of the internal "http".
  const type = input.type === 'streamable-http' ? 'http' : input.type;
  if (type === 'sse') throw new Error('unsupported transport "sse"');
  if (type !== undefined && type !== 'stdio' && type !== 'http') {
    throw new Error('type must be "stdio", "http", or "streamable-http"');
  }
  if (type === 'stdio' && !command) throw new Error('type "stdio" requires command');
  if (type === 'http' && !url) throw new Error('type "http" requires url');

  const instructions = input.instructions;
  if (instructions !== undefined && typeof instructions !== 'string') {
    throw new Error('MCP instructions must be a string');
  }

  if (url !== undefined) {
    if (command !== undefined) throw new Error('Provide exactly one of command or url');
    if (input.args !== undefined || input.env !== undefined || input.cwd !== undefined) {
      throw new Error('args, env, and cwd are only valid with command');
    }
    let parsed: URL;
    try {

View on GitHub (pinned to 294ef2aee8)

Solutions

  1. Change "type": "sse" to "type": "streamable-http" (usually same URL)
  2. Verify the server actually supports streamable-http (most former SSE servers do)
  3. Update the stored config via ncl groups config update or remove/re-add the MCP server

Example fix

// before
{"type": "sse", "url": "https://mcp.example.com/sse"}
// after
{"type": "streamable-http", "url": "https://mcp.example.com/mcp"}
Defensive patterns

Strategy: fallback

Validate before calling

if (entry.type === 'sse') entry = { ...entry, type: 'streamable-http' }; // migrate before submit

Type guard

function isSupportedTransport(t: string | undefined): boolean {
  return t === undefined || t === 'stdio' || t === 'http' || t === 'streamable-http';
}

Prevention

When it happens

Trigger: An MCP server entry with "type": "sse" in container config, via add-mcp-server or a stored config (legacy configs from when SSE was tolerated).

Common situations: Copying an MCP server definition from older Claude/other MCP client configs that used the SSE transport; upstream servers migrated to streamable-http.

Related errors


AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28). Data as JSON: /api/errors/112d7801bad3bfe1. Report an issue: GitHub.