MoonshotAI / MoonshotAI/kimi-code

stdio MCP child env injects bracketed [::1] into NO_PROXY, crashing Python httpx-based MCP servers

Open
#1,931 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

What version of Kimi Code is running?

0.27.0

Which open platform/subscription were you using?

Kimi Code (OAuth)

Which model were you using?

k3

What platform is your computer?

Linux 5.15.0-43-generic x86_64 x86_64

What issue are you seeing?

With an HTTP proxy configured (HTTP_PROXY/HTTPS_PROXY/ALL_PROXY set), any stdio MCP server implemented in Python on top of httpx crashes at startup, and the MCP connection fails with Connection closed.

Example with mcp-atlassian (Jira):

MCP server "jira" failed: MCP error -32000: Connection closed
...
File ".../fastmcp/utilities/version_check.py", line 69, in _fetch_latest_version
  response = httpx.get(PYPI_URL, timeout=REQUEST_TIMEOUT_SECONDS)
File ".../httpx/_client.py", line 698, in __init__
  URLPattern(key): None
File ".../httpx/_urlparse.py", line 411, in normalize_port
  raise InvalidURL(f"Invalid port: {port!r}")
httpx.InvalidURL: Invalid port: ':1]'

The child process environment contains:

NO_PROXY=localhost,127.0.0.1,::1,[::1]

even though the parent shell has no no_proxy set at all. The entire value is injected by Kimi Code itself.

What steps can reproduce the bug?
  1. Set proxy variables, e.g. export HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890
  2. Configure any Python/httpx-based stdio MCP server in mcp.json (e.g. mcp-atlassian)
  3. Start Kimi Code — the server fails with Invalid port: ':1]'

Minimal repro of the underlying parsing failure (no Kimi Code needed):

$ NO_PROXY='localhost,[::1]' python3 -c "import httpx; httpx.Client()"
httpx.InvalidURL: Invalid port: ':1]'

$ NO_PROXY='localhost,::1' python3 -c "import httpx; httpx.Client()"   # bare ::1 is fine
# OK
What is the expected behavior?

Kimi Code's loopback-protection additions to NO_PROXY should not break stdio MCP child processes written in other languages. The injected value should be parseable by mainstream HTTP client libraries (Python httpx, requests, Go, etc.), or at least not cause a hard crash.

Additional information

Root cause: PR #487 (commit 4d113949) added LOOPBACK_NO_PROXY = ['localhost', '127.0.0.1', '::1', '[::1]'] in packages/agent-core/src/utils/proxy.ts. The bracketed [::1] is required for the main process because undici's EnvHttpProxyAgent mis-parses a bare ::1 (as host : port 1) — the code comment documents this. However, mergeStdioEnv propagates the same value verbatim into child processes, where it is only needed by Node/undici children (NODE_USE_ENV_PROXY). Python's httpx hits the mirror-image bug: it parses all://[::1] and treats :1] as the port, raising httpx.InvalidURL — which is not a subclass of httpx.HTTPError, so even libraries that wrap their requests in try/except httpx.HTTPError (like fastmcp's version check) crash anyway.

Suggested fix (either would work):

  • Inject only the bare ::1 (plus localhost/127.0.0.1) into spawned children's NO_PROXY, keeping the bracketed [::1] only for the in-process undici dispatcher; or
  • Reconcile per-server env overrides of NO_PROXY/no_proxy so users can fully replace the injected value (currently the injected loopback entries are always appended — see reconcileChildNoProxy/resolveNoProxy).

Workaround for affected users: explicitly override both casings in the server's env in mcp.json:

"env": {
  "no_proxy": "localhost,127.0.0.1,::1",
  "NO_PROXY": "localhost,127.0.0.1,::1"
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/agent-core/src/utils/proxy.ts, especially LOOPBACK_NO_PROXY, mergeStdioEnv, reconcileChildNoProxy, and resolveNoProxy. Reproduce the failure with proxy variables and a Python/httpx-based stdio MCP server, then verify that spawned children receive a parseable NO_PROXY value and no longer fail with InvalidURL.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, python, typescript
Domain
cli, networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.