Skip to content

fix(mcp): register IHttpClientFactory so EmbeddingClient can activate - #4413

Open
DrewWhittleNZ wants to merge 1 commit into
daniel3303:mainfrom
DrewWhittleNZ:fix/mcp-httpclientfactory-di
Open

fix(mcp): register IHttpClientFactory so EmbeddingClient can activate#4413
DrewWhittleNZ wants to merge 1 commit into
daniel3303:mainfrom
DrewWhittleNZ:fix/mcp-httpclientfactory-di

Conversation

@DrewWhittleNZ

Copy link
Copy Markdown

Disclosure: I'm not a C# developer and didn't write this fix by hand — I found and diagnosed the bug while evaluating Equibles for my own project, then used Claude (Anthropic's AI assistant) to trace the root cause against your source and prepare this patch. I did verify it live against a running instance with real data (see Testing below) before opening this. Happy to answer questions or make changes if anything here doesn't fit your conventions.

What

Equibles.Mcp.Server/Program.cs never registers IHttpClientFactory, so any tool whose dependency graph reaches EmbeddingClient fails to activate — regardless of ticker, filing-data availability, or the Embedding__Enabled setting.

EmbeddingClient's constructor calls httpClientFactory.CreateClient() unconditionally, before it checks _config.IsConfigured:

public EmbeddingClient(
    IHttpClientFactory httpClientFactory,
    IOptions<EmbeddingConfig> config,
    ILogger<EmbeddingClient> logger
)
{
    _config = config.Value;
    _logger = logger;
    _httpClient = httpClientFactory.CreateClient();
    // ...

Equibles.Web/Program.cs already calls builder.Services.AddHttpClient(); — this PR adds the same call to the MCP host, which was missing it.

Repro

System.InvalidOperationException: Unable to resolve service for type
'System.Net.Http.IHttpClientFactory' while attempting to activate
'Equibles.Sec.BusinessLogic.Embeddings.EmbeddingClient'.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory...
   at ModelContextProtocol.Server.RequestServiceProvider`1.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(...)
   at Microsoft.Extensions.DependencyInjection.McpServerBuilderExtensions.CreateTarget(...)

Calling ListCompanyDocuments, SearchDocuments, or SearchCompanyDocuments for any ticker fails at MCP tool construction time with this error. Reproduced against a self-hosted instance:

  • With Embedding__Enabled unset (the documented default) — fails.
  • After restarting with Embedding__Enabled=true and a working Ollama qwen3-embedding:0.6b endpoint configured — still fails identically. Rules out a feature-flag gating explanation; the dependency is unconditional.

Likely introduced by 49ad9aa (hybrid BM25+semantic retrieval + pluggable embedding provider), which appears to be where IHttpClientFactory was first plumbed into EmbeddingClient. Same general class of bug as #4019 and #4058 — a business-logic assembly's dependency changes or gets auto-wired into a host, and that host's Program.cs is missing the one extra explicit registration the dependency needs.

Testing

Verified live against a running instance with real ingested data (SEC filings + insider transactions for OGC/RKLB/NVDA/CRWD):

  • Before fix: ListCompanyDocuments, SearchDocuments, SearchCompanyDocuments all failed with the IHttpClientFactory exception above, on every ticker, every parameter combination.
  • After fix: ListCompanyDocuments for CRWD returns a correct, well-formed document list — 99 documents, correctly typed and dated (recent 8-Ks, a 10-Q filed 2026-06-04 for the period ending 2026-04-30, a DEF 14A, a 10-K, etc.). No error.

SearchDocuments/SearchCompanyDocuments no longer error post-fix either, though they currently return no matches for queries that should hit real content (e.g. "revenue" against a company with a 10-Q on file) — this looks like the search index still catching up with a recently-populated document backlog rather than anything related to this fix, since it's a distinct symptom (empty result vs. exception) from what this PR addresses. Happy to dig into that separately if it persists once ingestion settles.

EmbeddingClient's constructor resolves IHttpClientFactory
unconditionally (before it even checks whether embeddings are
enabled), but Equibles.Mcp.Server/Program.cs never calls
AddHttpClient(), unlike Equibles.Web/Program.cs which does. This
leaves ListCompanyDocuments, SearchDocuments, and
SearchCompanyDocuments unable to activate at all -- every call fails
with:

  System.InvalidOperationException: Unable to resolve service for
  type 'System.Net.Http.IHttpClientFactory' while attempting to
  activate 'Equibles.Sec.BusinessLogic.Embeddings.EmbeddingClient'.

Reproduces regardless of ticker, filing-data availability, or the
Embedding__Enabled setting (confirmed with it both unset and
explicitly enabled with a working Ollama endpoint), since
EmbeddingClient always calls httpClientFactory.CreateClient() before
checking its own config.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@CLAassistant

CLAassistant commented Aug 19, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants