Using Web Search with Claude Code API Billing

If you’re running Claude Code against your own API key or through a proxy instead of Anthropic’s native backend, you’ve probably noticed that the built-in WebSearch tool just doesn’t return results because it relies on a server-side API that only exists at Anthropic. Without web search, the agent cant research, so we built a self-hosted replacement using MCP.

What we built

The brilliant DDGS is an open source metasearch server that aggregates results from DuckDuckGo, Bing, Google, Brave, and Yahoo. It has a built in MCP server which exposes five tools: search_text, search_news, search_images, search_videos, and search_books.

We deployed it to Azure App Service, and stuck Entra ID authentication in front of it. Claude Code supports MCP OAuth, but getting OAuth working between Claude Code and a remote server is harder in a corporate environment.

MCP’s built-in OAuth support assumes you can register redirect URIs and grant API scopes freely, but in a corporate tenant, you can’t. Custom API scopes need admin consent, which means filing tickets with the identity team, design reviews, the usual. We didn’t want to wait for that.

Instead we built a simple local proxy that authenticates via MSAL and grabs an ID token (audience = our app’s client ID). We send that ID token as a Bearer token to the remote server. Azure App Service’s Easy Auth validates it because we added the client ID to the allowed audiences list.

The architecture

Three components:

  1. Local proxy (proxy/server.py) – runs on your machine, handles Entra ID authentication via browser popup, forwards requests to the remote server. Claude Code talks to this over stdio.
  2. Remote backend – FastAPI + DDGS running in a Docker container on Azure App Service. Two B1 instances behind sticky sessions (SSE needs connection affinity). Easy Auth v2 validates every request.
  3. CI/CD – GitHub Actions with OIDC federation. Zero stored secrets. Push to main and it detects whether infra or app code changed, then deploys accordingly.

Setup for a new developer is one command:

claude mcp add websearch -- uv run --directory /path/to/proxy python server.py

First search triggers a browser login, and after that, tokens are cached for the session.

Was it worth it?

Yes. Having web search available changes how you use Claude Code. It can check docs, verify API behaviour, look up error messages. Without it you’re constantly copying things from a browser window.

Leave a Reply

Your email address will not be published. Required fields are marked *