When using the Dynamic GitLab API, making concurrent tool calls with the same mcp-session-id causes the second (and subsequent) requests to hang indefinitely until timeout.
Expected Behavior
Both tool calls should complete successfully and return file contents.
Actual Behavior
First request completes successfully (returns file content)
Second request hangs indefinitely (no response)
After 60 seconds: McpError: MCP error -32001: Request timed out
script.js
import { MultiServerMCPClient } from '@langchain/mcp-adapters';
/**
*
* Setup:
* 1. Start MCP server
* 2. Configure MCP_ENDPOINT below
* 3. Run: node test.js
*
* Expected: Both files fetched successfully
* Actual: Second request hangs for 60s then times out
*/
const MCP_ENDPOINT = process.env.MCP_ENDPOINT || 'http://127.0.0.1:3002/mcp';
const PROJECT_ID = process.env.PROJECT_ID || 'xxx';
async function testConcurrentCalls() {
console.log('🔧 Connecting to MCP server at:', MCP_ENDPOINT);
const client = new MultiServerMCPClient({
mcpServers: {
gitlab: {
transport: 'http',
url: MCP_ENDPOINT,
headers: {
Authorization: `Bearer xxx`,
'X-GitLab-API-URL': 'http://gitlab.xxx.com',
},
},
},
beforeToolCall: ({ serverName, name, args }) => {
// Inject custom headers for this specific call
return {
args,
headers: {
Authorization: `Bearer xxx`,
'X-GitLab-API-URL': 'http://gitlab.xxx.com',
},
}
},
});
// Get tools
const tools = await client.getTools();
const getFileContentsTool = tools.find((t) => t.name === 'get_file_contents');
if (!getFileContentsTool) {
throw new Error('get_file_contents tool not found');
}
console.log('✅ Found get_file_contents tool');
// Test 1: Sequential calls (should work)
console.log('\n📝 Test 1: Sequential calls');
console.time('Sequential');
await getFileContentsTool.invoke({
project_id: PROJECT_ID,
file_path: 'package.json',
ref: 'test',
});
console.log(' ✅ File 1 fetched');
await getFileContentsTool.invoke({
project_id: PROJECT_ID,
file_path: 'README.md',
ref: 'test',
});
console.log(' ✅ File 2 fetched');
console.timeEnd('Sequential');
// Test 2: Concurrent calls (BUG - second one will hang)
console.log('\n⚠️ Test 2: Concurrent calls (THIS WILL HANG)');
console.time('Concurrent');
try {
const [file3, file4] = await Promise.all([
getFileContentsTool.invoke({
project_id: PROJECT_ID,
file_path: 'package.json',
ref: 'test',
}),
getFileContentsTool.invoke({
project_id: PROJECT_ID,
file_path: 'README.md',
ref: 'test',
}),
]);
console.log(' ✅ File 3 fetched');
console.log(' ✅ File 4 fetched');
console.timeEnd('Concurrent');
} catch (error) {
console.timeEnd('Concurrent');
console.error(' ❌ Error:', error.message);
throw error;
}
}
testConcurrentCalls()
.then(() => {
console.log('\n✅ All tests passed!');
process.exit(0);
})
.catch((error) => {
console.error('\n❌ Test failed:', error.message);
process.exit(1);
});
script.js Output
🔧 Connecting to MCP server at: http://127.0.0.1:3002/mcp
✅ Client created
✅ Found get_file_contents tool
📝 Test 1: Sequential calls
✅ File 1 fetched
✅ File 2 fetched
Sequential: 354.626ms
⚠️ Test 2: Concurrent calls (THIS WILL HANG)
McpError: MCP error -32001: Request timed out
at McpError.fromError (file:///home/binqi/github/dependencies-builder/node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_@cfworker+json-schema@4.1.1_hono@4.10.6_zod@4.1.12/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js:2035:16)
at Timeout.timeoutHandler (file:///home/binqi/github/dependencies-builder/node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_@cfworker+json-schema@4.1.1_hono@4.10.6_zod@4.1.12/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js:692:58)
at listOnTimeout (node:internal/timers:594:17)
at process.processTimers (node:internal/timers:529:7) {
code: -32001,
data: { timeout: 60000 }
}
Concurrent: 1:00.039 (m:ss.mmm)
❌ Error: Error calling tool get_file_contents: McpError: MCP error -32001: Request timed out
❌ Test failed: Error calling tool get_file_contents: McpError: MCP error -32001: Request timed out
mcp output
INFO [06:35:37.933] (1772223): Remote authorization enabled: tokens will be read from HTTP headers
INFO [06:35:37.933] (1772223): Configuration validation passed
INFO [06:35:37.934] (1772223): Initializing server with transport mode:
WARN [06:35:37.934] (1772223): Starting GitLab MCP Server with Streamable HTTP transport
INFO [06:35:37.941] (1772223): Configured GitLab API URLs: http://gitlab.seeyon.com/api/v4
INFO [06:35:37.941] (1772223): Default GitLab API URL: http://gitlab.seeyon.com/api/v4
INFO [06:35:37.948] (1772223): GitLab MCP Server running with Streamable HTTP transport
INFO [06:35:37.948] (1772223): Endpoint: http://127.0.0.1:3002/mcp
WARN [06:35:47.857] (1772223): Streamable HTTP session initialized: a6b1c09f-90ec-4696-9d08-ce9235758c4f
INFO [06:35:47.857] (1772223): Session a6b1c09f-90ec-4696-9d08-ce9235758c4f: stored Authorization header
DEBUG [06:35:47.892] (1772223): Session a6b1c09f-90ec-4696-9d08-ce9235758c4f: updated Authorization header
DEBUG [06:35:47.905] (1772223): Session a6b1c09f-90ec-4696-9d08-ce9235758c4f: updated Authorization header
WARN [06:35:47.930] (1772223): Streamable HTTP session initialized: 1c822589-3d9c-4812-bd31-dd563b71c5e8
INFO [06:35:47.930] (1772223): Session 1c822589-3d9c-4812-bd31-dd563b71c5e8: stored Authorization header
DEBUG [06:35:47.936] (1772223): Session 1c822589-3d9c-4812-bd31-dd563b71c5e8: updated Authorization header
DEBUG [06:35:47.942] (1772223): Session 1c822589-3d9c-4812-bd31-dd563b71c5e8: updated Authorization header
INFO [06:35:47.947] (1772223): get_file_contents
DEBUG [06:35:47.948] (1772223): buildAuthHeaders: session context
context: {
"sessionId": "1c822589-3d9c-4812-bd31-dd563b71c5e8",
"header": "Authorization",
"token": "xxx",
"lastUsed": 1767940547942,
"apiUrl": "http://gitlab.xxx.com/api/v4"
}
WARN [06:35:48.127] (1772223): Streamable HTTP session initialized: 0f3700ca-b62a-4275-bf31-ba1e7f6f06a8
INFO [06:35:48.127] (1772223): Session 0f3700ca-b62a-4275-bf31-ba1e7f6f06a8: stored Authorization header
DEBUG [06:35:48.134] (1772223): Session 0f3700ca-b62a-4275-bf31-ba1e7f6f06a8: updated Authorization header
DEBUG [06:35:48.140] (1772223): Session 0f3700ca-b62a-4275-bf31-ba1e7f6f06a8: updated Authorization header
INFO [06:35:48.141] (1772223): get_file_contents
DEBUG [06:35:48.142] (1772223): buildAuthHeaders: session context
context: {
"sessionId": "0f3700ca-b62a-4275-bf31-ba1e7f6f06a8",
"header": "Authorization",
"token": "xxx",
"lastUsed": 1767940548139,
"apiUrl": "http://gitlab.xxx.com/api/v4"
}
WARN [06:35:48.316] (1772223): Streamable HTTP session initialized: dc5d0098-e2ab-435d-b282-28326b616e5f
INFO [06:35:48.316] (1772223): Session dc5d0098-e2ab-435d-b282-28326b616e5f: stored Authorization header
WARN [06:35:48.320] (1772223): Streamable HTTP session initialized: 149a183a-c743-4db2-affd-1a239a4e8909
INFO [06:35:48.320] (1772223): Session 149a183a-c743-4db2-affd-1a239a4e8909: stored Authorization header
DEBUG [06:35:48.325] (1772223): Session dc5d0098-e2ab-435d-b282-28326b616e5f: updated Authorization header
DEBUG [06:35:48.327] (1772223): Session 149a183a-c743-4db2-affd-1a239a4e8909: updated Authorization header
DEBUG [06:35:48.333] (1772223): Session dc5d0098-e2ab-435d-b282-28326b616e5f: updated Authorization header
INFO [06:35:48.335] (1772223): get_file_contents
DEBUG [06:35:48.335] (1772223): buildAuthHeaders: session context
context: {
"sessionId": "dc5d0098-e2ab-435d-b282-28326b616e5f",
"header": "Authorization",
"token": "xxx",
"lastUsed": 1767940548333,
"apiUrl": "http://gitlab.xxx.com/api/v4"
}
DEBUG [06:35:48.336] (1772223): Session 149a183a-c743-4db2-affd-1a239a4e8909: updated Authorization header
INFO [06:35:48.338] (1772223): get_file_contents
DEBUG [06:35:48.338] (1772223): buildAuthHeaders: session context
context: {
"sessionId": "149a183a-c743-4db2-affd-1a239a4e8909",
"header": "Authorization",
"token": "xxx",
"lastUsed": 1767940548336,
"apiUrl": "http://gitlab.xxx.com/api/v4"
}
When using the Dynamic GitLab API, making concurrent tool calls with the same mcp-session-id causes the second (and subsequent) requests to hang indefinitely until timeout.
Expected Behavior
Both tool calls should complete successfully and return file contents.
Actual Behavior
First request completes successfully (returns file content)
Second request hangs indefinitely (no response)
After 60 seconds: McpError: MCP error -32001: Request timed out
script.js
script.js Output
mcp output