MoonshotAI / MoonshotAI/kimi-code
stdio MCP child env injects bracketed [::1] into NO_PROXY, crashing Python httpx-based MCP servers
Nobody has claimed this yet.
- 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?
- Set proxy variables, e.g.
export HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890 - Configure any Python/httpx-based stdio MCP server in
mcp.json(e.g.mcp-atlassian) - 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(pluslocalhost/127.0.0.1) into spawned children'sNO_PROXY, keeping the bracketed[::1]only for the in-process undici dispatcher; or - Reconcile per-server
envoverrides ofNO_PROXY/no_proxyso users can fully replace the injected value (currently the injected loopback entries are always appended — seereconcileChildNoProxy/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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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