[Bug]: npx MCP server not found
Is there an existing issue for the same bug? (If one exists, thumbs up or comment on the issue instead).
- [x] I have checked the existing issues.
Describe the bug and reproduction steps
Trying to get MCP working since this PR (specifically, the Jetbrains MCP Server).
I setup the options:
Yet it doesn't find it:
Here's the only portion of the logs I see that mention MCP:
Interestingly, if I try the uvx "fetch" example shown on the settings page, it does work. If I list both, like this, it finds "fetch" only but not "jetbrains":
{
"sse_servers": [],
"stdio_servers": [
{
"name": "jetbrains",
"command": "npx",
"args": [
"-y",
"@jetbrains/mcp-proxy"
],
"env": {}
},
{
"name": "fetch",
"command": "uvx",
"args": [
"mcp-server-fetch"
],
"env": {}
}
]
}
Any ideas?
Thanks in advance!
OpenHands Installation
Docker command in README
OpenHands Version
0.38
Operating System
None
Logs, Errors, Screenshots, and Additional Context
No response
Cc: @ryanhoangt Maybe this looks familiar? Not sure if this may be because of a failure when loading from UI or is it npx
I looked into the log a bit and it seems the error happened when the client attempted to retrieve tools from action_execution_server:
08:38:10 - openhands:ERROR: utils.py:63 - Failed to connect to url='http://localhost:33509/sse' api_key='******': 1 validation error for ListToolsResult
tools
Field required [type=missing, input_value={}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.11/v/missing
Traceback (most recent call last):
File "/home/hoang/OpenHands/openhands/mcp/utils.py", line 58, in create_mcp_clients
await client.connect_sse(server_url.url, api_key=server_url.api_key)
File "/home/hoang/OpenHands/openhands/mcp/client.py", line 56, in connect_sse
await asyncio.wait_for(connect_with_timeout(), timeout=timeout)
File "/home/hoang/miniconda3/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
return await fut
^^^^^^^^^
File "/home/hoang/OpenHands/openhands/mcp/client.py", line 53, in connect_with_timeout
await self._initialize_and_list_tools()
File "/home/hoang/OpenHands/openhands/mcp/client.py", line 74, in _initialize_and_list_tools
response = await self.session.list_tools()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/lib/python3.12/site-packages/mcp/client/session.py", line 320, in list_tools
return await self.send_request(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/lib/python3.12/site-packages/mcp/shared/session.py", line 270, in send_request
return result_type.model_validate(response_or_error.result)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/lib/python3.12/site-packages/pydantic/main.py", line 703, in model_validate
return cls.__pydantic_validator__.validate_python(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 1 validation error for ListToolsResult
tools
Field required [type=missing, input_value={}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.11/v/missing
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/bin/uvicorn", line 8, in <module>
sys.exit(main())
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/lib/python3.12/site-packages/click/core.py", line 1161, in __call__
return self.main(*args, **kwargs)
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/lib/python3.12/site-packages/click/core.py", line 1082, in main
rv = self.invoke(ctx)
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/lib/python3.12/site-packages/click/core.py", line 1443, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/lib/python3.12/site-packages/click/core.py", line 788, in invoke
return __callback(*args, **kwargs)
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/lib/python3.12/site-packages/uvicorn/main.py", line 413, in main
run(
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/lib/python3.12/site-packages/uvicorn/main.py", line 580, in run
server.run()
File "/home/hoang/.cache/pypoetry/virtualenvs/openhands-ai-xKdyWjiY-py3.12/lib/python3.12/site-packages/uvicorn/server.py", line 66, in run
return asyncio.run(self.serve(sockets=sockets))
File "/home/hoang/miniconda3/lib/python3.12/asyncio/runners.py", line 194, in run
return runner.run(main)
File "/home/hoang/miniconda3/lib/python3.12/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
File "/home/hoang/miniconda3/lib/python3.12/asyncio/base_events.py", line 672, in run_until_complete
self.run_forever()
File "/home/hoang/miniconda3/lib/python3.12/asyncio/base_events.py", line 639, in run_forever
self._run_once()
File "/home/hoang/miniconda3/lib/python3.12/asyncio/base_events.py", line 1985, in _run_once
handle._run()
File "/home/hoang/miniconda3/lib/python3.12/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "/home/hoang/OpenHands/openhands/server/session/session.py", line 162, in initialize_agent
await self.agent_session.start(
File "/home/hoang/OpenHands/openhands/server/session/agent_session.py", line 130, in start
await add_mcp_tools_to_agent(agent, self.runtime, config.mcp)
File "/home/hoang/OpenHands/openhands/mcp/utils.py", line 171, in add_mcp_tools_to_agent
mcp_tools = await fetch_mcp_tools_from_config(updated_mcp_config)
File "/home/hoang/OpenHands/openhands/mcp/utils.py", line 86, in fetch_mcp_tools_from_config
mcp_clients = await create_mcp_clients(
File "/home/hoang/OpenHands/openhands/mcp/utils.py", line 63, in create_mcp_clients
logger.error(f'Failed to connect to {server_url}: {str(e)}')
File "/home/hoang/miniconda3/lib/python3.12/logging/__init__.py", line 1568, in error
self._log(ERROR, msg, args, **kwargs)
File "/home/hoang/miniconda3/lib/python3.12/logging/__init__.py", line 1684, in _log
self.handle(record)
The config seems to be loaded and updated correctly though:
08:38:06 - openhands:DEBUG: action_execution_client.py:364 - [runtime dbc302983ed7427f8f35dc29e9f4aff7] Updating MCP server to: [{'name': 'jetbrains', 'command': 'npx', 'args': ['-y', '@jetbrains/mcp-proxy'], 'env': {}}]
08:38:10 - openhands:INFO: action_execution_client.py:381 - [runtime dbc302983ed7427f8f35dc29e9f4aff7] Updated MCP config: [MCPSSEServerConfig(url='http://localhost:33509/sse', api_key='******')]
08:38:10 - openhands:DEBUG: utils.py:84 - Creating MCP clients with config: sse_servers=[MCPSSEServerConfig(url='http://localhost:33509/sse', api_key='******')] stdio_servers=[MCPStdioServerConfig(name='jetbrains', command='npx', args=['-y', '@jetbrains/mcp-proxy'], env={})]
08:38:10 - openhands:INFO: utils.py:52 - Initializing MCP agent for url='http://localhost:33509/sse' api_key='******' with SSE connection...
@xingyaoww do you have any ideas? Here is what it looks like from MCP Inspector:
It is possible it might be npx related error? @ryanhoangt can you try DEBUG_RUNTIME=1 and see if that shows error?
Here's the error message inside runtime:
INFO:mcpm.router.router:Connected to server jetbrains with capabilities: experimental=None logging=None prompts=None resources=ResourcesCapability(subscribe=None, listChanged=None) tools=ToolsCapability(listChanged=True)
ERROR:mcpm.router.router:Failed to add server jetbrains: No working IDE endpoint available.
16:56:36 - openhands:INFO: action_execution_server.py:901 - MCP router updated successfully
Looks like we need to open Jetbrains IDE before starting MCP server. From the README:
After installing the MCP Server Plugin, and adding the JSON to the config file, restart Claude Desktop, and make sure the Jetbrains product is open before restarting Claude Desktop.
@metal450 could you open the IDE, install the plugin and then start OH to see if it works?
The tricky thing i believe is that "runtime" runs in its own docker so it can access IDE in the host machine :(
I think you'll also need to configure this: https://github.com/JetBrains/mcp-jetbrains/blob/main/README.md#configuration
Here's the error message inside runtime:
INFO:mcpm.router.router:Connected to server jetbrains with capabilities: experimental=None logging=None prompts=None resources=ResourcesCapability(subscribe=None, listChanged=None) tools=ToolsCapability(listChanged=True) ERROR:mcpm.router.router:Failed to add server jetbrains: No working IDE endpoint available. 16:56:36 - openhands:INFO: action_execution_server.py:901 - MCP router updated successfully
Hmm, I think the first issue here then would be to expose these types of logs to the main openhands log output - i.e. "No working IDE endpoint available" should be visible to the user.
could you open the IDE, install the plugin and then start OH to see if it works?
It had already been open. I'd also stopped & restarted OpenHands while the IDE was open just to be sure. I've also verified it works using Claude Desktop, so I know the plugin/server in the IDE is running properly.
I think you'll also need to configure this: https://github.com/JetBrains/mcp-jetbrains/blob/main/README.md#configuration
Ah, that looks promising! And yeah, makes sense since it's running inside the Docker container, that it needs to know how to call out to a server running on the system.
However, I tried setting HOST=host.docker.internal but no avail. Also tried the specific IP of the host machine on the LAN ( 192.168.3.2) but still no go.
In any event, I think the issue here is just that it needs to expose those logs so it's easier to debug what's going on 🙏
@ryanhoangt could we think of a way to expose those logs?
I remember these is a specific logger for MCP Router, maybe we should by default pass that somehow to frontend (eg when the backend MCP server is updated, capture all logs and then send back as part of the reset request)
@OpenHands can you think of ways to implement the log passing mechanism I described in the issue comment?
Maybe smth like: I want the /update_mcp_config in action execution server to return the error logs in the next 2 seconds before return back
I'm on it! xingyaoww can track my progress at all-hands.dev
Work Summary: MCP Log Passing Mechanism Implementation
I've successfully implemented the log passing mechanism for the MCP router as requested in issue #8514. This enhancement helps users debug MCP server configuration issues by exposing error logs that were previously hidden.
What I Did:
-
Created a Log Capture System:
- Implemented a
QueueHandlerclass to capture logs from the MCP router - Added code to collect logs for 2 seconds after MCP server updates
- Modified the
/update_mcp_serverendpoint to return these logs as part of its response
- Implemented a
-
Updated Client-Side Processing:
- Enhanced the action execution client to display captured logs to users
- Increased timeout from 10 to 15 seconds to account for log collection
-
Added Comprehensive Tests:
- Created unit tests to verify the log capture functionality
- Tested both the
QueueHandlerclass and the log capture in the endpoint
-
Created a Pull Request:
- PR #8532: https://github.com/All-Hands-AI/OpenHands/pull/8532
- The PR is currently in draft status and fixes issue #8514
This implementation will help users like @metal450 see important error messages like "No working IDE endpoint available" that were previously hidden, making it much easier to troubleshoot MCP configuration issues.