Session Management & Tool Invocation with Gateway vs Direct MCP Client–Server #870
Replies: 2 comments
-
TL;DR: You're Right, This is ExpectedThe behavior you're seeing is exactly what should happen when Context Forge is configured in stateless mode (which it is by default). Let me break down what's going on: Session Behavior AnalysisDirect Client → MCP Server
Client → Gateway → MCP Server
What's Actually HappeningYour Current Config (check your # Streaming HTTP Configuration
USE_STATEFUL_SESSIONS=false # ← This is why you see multiple sessions
JSON_RESPONSE_ENABLED=true The Code Behind It ( if settings.use_stateful_sessions:
event_store = InMemoryEventStore()
stateless = False
else:
event_store = None
stateless = True # ← Gateway creates new session per tool call The FixFor your use case (multiple tool calls in a workflow), you probably want stateful sessions: Change your configuration: # Enable session persistence
USE_STATEFUL_SESSIONS=true
JSON_RESPONSE_ENABLED=true Why this helps:
When to Use Each Mode
Security Stuff (You're Already Doing This Right)Your current setup is actually pretty solid: # Your client code looks good
async with streamablehttp_client(
"http://localhost:4444/servers/{virtual-server-id}/mcp"
) as (read_stream, write_stream, _):
async with ClientSession(read_stream, write_stream) as session:
await session.initialize() # Single auth per workflow
tools_result = await session.list_tools()
result = await session.call_tool("ping-pong-ping", {}) You've got:
Recommended ConfigurationFor Your Workflow (Conversational/Multi-tool):# Enable persistent sessions
USE_STATEFUL_SESSIONS=true
JSON_RESPONSE_ENABLED=true
# Optional: Session timeout tuning
SESSION_TTL=3600 # 1 hour session lifetime
MESSAGE_TTL=300 # 5 minute message retention Production Considerations:# Security
AUTH_REQUIRED=true
JWT_SECRET_KEY=your-strong-secret
# Performance
DB_POOL_SIZE=200
CACHE_TYPE=redis # For session persistence across restarts
# Monitoring
METRICS_ENABLED=true
LOG_LEVEL=INFO Verification Steps
Bottom LineWhat you're seeing makes perfect sense:
The stateless default is there for high-availability deployments where you might have multiple gateway instances behind a load balancer. For your use case (sounds like development/single-instance), stateful sessions will give you the behavior that matches the direct MCP connection. Hope that clears things up! |
Beta Was this translation helpful? Give feedback.
-
Firstly, thank you for the detailed explanation of the Gateway workflow and for creating this amazing tool. Even with Interestingly, this behaviour is different when connecting directly (client → server). In that case, if I invoke two tools, I see a single This raised a few questions for me:
Would love to hear your insights on this. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Context
I have a simple MCP server built using FastMCP (Node.js).
I have a Python client using the Python MCP SDK to fetch tools and call them.
I have IBM Context Forge up and running, with my MCP server registered under the Gateways/MCP Servers tab.
To route calls through the Gateway, I created a Virtual Server, where I selected a subset of tools.
Current Behaviour
Direct client → MCP server (no Gateway):
Client → IBM Context Forge (Gateway) → MCP server:
Python Client:
Node.js MCP server:
Logs:
Question
Is this expected behaviour with IBM Context Forge?
What is the correct/ideal industry practice for MCP client–server communication in such a setup?
How should this setup be configured when factoring in authentication and security best practices?
Looking for insights on:
Beta Was this translation helpful? Give feedback.
All reactions