Skip to main content

McpHttpClient

Communicates with a remote MCP server over HTTP. Use this for hosted MCP services or for an MCP server running as its own daemon on another host.

public sealed class McpHttpClient : IMcpClient
{
public McpHttpClient(string baseUrl, string? apiKey = null);
public Task ConnectAsync(CancellationToken ct = default);
public Task<IList<McpToolInfo>> GetToolsAsync(CancellationToken ct = default);
public Task<string> CallToolAsync(string toolName, string argsJson, CancellationToken ct = default);
public McpServerInfo? ServerInfo { get; }
}

The apiKey argument is sent as a Bearer token on every request — the auth scheme most hosted MCP servers expect. Pass null for servers that are unauthenticated or behind a different auth mechanism (use a custom proxy in that case).

Example — connect and use

using LogicGrid.Core.Agents;
using LogicGrid.Core.Tools;
using LogicGrid.Mcp;

using var mcp = new McpHttpClient(
baseUrl: "https://mcp.your-company.com",
apiKey: Environment.GetEnvironmentVariable("MCP_TOKEN"));

await mcp.ConnectAsync();

IList<ToolBase> tools = await McpToolAdapter.GetAllAsync(mcp);

IAgent agent = new Agent<string>(
"Assistant",
"Uses the company's MCP tools.",
"Use the available tools to answer the user.",
llm,
tools: tools);

Long-lived connections

Connect once at app startup, reuse the client across requests:

// Program.cs / Startup
builder.Services.AddSingleton<IMcpClient>(sp =>
{
var client = new McpHttpClient(
baseUrl: "https://mcp.your-company.com",
apiKey: builder.Configuration["Mcp:ApiKey"]);
client.ConnectAsync().GetAwaiter().GetResult();
return client;
});

The HTTP client uses a 30-second per-request timeout and a single HttpClient instance for the lifetime of McpHttpClient.

Common pitfalls

  • Trailing slashes. The constructor trims trailing slashes from baseUrl. Don't include the /jsonrpc path — that's appended internally.
  • Self-signed TLS. Production-only servers will have a real cert; for staging/dev with a self-signed cert, configure the runtime's trust store rather than disabling validation.
  • Per-request HttpClient. Don't new an McpHttpClient per request — it owns its own HttpClient and you'll exhaust sockets. Use the singleton pattern above.