Skip to content

Web search for the OpenAI Agents SDK with an MCP server

The OpenAI Agents SDK speaks MCP, so web search is one MCPServerStdio away. Start the ContextFetch server with npx @contextfetch/mcp, pass your key in its env, and give the server to Agent(mcp_servers=[...]). The agent gets contextfetch_search plus tools to read a URL as Markdown, research and crawl. A search costs $1 per 1,000, and without a key the server still answers 25 calls a day.

Verified PythonOpenAI Agents SDKMCP/v1/search

1. Get a key (optional at first)

The MCP server runs keyless for 25 calls per IP address per day. For more, claim a free key: $2.50 of balance, 2,500 default searches, one per network. Export it as CONTEXTFETCH_API_KEY.

curl -X POST https://api.contextfetch.dev/v1/keys/free# {"apiKey": "cf_live_...", "balance_usd": 2.5, "searches": 2500}export CONTEXTFETCH_API_KEY="cf_live_..."

2. Install the SDK

openai-agents includes the MCP client. The server itself is an npm package that npx downloads on first run, so Node.js must be on the PATH.

pip install openai-agents

3. Start the server with MCPServerStdio

MCPServerStdio launches the server as a child process and talks to it over stdin and stdout. Put the key in env; leave it out to run keyless. Use it as an async context manager so the process is stopped when you are done. The first npx download can take a few seconds, so allow a longer client_session_timeout_seconds than the default.

4. Give the server to an agent

Pass the connected server in mcp_servers. The SDK lists its tools for the model on each run, and when the model calls contextfetch_search the SDK forwards the call to the server. The program below lists the tools and calls one by hand with call_tool, which needs no OpenAI key.

from agents import Agent, Runner async with MCPServerStdio(name="contextfetch", params=params) as server:    agent = Agent(        name="Researcher",        instructions="Search the web before answering and cite URLs.",        mcp_servers=[server],    )    result = await Runner.run(agent, "What is a Kubernetes PodDisruptionBudget?")    print(result.final_output)

5. Tools and what they cost

contextfetch_search returns each result's title, URL and only the passages relevant to the query, at $1 per 1,000 searches. contextfetch_extract_url reads a page as Markdown, contextfetch_research runs several searches at once, and contextfetch_crawl and contextfetch_map walk a site, each billed at its own rate. contextfetch_balance reports what is left and costs nothing. When a balance runs out, the tools return the payment link as an error result instead of crashing the run.

The complete code

Python, runnable as is with CONTEXTFETCH_API_KEY set. Install first: openai-agents. We ran it against the live API; the output below is what it printed.

import asyncioimport osimport re from agents.mcp import MCPServerStdio  async def main() -> None:    async with MCPServerStdio(        name="contextfetch",        params={            "command": "npx",            "args": ["-y", "@contextfetch/mcp"],            "env": {"CONTEXTFETCH_API_KEY": os.environ["CONTEXTFETCH_API_KEY"]},        },        client_session_timeout_seconds=60,    ) as server:        tools = await server.list_tools()        print("Tools the agent gets:", ", ".join(t.name for t in tools))         # The same call the agent makes when the model picks contextfetch_search.        result = await server.call_tool(            "contextfetch_search",            {"query": "kubernetes pod disruption budget", "num_results": 3},        )        text = result.content[0].text        print("\ncontextfetch_search returned (headings and URLs):")        for line in text.splitlines():            if re.match(r"## \d+\. |https://", line):                print(" ", line[:160])  asyncio.run(main()) 
OutputRecorded
Tools the agent gets: contextfetch_search, contextfetch_extract_url, contextfetch_find_similar, contextfetch_research, contextfetch_deep_research, contextfetch_answer, contextfetch_crawl, contextfetch_map, contextfetch_balance, contextfetch_auto_reload, contextfetch_get_free_key

contextfetch_search returned (headings and URLs):
  ## 1. Pod Disruption Budgets in Kubernetes: Complete Guide to PDBs
  https://www.groundcover.com/learn/kubernetes/pod-disruption-budget · score 1.000
  ## 2. Pod Disruption Budget in Kubernetes
  https://dev.to/oshi36/pod-disruption-budget-in-kubernetes-6kg · published 2023-07-03 · score 1.000
  ## 3. Pod Disruption Budgets: Pitfalls, Evictions & Kubernetes Upgrades
  https://www.chkk.io/blog/pod-disruption-budgets · score 1.000

The same call with curl

The raw HTTP request, and the response it returned (long text fields and lists shortened).

curl -s https://api.contextfetch.dev/v1/search \  -H "Authorization: Bearer $CONTEXTFETCH_API_KEY" \  -H "Content-Type: application/json" \  -d '{"query": "kubernetes pod disruption budget", "numResults": 3, "contents": {"text": true, "highlights": true, "pruned_context": true}}'
ResponseRecorded
{
  "requestId": "b7c20730856f4583a160910ae78e3014",
  "results": [
    {
      "id": "14908850-43c9-52ec-8a5a-23c8c302d799",
      "url": "https://www.groundcover.com/learn/kubernetes/pod-disruption-budget",
      "title": "Pod Disruption Budgets in Kubernetes: Complete Guide to PDBs",
      "score": 0.9999999999424001,
      "publishedDate": null,
      "text": "# Pod Disruption Budgets in Kubernetes: Complete Guide to PDBs\n\nKubernetes\n\n# Pod Disruption Budgets: Availability Guarantees in Kubernetes\n\n\n\n\n\ngroundcover Team\n\nFebruary 19, 2026\n\n7\n\nmin read\n\nKubernetes\n\nGuaranteeing application availability is a key goal for most Kubernetes w…",
      "highlights": [
        "## What is a Pod disruption budget in Kubernetes?\n\nIn Kubernetes, a Pod disruption budget (PDB) is a type of resource that restricts the number of Pod replicas that can be taken down during a voluntary disruption event.\n\nA voluntary disruption event means a change that a cluster …",
        "This is because (as we mentioned above) Pod disruption budgets tell Kubernetes to keep a certain number of Pod replicas running during events that could otherwise cause all replicas to shut down (and, therefore, make an application unavailable).\n\nWhat makes Pod disruption budgets…",
        "Fortunately, Kubernetes offers a feature to help safeguard against this risk. It’s called Pod disruption budgets, and it makes it possible to ensure that a fixed number of Pods will remain available in the event of planned or voluntary disruptions to your Kubernetes cluster’s sta…"
      ],
      "highlightScores": [
        0.999968386949313,
        0.9998961324181257,
        0.9998805150702426
      ],
      "prunedContext": "# Pod Disruption Budgets in Kubernetes: Complete Guide to PDBs\n\nKubernetes\n\n# Pod Disruption Budgets: Availability Guarantees in Kubernetes\n\ngroundcover Team\n\nFebruary 19, 2026\n\n7\n\nmin read\n\nKubernetes\n\nGuaranteeing application availability is a key goal for most Kubernetes workl…",
      "textSource": "page",
      "language": "en"
    },
    {
      "id": "ad3579b9-f935-514a-a043-6b68b539fccc",
      "url": "https://dev.to/oshi36/pod-disruption-budget-in-kubernetes-6kg",
      "title": "Pod Disruption Budget in Kubernetes",
      "score": 0.9999999984252316,
      "publishedDate": "2023-07-03",
      "text": "Maintaining highly available applications in a Kubernetes cluster can be hard, especially when nodes go under maintenance or fail. The application pods get terminated or may reschedule on other nodes, which can cause downtime or data loss.\n\nTo make the applications available **24…",
      "highlights": [
        "*Pod Disruption Budget (PDB) is an object created by the application owner that defines the minimum number of application replicas that should run during voluntary disruptions (node upgrade/maintenance) to make it highly available.*\n\nLet’s understand with an example, Let’s say yo…",
        "Maintaining highly available applications in a Kubernetes cluster can be hard, especially when nodes go under maintenance or fail. The application pods get terminated or may reschedule on other nodes, which can cause downtime or data loss.\n\nTo make the applications available **24…",
        "- Make sure your pod requests the resources it needs and not more.\n- Create enough replicas of your application to make it more available(HA).\n- Even in HA, use anti-affinity to have pods on all cluster nodes or zone if using multi-zone clusters.\n\nSimilarly, to deal with voluntar…"
      ],
      "highlightScores": [
        0.9999247120995152,
        0.9998966397740114,
        0.9998604487137517
      ],
      "prunedContext": "Maintaining highly available applications in a Kubernetes cluster can be hard, especially when nodes go under maintenance or fail. The application pods get terminated or may reschedule on other nodes, which can cause downtime or data loss.\n\nTo make the applications available **24…",
      "textSource": "page",
      "language": "en"
    },
    {
      "id": "692ca877-7bf8-557a-a65d-ff6f677dcbd8",
      "url": "https://www.chkk.io/blog/pod-disruption-budgets",
      "title": "Pod Disruption Budgets: Pitfalls, Evictions & Kubernetes Upgrades",
      "score": 0.9999999973447038,
      "publishedDate": null,
      "text": "Ensuring high application availability is a key concern for anyone managing workloads on Kubernetes. Imagine Kubernetes as an orchestra, where each component of your application plays a vital role. Pod Disruption Budgets (PDBs) act like stage managers, ensuring the show goes on e…",
      "highlights": [
        "A Kubernetes Pod Disruption Budget specifies a minimum level of availability for a given set of pods. Kubernetes uses PDBs to determine if pods can be evicted, preventing disruptions that would cause the number of running replicas to fall below the defined target size. If evictin…",
        "Ensuring high application availability is a key concern for anyone managing workloads on Kubernetes. Imagine Kubernetes as an orchestra, where each component of your application plays a vital role. Pod Disruption Budgets (PDBs) act like stage managers, ensuring the show goes on e…",
        "`minAvailable: 90%` to ensure no more than a 10% reduction in serving capacity.`maxUnavailable=0` to prevent termination without consultation.\nAfter creating a Kubernetes PDB, it's important to verify its status using:\n\n`kubectl get poddisruptionbudgets.`\n\nThe output provides key…"
      ],
      "highlightScores": [
        0.9998692163590086,
        0.9997734118575949,
        0.9992937976978788
      ],
      "prunedContext": "Ensuring high application availability is a key concern for anyone managing workloads on Kubernetes. Imagine Kubernetes as an orchestra, where each component of your application plays a vital role. Pod Disruption Budgets (PDBs) act like stage managers, ensuring the show goes on e…",
      "textSource": "page",
      "language": "en"
    }
  ],
  "costDollars": {
    "total": 0.001
  },
  "searchTimeMs": 3,
  "searchTime": 3,
  "contextfetch": {
    "tokens": {
      "raw": 7370,
      "pruned": 2947,
      "savedPct": 60.01356852103121
    },
    "sources": {
      "local": 3
    },
    "cache": "hit",
    "timingsMs": {
      "recall": 0,
      "fetch": 0,
      "rerank": 0,
      "total": 3
    }
  }
}

Questions

Why MCP instead of OpenAI's hosted web search tool?

MCP keeps the search provider separate from the model: the same server works with any model the Agents SDK can drive, and you see and pay for each search directly at $1 per 1,000. The tool results are plain text you can log and inspect.

Can I use the remote server instead of npx?

Yes. ContextFetch also serves MCP over streamable HTTP at https://api.contextfetch.dev/mcp, which the SDK's MCPServerStreamableHttp can connect to with an Authorization: Bearer header. [The MCP client guide](/guides/integrations/web-search-mcp-claude-code-cursor) shows raw calls to it.

What does the agent see from a search?

Markdown: a numbered heading per result, its URL, publish date when known, a relevance score and the passages that match the query. The server gets that from /v1/search; the curl call below sends the same request body and shows the JSON before it is turned into Markdown.

Do I need a key?

Not to start. Without CONTEXTFETCH_API_KEY the server allows 25 calls per IP address per day. After that, the agent can call contextfetch_get_free_key to claim a free key with $2.50 of balance.

Run it with your own key

A free key has 2,500 searches and needs no signup. Agents can claim one themselves with the POST below.

curl -X POST https://api.contextfetch.dev/v1/keys/free
Get a free key