Failing at get_tools() in production environment

2025-11-11 09:55:00.504 | INFO     | admin_portal.web.aichat.views:query:51 - User is querying: Give me detail about this subscription - ABCD Insurance company.
2025-11-11 09:55:00.520 | INFO     | admin_portal.web.aichat.service:fetch_mcp_tools:91 - Fetching tools from the MCP server...
2025-11-11 09:55:00 INFO     mcp.server.streamable_http_manager Created new transport with session ID: f8ac
2025-11-11 09:55:00.568 | INFO     | logging:callHandlers:1706 - 127.0.0.1:34858 - "POST /mcp HTTP/1.1" 200
2025-11-11 09:55:00 INFO     httpx           HTTP Request: POST http://127.0.0.1:8000/mcp "HTTP/1.1 200 OK"
2025-11-11 09:55:00 INFO     mcp.client.streamable_http Received session ID: f8ac
2025-11-11 09:55:00 INFO     mcp.client.streamable_http Negotiated protocol version: 2025-06-18
2025-11-11 09:55:00.571 | INFO     | logging:callHandlers:1706 - 127.0.0.1:34858 - "POST /mcp HTTP/1.1" 202
2025-11-11 09:55:00 INFO     httpx           HTTP Request: POST http://127.0.0.1:8000/mcp "HTTP/1.1 202 Accepted"
2025-11-11 09:55:00.573 | INFO     | logging:callHandlers:1706 - 127.0.0.1:34872 - "GET /mcp HTTP/1.1" 400
2025-11-11 09:55:00 INFO     httpx           HTTP Request: GET http://127.0.0.1:8000/mcp "HTTP/1.1 400 Bad Request"
2025-11-11 09:55:00.579 | INFO     | logging:callHandlers:1706 - 127.0.0.1:34888 - "POST /mcp HTTP/1.1" 400
2025-11-11 09:55:00 INFO     httpx           HTTP Request: POST http://127.0.0.1:8000/mcp "HTTP/1.1 400 Bad Request"
2025-11-11 09:55:00.580 | ERROR    | admin_portal.web.aichat.service:fetch_mcp_tools:111 - Failed to fetch MCP tools: unhandled errors in a TaskGroup (1 sub-exception)
  + Exception Group Traceback (most recent call last):
  |   File "/admin_portal/lib/python3.11/site-packages/admin_portal/web/aichat/service.py", line 107, in fetch_mcp_tools
  |     tools = await client.get_tools()
  |             ^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/admin_portal/lib/python3.11/site-packages/langchain_mcp_adapters/client.py", line 187, in get_tools
  |     tools_list = await asyncio.gather(*load_mcp_tool_tasks)
  |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/admin_portal/lib/python3.11/site-packages/langchain_mcp_adapters/tools.py", line 348, in load_mcp_tools
  |     async with create_session(
  |   File "/usr/local/lib/python3.11/contextlib.py", line 231, in __aexit__
  |     await self.gen.athrow(typ, value, traceback)
  |   File "/admin_portal/lib/python3.11/site-packages/langchain_mcp_adapters/sessions.py", line 409, in create_session
  |     async with _create_streamable_http_session(**params) as session:
  |   File "/usr/local/lib/python3.11/contextlib.py", line 231, in __aexit__
  |     await self.gen.athrow(typ, value, traceback)
  |   File "/admin_portal/lib/python3.11/site-packages/langchain_mcp_adapters/sessions.py", line 310, in _create_streamable_http_session
  |     async with (
  |   File "/usr/local/lib/python3.11/contextlib.py", line 231, in __aexit__
  |     await self.gen.athrow(typ, value, traceback)
  |   File "/admin_portal/lib/python3.11/site-packages/mcp/client/streamable_http.py", line 474, in streamablehttp_client
  |     async with anyio.create_task_group() as tg:
  |   File "/admin_portal/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 781, in __aexit__
  |     raise BaseExceptionGroup(
  | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "/admin_portal/lib/python3.11/site-packages/mcp/client/streamable_http.py", line 405, in handle_request_async
    |     await self._handle_post_request(ctx)
    |   File "/admin_portal/lib/python3.11/site-packages/mcp/client/streamable_http.py", line 277, in _handle_post_request
2025-11-11 09:55:00.582 | INFO     | admin_portal.web.aichat.service:fetch_mcp_tools:114 - Retrying to fetch tools... (1/9)
    |     response.raise_for_status()
    |   File "/admin_portal/lib/python3.11/site-packages/httpx/_models.py", line 761, in raise_for_status
    |     raise HTTPStatusError(message, request=request, response=self)
    | httpx.HTTPStatusError: Client error '400 Bad Request' for url 'http://127.0.0.1:8000/mcp'
    | For more information check: 

    +------------------------------------
2025-11-11 09:55:01 INFO     mcp.server.streamable_http_manager Created new transport with session ID: 8eb7
2025-11-11 09:55:01.619 | INFO     | logging:callHandlers:1706 - 127.0.0.1:48936 - "POST /mcp HTTP/1.1" 200
2025-11-11 09:55:01 INFO     httpx           HTTP Request: POST http://127.0.0.1:8000/mcp "HTTP/1.1 200 OK"
2025-11-11 09:55:01 INFO     mcp.client.streamable_http Received session ID: 8eb7
2025-11-11 09:55:01 INFO     mcp.client.streamable_http Negotiated protocol version: 2025-06-18
2025-11-11 09:55:01.623 | INFO     | logging:callHandlers:1706 - 127.0.0.1:48936 - "POST /mcp HTTP/1.1" 202
2025-11-11 09:55:01.623 | INFO     | logging:callHandlers:1706 - 127.0.0.1:48940 - "GET /mcp HTTP/1.1" 400
2025-11-11 09:55:01 INFO     httpx           HTTP Request: POST http://127.0.0.1:8000/mcp "HTTP/1.1 202 Accepted"
2025-11-11 09:55:01 INFO     httpx           HTTP Request: GET http://127.0.0.1:8000/mcp "HTTP/1.1 400 Bad Request"
2025-11-11 09:55:01.626 | INFO     | logging:callHandlers:1706 - 127.0.0.1:48948 - "POST /mcp HTTP/1.1" 400
2025-11-11 09:55:01 INFO     httpx           HTTP Request: POST http://127.0.0.1:8000/mcp "HTTP/1.1 400 Bad Request"
2025-11-11 09:55:01.628 | ERROR    | admin_portal.web.aichat.service:fetch_mcp_tools:111 - Failed to fetch MCP tools: unhandled errors in a TaskGroup (1 sub-exception)
  + Exception Group Traceback (most recent call last):
  |   File "/admin_portal/lib/python3.11/site-packages/admin_portal/web/aichat/service.py", line 107, in fetch_mcp_tools
  |     tools = await client.get_tools()
  |             ^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/admin_portal/lib/python3.11/site-packages/langchain_mcp_adapters/client.py", line 187, in get_tools
  |     tools_list = await asyncio.gather(*load_mcp_tool_tasks)
  |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/admin_portal/lib/python3.11/site-packages/langchain_mcp_adapters/tools.py", line 348, in load_mcp_tools
  |     async with create_session(
  |   File "/usr/local/lib/python3.11/contextlib.py", line 231, in __aexit__
  |     await self.gen.athrow(typ, value, traceback)
  |   File "/admin_portal/lib/python3.11/site-packages/langchain_mcp_adapters/sessions.py", line 409, in create_session
  |     async with _create_streamable_http_session(**params) as session:
  |   File "/usr/local/lib/python3.11/contextlib.py", line 231, in __aexit__
  |     await self.gen.athrow(typ, value, traceback)
  |   File "/admin_portal/lib/python3.11/site-packages/langchain_mcp_adapters/sessions.py", line 310, in _create_streamable_http_session
  |     async with (
  |   File "/usr/local/lib/python3.11/contextlib.py", line 231, in __aexit__
  |     await self.gen.athrow(typ, value, traceback)
  |   File "/admin_portal/lib/python3.11/site-packages/mcp/client/streamable_http.py", line 474, in streamablehttp_client
  |     async with anyio.create_task_group() as tg:
  |   File "/admin_portal/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 781, in __aexit__
  |     raise BaseExceptionGroup(
  | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "/admin_portal/lib/python3.11/site-packages/mcp/client/streamable_http.py", line 405, in handle_request_async
    |     await self._handle_post_request(ctx)
    |   File "/admin_portal/lib/python3.11/site-packages/mcp/client/streamable_http.py", line 277, in _handle_post_request
    |     response.raise_for_status()
    |   File "/admin_portal/lib/python3.11/site-packages/httpx/_models.py", line 761, in raise_for_status
    |     raise HTTPStatusError(message, request=request, response=self)
    | httpx.HTTPStatusError: Client error '400 Bad Request' for url 'http://127.0.0.1:8000/mcp'
    | For more information check: 

    +------------------------------------
2025-11-11 09:55:01.629 | INFO     | admin_portal.web.aichat.service:fetch_mcp_tools:114 - Retrying to fetch tools... (2/9)
2025-11-11 09:55:03 INFO     mcp.server.streamable_http_manager Created new transport with session ID: a051
2025-11-11 09:55:03.668 | INFO     | logging:callHandlers:1706 - 127.0.0.1:48956 - "POST /mcp HTTP/1.1" 200
2025-11-11 09:55:03 INFO     httpx           HTTP Request: POST http://127.0.0.1:8000/mcp "HTTP/1.1 200 OK"
2025-11-11 09:55:03 INFO     mcp.client.streamable_http Received session ID: a051
2025-11-11 09:55:03 INFO     mcp.client.streamable_http Negotiated protocol version: 2025-06-18
2025-11-11 09:55:03.671 | INFO     | logging:callHandlers:1706 - 127.0.0.1:48956 - "POST /mcp HTTP/1.1" 202
2025-11-11 09:55:03 INFO     httpx           HTTP Request: POST http://127.0.0.1:8000/mcp "HTTP/1.1 202 Accepted"
2025-11-11 09:55:03 INFO     mcp.server.lowlevel.server Processing request of type ListToolsRequest
2025-11-11 09:55:03.673 | INFO     | logging:callHandlers:1706 - 127.0.0.1:48960 - "GET /mcp HTTP/1.1" 400
2025-11-11 09:55:03.676 | INFO     | logging:callHandlers:1706 - 127.0.0.1:48968 - "POST /mcp HTTP/1.1" 200
2025-11-11 09:55:03 INFO     httpx           HTTP Request: GET http://127.0.0.1:8000/mcp "HTTP/1.1 400 Bad Request"
2025-11-11 09:55:03 INFO     httpx           HTTP Request: POST http://127.0.0.1:8000/mcp "HTTP/1.1 200 OK"
2025-11-11 09:55:03 INFO     mcp.server.streamable_http Terminating session: a0513814ddb24c73afb4bab78a7e7b8a
2025-11-11 09:55:03.682 | INFO     | logging:callHandlers:1706 - 127.0.0.1:48968 - "DELETE /mcp HTTP/1.1" 200
2025-11-11 09:55:03 INFO     httpx           HTTP Request: DELETE http://127.0.0.1:8000/mcp "HTTP/1.1 200 OK"
2025-11-11 09:55:03.684 | INFO     | admin_portal.web.aichat.service:fetch_mcp_tools:108 - Successfully fetched 55 tools from the MCP server.

###########################################################################
THESE ARE THE LOGS. AS YOU CAN SEE AM FACING SOME ISSUE with get_tools().

my MCP configuration:

client = MultiServerMCPClient(
                {
                    "api-server": {
                        "url": base_url,
                        "transport": "streamable_http",
                        "headers": {
                            "Authorization": f"{token}",
                        },
                    },
                }
            )

I am creating mcp clients for each session to get the tools and then am binding those tools to the llm.


def call_model(state: AgentState):
    """Call the LLM model."""
    messages = state["messages"]
    user = state["user"]
    token = state["token"]

    with temporary_env(REQUESTS_CA_BUNDLE=pem_path, SSL_CERT_FILE=pem_path):
        llm = ChatOpenAI(
            model=settings.llm_model,
            base_url=settings.llm_openai_api_base,
            api_key=settings.llm_openai_api_key,
            model_kwargs={"user": user},
        )

    # Get tools and bind to model
    tools = asyncio.run(fetch_mcp_tools(base_url=f"{settings.mcp_url}", token=token))
    llm_with_tools = llm.bind_tools(tools)
    logger.info(f"LLM with {len(tools)} tools bound.")

    response = llm_with_tools.invoke(messages)
    return {"messages": [response]}


Guys could you please help me in figuring out how I can resolve this error ?

Hi @dmc11 Can you share fetch_mcp_tools code once?

async def fetch_mcp_tools(base_url=None, token=None) -> List[BaseTool]:
    """Fetch tools from the MCP server and create LangChain tools
    dynamically."""
    logger.info("Fetching tools from the MCP server...")
    retry_count = int(settings.tools_retry_attempts)
    # Retry logic for fetching tools
    for retry in range(retry_count):
        try:
            client = MultiServerMCPClient(
                {
                    "api-server": {
                        "url": base_url,
                        "transport": "streamable_http",
                        "headers": {
                            "Authorization": f"{token}",
                        },
                    },
                }
            )
            tools = await client.get_tools()
            logger.info(f"Successfully fetched {len(tools)} tools from the MCP server.")
            return tools
        except Exception as e:
            logger.error(f"Failed to fetch MCP tools: {str(e)}")
            traceback.print_exc()
            if retry < retry_count - 1:
                logger.info(f"Retrying to fetch tools... ({retry + 1}/{retry_count-1})")
                await asyncio.sleep(2**retry)
            else:
                raise HTTPException(
                    status_code=500,
                    detail=f"Error occurred while initializing required tools: {str(e)}",
                ) from e

HI @heisenberg-7 This is the fetch_mcp_tools() .

Can you please try below once:

async def call_model(state: AgentState):
    """Call the LLM model."""
    messages = state["messages"]
    user = state["user"]
    token = state["token"]

    with temporary_env(REQUESTS_CA_BUNDLE=pem_path, SSL_CERT_FILE=pem_path):
        llm = ChatOpenAI(
            model=settings.llm_model,
            base_url=settings.llm_openai_api_base,
            api_key=settings.llm_openai_api_key,
            model_kwargs={"user": user},
        )

    # Get tools and bind to model
    tools = await fetch_mcp_tools(base_url=f"{settings.mcp_url}", token=token)
    llm_with_tools = llm.bind_tools(tools)
    logger.info(f"LLM with {len(tools)} tools bound.")

    response = llm_with_tools.invoke(messages)
    return {"messages": [response]}

If it does not work can you please also share api-server code?

The thing is, this issue is only showing up in staging or production env. I am unable to replicate this issue in my local, also if I do make this change I need to be able to explain also why this will work ? Could you please explain why this should work ? Also I thought my issue might be more related to me creating mutiplt mcp clients, ie on each request am creating a mcp client. If this is the issue how can I resolve it, because I am making those mutiple mcp clients just to get the tools and bind them to llm, what way can i follow to reuse them ?