When I call a MCP Tool using FastMCP, I am not getting Context initialized correctly

Langchain version: 1.2.15

langchain-mcp-adapters version: 0.2.2

FastMCP Version : 3.2.0

My MCP tool needs access to ctx.transport value, (stdio, sse etc.) to do some specific processing. Sample tool as below:

@tally_mcp.tool()

async def my_tool(ctx: Context) โ†’ dict:

"""My tool access data based on transport."""

transport=ctx.transport  #introduced in FastMCP v3

return { "transport": transport }

At client side my langchain code is as below:

client = MultiServerMCPClient(
        {
            "mcp_server": {
                "transport": "stdio",
                "command": "python",
                "args": ["mcp_stdio_server.py"]
            }
        }
    )
tools = await client.get_tools() 
agent =  create_agent(
            model=โ€ฆ,
            tools=tools  
        )
response = await agent.ainvoke(

            {"messages": [{"role": "user", "content": "list my companies."}]}

        )

In the tool response I am getting:

[{โ€˜typeโ€™: โ€˜textโ€™, โ€˜textโ€™: โ€˜{โ€œtransportโ€: null\n}โ€™, โ€˜idโ€™: โ€˜lc_2e6e7b99-d184-4b40-93f8-3acabdeffe33โ€™}]

This should be set as โ€˜stdioโ€™. is it a bug in Langchain?

Hello @tuhin-52321

I replicated your flow with following versions:

langchain-mcp-adapters: 0.2.2
fastmcp: 3.2.2
langchain: 1.2.15

server.py


"""FastMCP server demonstrating ctx.transport access in a tool."""

from fastmcp import FastMCP, Context

tally_mcp = FastMCP(name="tally-mcp-server")


@tally_mcp.tool()
async def my_tool(ctx: Context) -> dict:
    """Return transport info and list sample companies based on the transport type."""
    transport = ctx.transport

    companies = ["Acme Corp", "Globex Inc", "Initech Ltd"]

    return {
        "transport": transport,
        "companies": companies,
        "note": f"Fetched via {transport!r} transport",
    }


if __name__ == "__main__":
    tally_mcp.run(transport="stdio")

client.py


async def main() -> None:
    client = MultiServerMCPClient(
        {
            "mcp_server": {
                "transport": "stdio",
                "command": "python3",
                "args": ["mcp_stdio_server.py"],
            }
        }
    )

    tools = await client.get_tools()
    print(f"Loaded {len(tools)} tool(s): {[t.name for t in tools]}")

    model = ChatOpenAI(model="gpt-4o-mini")
    agent = create_agent(model=model, tools=tools)

    response = await agent.ainvoke(
        {"messages": [{"role": "user", "content": "list my companies."}]}
    )

    for msg in response["messages"]:
        role = getattr(msg, "type", msg.__class__.__name__)
        content = msg.content
        if content:
            print(f"\n[{role}]: {content}")


if __name__ == "__main__":
    asyncio.run(main())

And got the following output:


[04/09/26 20:59:32] INFO     Starting MCP server 'tally-mcp-server' with transport 'stdio'                                                                                                                        transport.py:209
Loaded 1 tool(s): ['my_tool']


                                                                         โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                                                                         
                                                                         โ”‚                                                                              โ”‚                                                                         
                                                                         โ”‚                                                                              โ”‚                                                                         
                                                                         โ”‚                         โ–„โ–€โ–€ โ–„โ–€โ–ˆ โ–ˆโ–€โ–€ โ–€โ–ˆโ–€ โ–ˆโ–€โ–„โ–€โ–ˆ โ–ˆโ–€โ–€ โ–ˆโ–€โ–ˆ                        โ”‚                                                                         
                                                                         โ”‚                         โ–ˆโ–€  โ–ˆโ–€โ–ˆ โ–„โ–„โ–ˆ  โ–ˆ  โ–ˆ โ–€ โ–ˆ โ–ˆโ–„โ–„ โ–ˆโ–€โ–€                        โ”‚                                                                         
                                                                         โ”‚                                                                              โ”‚                                                                         
                                                                         โ”‚                                                                              โ”‚                                                                         
                                                                         โ”‚                                FastMCP 3.2.2                                 โ”‚                                                                         
                                                                         โ”‚                            https://gofastmcp.com                             โ”‚                                                                         
                                                                         โ”‚                                                                              โ”‚                                                                         
                                                                         โ”‚                  ๐Ÿ–ฅ  Server:      tally-mcp-server, 3.2.2                     โ”‚                                                                         
                                                                         โ”‚                  ๐Ÿš€ Deploy free: https://horizon.prefect.io                  โ”‚                                                                         
                                                                         โ”‚                                                                              โ”‚                                                                         
                                                                         โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                                                                         


[04/09/26 20:59:36] INFO     Starting MCP server 'tally-mcp-server' with transport 'stdio'                                                                                                                        transport.py:209

[human]: list my companies.

[tool]: [{'type': 'text', 'text': '{"transport":"stdio","companies":["Acme Corp","Globex Inc","Initech Ltd"],"note":"Fetched via \'stdio\' transport"}', 'id': 'lc_2cd0cb69-1b5b-46ed-9b21-503b6fdc3f17'}]

[ai]: Here are your companies:

1. Acme Corp
2. Globex Inc
3. Initech Ltd

As you can see, I was able to access the transport attribute and did not get a null, which you are getting.
The only difference I see is that I am using the latest fast mcp version, so perhaps try updating it.

I upgraded to FastMCP 3.2.3:

Name: fastmcp
Version: 3.2.3
Summary: The fast, Pythonic way to build MCP servers and clients.
Home-page: https://gofastmcp.com
Author: Jeremiah Lowin
Author-email:
License-Expression: Apache-2.0
Location: d:\work\code.tallyai.backend.venv\Lib\site-packages
Requires: authlib, cyclopts, exceptiongroup, httpx, jsonref, jsonschema-path, mcp, openapi-pydantic, opentelemetry-api, packaging, platformdirs, py-key-value-aio, pydantic, pyperclip, python-dotenv, pyyaml, rich, uncalled-for, uvicorn, watchfiles, websockets
Required-by:
(.venv) PS D:\work\code.tallyai.backen

Still no luck.

AI response:
Tool response: [{โ€˜typeโ€™: โ€˜textโ€™, โ€˜textโ€™: โ€˜{\n โ€œtransportโ€: null,\n โ€œcompaniesโ€: [\n โ€œAcme Corpโ€,\n โ€œGlobex Incโ€,\n โ€œInitech Ltdโ€\n ],\n โ€œnoteโ€: โ€œFetched via None transportโ€\n}โ€™, โ€˜idโ€™: โ€˜lc_0541a012-cd29-4337-acb8-bad716058f2eโ€™}]
AI response: Here are your companies: Acme Corp, Globex Inc, Initech Ltd.

Another difference, I am using ChatGoogleGenerativeAI(vertexai=True, โ€ฆ) , not ChatOpenAI.

I am using Gemini 2.5 Flash via Vertex AI. Could that be the issue?

I am using Windows OS for testing - can this be cause of the issue?

UPDATE:

Found the problem - it is Windows OS issue. Same code working fine in my Mac. With Mac the output coming correctly. But with Windows , it is not working. In Windows I am not even getting the info log when mc server starts in stdio mode โ€œ [04/09/26 20:59:36] INFO Starting MCP server โ€˜tally-mcp-serverโ€™ with transport โ€˜stdioโ€™โ€œ

Is FastMCP not supported in Windows?

UPDATE:

Created below setup:

  1. MCP Server running on Docker
  2. Langchain is running on Windows.

Still same issue. No idea what is happening. This time I used HTTP Streamble transport.

Docker run output:

INFO: Started server process [7]
INFO: Waiting for application startup.
INFO | mcp.server.streamable_http_manager | streamable_http_manager.py:128 | StreamableHTTP session manager started
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO | mcp.server.streamable_http_manager | streamable_http_manager.py:255 | Created new transport with session ID: fa3cd8fb3c2941f1b455a9b90ac00ba6
INFO: 172.17.0.1:41112 - โ€œPOST /mcp HTTP/1.1โ€ 200 OK
INFO: 172.17.0.1:41122 - โ€œPOST /mcp HTTP/1.1โ€ 202 Accepted
INFO: 172.17.0.1:41126 - โ€œGET /mcp HTTP/1.1โ€ 200 OK
INFO: 172.17.0.1:41136 - โ€œPOST /mcp HTTP/1.1โ€ 200 OK
INFO | mcp.server.lowlevel.server | server.py:727 | Processing request of type ListToolsRequest
INFO | mcp.server.streamable_http | streamable_http.py:785 | Terminating session: fa3cd8fb3c2941f1b455a9b90ac00ba6
INFO: 172.17.0.1:41150 - โ€œDELETE /mcp HTTP/1.1โ€ 200 OK
INFO | mcp.server.streamable_http_manager | streamable_http_manager.py:255 | Created new transport with session ID: 5f5d5c8550f94b5f8d9fcd9cb85b233c
INFO: 172.17.0.1:43074 - โ€œPOST /mcp HTTP/1.1โ€ 200 OK
INFO: 172.17.0.1:43076 - โ€œPOST /mcp HTTP/1.1โ€ 202 Accepted
INFO: 172.17.0.1:43084 - โ€œGET /mcp HTTP/1.1โ€ 200 OK
INFO: 172.17.0.1:43086 - โ€œPOST /mcp HTTP/1.1โ€ 200 OK
INFO | mcp.server.lowlevel.server | server.py:727 | Processing request of type CallToolRequest
INFO | mcp_tools_logger | tally_mcp_tools.py:19 | [1] Received request with transport: None
INFO: 172.17.0.1:43102 - โ€œPOST /mcp HTTP/1.1โ€ 200 OK
INFO | mcp.server.lowlevel.server | server.py:727 | Processing request of type ListToolsRequest
INFO | mcp.server.streamable_http | streamable_http.py:785 | Terminating session: 5f5d5c8550f94b5f8d9fcd9cb85b233c
INFO: 172.17.0.1:43116 - โ€œDELETE /mcp HTTP/1.1โ€ 200 OK

MCP Client output:

(.venv) PS D:\work\code.tallyai.backend\conversational-ai\infra\cdk\lib\docker\llm-ws> python .\tally_mcp_client_test.py

[human]: list my companies.

[tool]: [{โ€˜typeโ€™: โ€˜textโ€™, โ€˜textโ€™: โ€˜{\n โ€œtransportโ€: null,\n โ€œcompaniesโ€: [\n โ€œAcme Corpโ€,\n โ€œGlobex Incโ€,\n โ€œInitech Ltdโ€\n ],\n โ€œnoteโ€: โ€œFetched via None transportโ€\n}โ€™, โ€˜idโ€™: โ€˜lc_619d944a-f402-4865-9ef6-569ed76ae5d2โ€™}]

[ai]: Here are your companies: Acme Corp, Globex Inc, Initech Ltd.
(.venv) PS D:\work\code.tallyai.backend\conversational-ai\infra\cdk\lib\docker\llm-ws>

is the issue in client side of Windows?

Working when client is run from Mac, but not working when client is run from Windows.

Client Code:

tally_mco_client_test.py

import os
os.environ["MCP_PORT"] = "8000"

import asyncio
from langchain.agents import create_agent

mcp_port = os.getenv("MCP_PORT", "8000")

def get_mcp_client(thread_id: str, company_id: str, mobile_number: str) -> MultiServerMCPClient:
    tally_mcp_client = MultiServerMCPClient(
        {
            "tally_mcp_server": {
                "transport": "streamable_http",
                "url": "http://localhost:" + mcp_port + "/mcp"
            }
        }
    )
    return tally_mcp_client

async def main():

    client = get_mcp_client(thread_id, company_id, mobile_number)

    #Get Tools
    tools = await client.get_tools()

    agent = create_agent(
            model=...,
            tools=tools  
        )

    tally_response = await agent.ainvoke(
            {"messages": [{"role": "user", "content": "list my companies."}]}
        )
    
    for msg in tally_response["messages"]:
        role = getattr(msg, "type", msg.__class__.__name__)
        content = msg.content
        if content:
            print(f"\n[{role}]: {content}")
        
if __name__ == "__main__":
    asyncio.run(main())

Docker Directory For MCP Server:

Dockerfile:

# Step 1: Use the official Python image (LTS version)
FROM python:3.13

ARG MCP_PORT
ARG LOG_LEVEL
# Step 2: Set the working directory inside the container
WORKDIR /usr/src/app


COPY requirements.txt ./

COPY *.py ./

# Step 3 : Install required python packages
RUN pip install --upgrade pip 
RUN pip install -r requirements.txt


# Step 4: Expose the port your application will run on (e.g., 80)
# EXPOSE Ports
EXPOSE ${MCP_PORT}

#Environment Variables

ENV MCP_PORT=${MCP_PORT}
ENV LOG_LEVEL=${LOG_LEVEL}

# Step 6: Set the command to start the application
COPY --chmod=755 <<EOT /usr/src/app/start.sh
#!/usr/bin/env bash
set -e
uvicorn --host 0.0.0.0 --port ${MCP_PORT} tally_mcp_server:mcp_app
EOT
ENTRYPOINT ["/usr/src/app/start.sh"]

tally_mcp_server.py

from mcp.server.fastmcp import FastMCP
from fastmcp.server.context import Context

# Create a server instance
tally_mcp = FastMCP(
    name="tally_mcp_server"
)


@tally_mcp.tool()
async def list_companies(ctx: Context) -> dict:
    """Return transport info and list sample companies based on the transport type."""
    transport = ctx.transport
    companies = ["Acme Corp", "Globex Inc", "Initech Ltd"]

    return {
        "transport": transport,
        "companies": companies,
        "note": f"Fetched via {transport!r} transport",
    }
    

My client side requirement.txt file (is this a problem?)

langchain-google-vertexai~=3.2.2
boto3~=1.42.83
fastapi~=0.124.4
pandas~=2.3.3
psutil~=7.1.3
langchain-tavily~=0.2.17
cryptography~=46.0.6
langchain-community~=0.4.1
valkey~=6.1.1
langchain_aws~=1.1.0
scipy~=1.16.3
langchain_chroma~=1.0.0
langchain_milvus~=0.3.3
tiktoken~=0.12.0
jellyfish~=1.2.1
langgraph-checkpoint-postgres~=3.0.5
uvicorn-worker~=0.4.0
uvicorn~=0.38.0
gunicorn~=23.0.0
aiohttp~=3.13.5
google-auth~=2.49.1
google-auth-oauthlib~=1.3.1
langchain~=1.2.15
langchain-core~=1.2.26
langchain-google-genai~=4.2.1
google-genai~=1.66.0
google-cloud-aiplatform~=1.140.0
vertexai~=1.43.0
langgraph~=1.1.6
langgraph-supervisor~=0.0.31
langgraph-prebuilt~=1.0.9
fastmcp~=3.2.2
langchain-mcp-adapters~=0.2.2

1 Like

Since I am not able to replicate this issue on Linux, I believe this may be a bug in FastMCP rather than in the LangChain MCP adapter, as the transport attribute in the tool is isolated to the FastMCP package.

I think you should open an issue on the official FastMCP repository. I also checked online and found no similar reported issues.

Additionally, since the transport attribute was introduced very recently in FastMCP, there is a good chance there is a bug specific to the Windows version.