Skip to content

feat: support remote MCP server migration (streamable-http, sse)#245

Open
kiloconnect[bot] wants to merge 1 commit intodevfrom
session/agent_38f930dd-192d-4357-b8cf-6beb88068fd0
Open

feat: support remote MCP server migration (streamable-http, sse)#245
kiloconnect[bot] wants to merge 1 commit intodevfrom
session/agent_38f930dd-192d-4357-b8cf-6beb88068fd0

Conversation

@kiloconnect
Copy link
Contributor

@kiloconnect kiloconnect bot commented Feb 11, 2026

Summary

Adds support for migrating remote MCP server configurations (streamable-http, sse) from .kilocode/mcp_settings.json and .kilocode/mcp.json.

Problem

When a user configures a remote streamable-http MCP server in .kilocode/mcp_settings.json:

{
  "mcpServers": {
    "local-mcp": {
      "type": "streamable-http",
      "url": "http://localhost:4321/mcp"
    }
  }
}

The migrator fails with: The "file" argument must be of type string. Received undefined

This happens because convertServer() unconditionally treats every server as a local/stdio server, accessing server.command (which is undefined for remote servers) and passing it to the command array.

Changes

packages/opencode/src/kilocode/mcp-migrator.ts

  • Extended KilocodeMcpServer interface with optional type, url, and headers fields for remote servers
  • Made command optional since remote servers don't have one
  • Added isRemote() helper that detects remote servers by checking for a url field or a remote type (streamable-http, sse)
  • Updated convertServer() to produce Config.McpRemote (type: "remote") for remote servers, passing through url and headers

packages/opencode/test/kilocode/mcp-migrator.test.ts

  • Added 9 new tests covering:
    • streamable-http server conversion
    • sse server conversion
    • Remote servers with headers/auth
    • Disabled remote servers
    • Servers with url but no explicit type
    • Mixed stdio + remote server migration
    • End-to-end migration from project settings

Backward Compatibility

All 16 existing tests continue to pass. Stdio/local server migration is unchanged.


Built for Marius Wichtner by Kilo for Slack

Add support for migrating remote MCP server configurations (streamable-http,
sse) from .kilocode/mcp_settings.json and .kilocode/mcp.json.

Previously, the migrator only handled stdio/local servers and would fail with
'The "file" argument must be of type string. Received undefined' when
encountering remote servers that have a url field instead of command/args.

Changes:
- Extended KilocodeMcpServer interface with optional type, url, and headers fields
- Added isRemote() helper to detect remote server configs
- Updated convertServer() to produce Config.McpRemote for remote servers
- Made command field optional since remote servers don't have one
- Added comprehensive tests for streamable-http, sse, mixed configs, and headers
@github-actions
Copy link
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

const REMOTE_TYPES = new Set(["streamable-http", "sse"])

function isRemote(server: KilocodeMcpServer): boolean {
return !!server.url || REMOTE_TYPES.has(server.type ?? "")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRITICAL: isRemote() can classify a server as remote even when url is missing

If server.type is "streamable-http"/"sse" but url is absent, convertServer() will still take the remote branch and emit { type: 'remote', url: undefined } (via non-null assertions), which can break config validation downstream. Consider requiring url when type indicates remote (or treat missing url as skipped + warning).

if (isRemote(server)) {
const mcpConfig: Config.Mcp = {
type: "remote",
url: server.url!,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRITICAL: Non-null assertion on server.url can produce invalid remote config

url: server.url! will silently become url: undefined at runtime if the input config has type set but no url. A defensive guard (return null and record a warning/skipped reason) would avoid emitting an invalid Config.McpRemote.


// Build the MCP config object
// Local/stdio servers
const command = [server.command!, ...(server.args ?? [])]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Non-null assertion on server.command can create [undefined, ...] for local servers

Since command is now optional on KilocodeMcpServer, a malformed/partial local config could reach this branch and produce an invalid command array. Consider validating server.command before constructing the local config (and skipping + warning if missing).

@kiloconnect
Copy link
Contributor Author

kiloconnect bot commented Feb 11, 2026

Code Review Summary

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 2
WARNING 1
SUGGESTION 0

Fix these issues in Kilo Cloud

Issue Details (click to expand)

CRITICAL

File Line Issue
packages/opencode/src/kilocode/mcp-migrator.ts 27 isRemote() can treat type as remote even when url is missing, producing invalid remote config
packages/opencode/src/kilocode/mcp-migrator.ts 55 Non-null assertion on server.url can emit { type: 'remote', url: undefined }

WARNING

File Line Issue
packages/opencode/src/kilocode/mcp-migrator.ts 62 Non-null assertion on server.command can produce invalid local command array
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
Files Reviewed (2 files)
  • packages/opencode/src/kilocode/mcp-migrator.ts - 3 issues
  • packages/opencode/test/kilocode/mcp-migrator.test.ts - 0 issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants