Description
Describe the bug
I am tesing an MPC client in a console application. I am trying to connect to an MPC server hosted on AWS this server uses streamable http transport
I can connect to MCP server using the Python SDK can the streamable httpp client
I can connect to the MCP server using Postman if I post in the follwoing payload to initialise
In my c# code I am getting a 400 bad request when I try to create the client using the SSE transport with UseStreamableHttp = true.
I am using version preview 13 of your library.
I can connect using a basic http client mimicing the postman inputs.
I think the transport is not intialising correctly possibly still expecting and end point ending in /sse my endpoint ends in /mcp.
Any suggestions or guidance woudl be much appreciated
I have come acorss the following class StreamableHttpClientSessionTransport that looks like it could do the job, but it is not public. Am I using the wrong transportation class in my mcp client?
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"serverInfo": {
"name": "mcp-lambda-server",
"version": "1.0.0"
},
"capabilities": {
"tools": {
"list": true,
"call": true
}
}
}
}
public class RemoteMcpClient
{
private readonly IMcpClient _mcpClient;
// Private constructor for factory pattern
private RemoteMcpClient(IMcpClient mcpClient)
{
_mcpClient = mcpClient;
}
// Factory method instead of constructor
public static async Task<RemoteMcpClient> CreateAsync(string sseUrl, Dictionary<string, string> headers)
{
try
{
// Create an SSE transport instance using the given URL
var transport = new SseClientTransport(new SseClientTransportOptions
{
Name = "Test",
Endpoint = new Uri(sseUrl),
UseStreamableHttp = true,
AdditionalHeaders = headers,
ConnectionTimeout = TimeSpan.FromSeconds(600)
});
Console.WriteLine($"Attempting to connect to MCP endpoint: {sseUrl}");
var mcpClient = await McpClientFactory.CreateAsync(transport);
Console.WriteLine("MCP client created successfully");
return new RemoteMcpClient(mcpClient);
}
catch (Exception ex)
{
Console.WriteLine($"Error creating MCP client: {ex.Message}");
if (ex.InnerException != null)
{
Console.WriteLine($"Inner exception: {ex.InnerException.Message}");
Console.WriteLine($"Inner stack trace: {ex.InnerException.StackTrace}");
}
Console.WriteLine($"Stack trace: {ex.StackTrace}");
throw;
}
}
public static async Task TestRawPostToServer(string sseUrl)
{
using (var httpClient = new HttpClient())
{
// Set Authorization header
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "token");
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
// Prepare the initialize JSON-RPC request
var initializeRequest = new StringContent(
"{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{}}",
new MediaTypeHeaderValue("application/json"));
Console.WriteLine($"Manually sending initialize request to {sseUrl}");
var response = await httpClient.PostAsync(sseUrl, initializeRequest);
// Check the response
string responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Initialize response: {(int)response.StatusCode} {response.StatusCode}");
Console.WriteLine($"Response content: {responseContent}");
}
}
public async Task<IList<McpClientTool>> AvailableTools()
{
return await _mcpClient.ListToolsAsync();
}
public async Task<CallToolResponse> ExecuteTool(string toolName, Dictionary<string, object?> args)
{
return await _mcpClient.CallToolAsync(toolName, args);
}
}