OpenHands icon indicating copy to clipboard operation
OpenHands copied to clipboard

[Bug]: npx MCP server not found

Open JGKle opened this issue 7 months ago • 10 comments

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: Image

Image

Yet it doesn't find it:

Image

Here's the only portion of the logs I see that mention MCP: Image

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

JGKle avatar May 15 '25 03:05 JGKle

Cc: @ryanhoangt Maybe this looks familiar? Not sure if this may be because of a failure when loading from UI or is it npx

enyst avatar May 15 '25 06:05 enyst

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:

Image

ryanhoangt avatar May 15 '25 09:05 ryanhoangt

It is possible it might be npx related error? @ryanhoangt can you try DEBUG_RUNTIME=1 and see if that shows error?

xingyaoww avatar May 15 '25 09:05 xingyaoww

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?

ryanhoangt avatar May 15 '25 17:05 ryanhoangt

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

xingyaoww avatar May 15 '25 17:05 xingyaoww

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 🙏

JGKle avatar May 16 '25 00:05 JGKle

@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)

xingyaoww avatar May 16 '25 03:05 xingyaoww

@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

xingyaoww avatar May 16 '25 03:05 xingyaoww

I'm on it! xingyaoww can track my progress at all-hands.dev

openhands-ai[bot] avatar May 16 '25 03:05 openhands-ai[bot]

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:

  1. Created a Log Capture System:

    • Implemented a QueueHandler class to capture logs from the MCP router
    • Added code to collect logs for 2 seconds after MCP server updates
    • Modified the /update_mcp_server endpoint to return these logs as part of its response
  2. 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
  3. Added Comprehensive Tests:

    • Created unit tests to verify the log capture functionality
    • Tested both the QueueHandler class and the log capture in the endpoint
  4. 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.

openhands-ai[bot] avatar May 16 '25 03:05 openhands-ai[bot]