<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aloya</title>
    <description>The latest articles on DEV Community by Aloya (@aloya).</description>
    <link>https://dev.to/aloya</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3976288%2F432b9fa7-d5a2-42b1-9ba4-5915752e81fd.png</url>
      <title>DEV Community: Aloya</title>
      <link>https://dev.to/aloya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aloya"/>
    <language>en</language>
    <item>
      <title>"A no-key web search API for AI agents, and the MCP server that wraps it"</title>
      <dc:creator>Aloya</dc:creator>
      <pubDate>Tue, 09 Jun 2026 16:19:39 +0000</pubDate>
      <link>https://dev.to/aloya/a-no-key-web-search-api-for-ai-agents-and-the-mcp-server-that-wraps-it-54f8</link>
      <guid>https://dev.to/aloya/a-no-key-web-search-api-for-ai-agents-and-the-mcp-server-that-wraps-it-54f8</guid>
      <description>&lt;p&gt;I have been building tooling for AI agents in Python for about a year. The thing I keep needing, over and over, is "give the agent a search bar." Every time, the search bar costs me an account, an API key, a billing relationship, and a way to keep that key out of the repo. The first three are friction; the fourth is risk.&lt;/p&gt;

&lt;p&gt;A few weeks ago I came across a public endpoint that does not have any of those: &lt;code&gt;GET https://scouts-ai.com/api/search&lt;/code&gt;. No header for auth, no signup, no rate-limit-agreement landing page. I tried it from a shell, it returned a clean JSON response with title, url, content, engine, tookMs and a per-result &lt;code&gt;publishedAt&lt;/code&gt; field. I have been using it as a research scratchpad ever since. This post is the field guide I wish I had on day one: what the response actually looks like, what the rate limits are (they are real, and they are not in the README), what the &lt;code&gt;lang&lt;/code&gt; parameter actually does (it does not do what you think), and a 100-line MCP server you can install in 30 seconds that exposes the same thing as a single &lt;code&gt;web_search&lt;/code&gt; tool to Claude Desktop, Cursor, Cline, Open WebUI, or any other MCP host.&lt;/p&gt;

&lt;h2&gt;
  
  
  The endpoint
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET https://scouts-ai.com/api/search
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three query parameters do anything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;q&lt;/code&gt; — the query, 1 to 512 characters&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lang&lt;/code&gt; — BCP-47 code, default &lt;code&gt;en&lt;/code&gt;. Hint, not a filter (see Gotcha #1)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;limit&lt;/code&gt; — default 10, max 50&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No &lt;code&gt;Authorization&lt;/code&gt; header. No &lt;code&gt;X-API-Key&lt;/code&gt;. The endpoint resolves the client from the IP.&lt;/p&gt;

&lt;p&gt;A real response from a few minutes ago, against the wire:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="s2"&gt;"https://scouts-ai.com/api/search?q=python+asyncio+tutorial&amp;amp;limit=3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"query"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python asyncio tutorial"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lang"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"page"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pageSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cached"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tookMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;970&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"results"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Python's asyncio: A Hands-On Walkthrough – Real Python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://realpython.com/async-io-python/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jul 30, 2025 · Python's asyncio library enables you to write concurrent code using the async and await keywords…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"publishedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"engine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bing"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"asyncio — Asynchronous I/O — Python 3.14.5 documentation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://docs.python.org/3/library/asyncio.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"asyncio is a library to write concurrent code using the async/await syntax…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"publishedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"engine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bing"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"asyncio in Python - GeeksforGeeks"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.geeksforgeeks.org/python/asyncio-in-python/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jul 23, 2025 · Asyncio is used as a foundation for multiple Python asynchronous frameworks…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"publishedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"engine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bing"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shape is small and stable. The wrapper object (&lt;code&gt;query&lt;/code&gt;, &lt;code&gt;lang&lt;/code&gt;, &lt;code&gt;page&lt;/code&gt;, &lt;code&gt;pageSize&lt;/code&gt;, &lt;code&gt;cached&lt;/code&gt;, &lt;code&gt;tookMs&lt;/code&gt;, &lt;code&gt;results&lt;/code&gt;) is on every response. Each result carries &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;content&lt;/code&gt;, &lt;code&gt;publishedAt&lt;/code&gt;, &lt;code&gt;engine&lt;/code&gt;. That's the contract. If you build against it, you do not need to scrape anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate limits, observed
&lt;/h2&gt;

&lt;p&gt;I hammered the endpoint a few times. Here is what the response headers actually say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;x-ratelimit-limit: 60
x-ratelimit-remaining: 58
cache-control: max-age=3600, private
x-cache: MISS
x-cache-ttl: 3600
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;60 requests per minute, per IP.&lt;/strong&gt; That is enough for one agent, a small team, or a notebook. It is not enough for a horizontally-scaled scraper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The endpoint caches for an hour.&lt;/strong&gt; &lt;code&gt;cache-control: max-age=3600, private&lt;/code&gt;. Repeat the same query inside the window and you get &lt;code&gt;cached: true&lt;/code&gt; and a &lt;code&gt;tookMs&lt;/code&gt; closer to 200 than to 1000. This is great for an agent that repeats questions; it is a footgun for an evaluation harness that wants to measure cold-path latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cache is &lt;code&gt;private&lt;/code&gt;.&lt;/strong&gt; No shared CDN copy. Two different IPs each get a fresh miss. This is the right design for a per-user agent and the wrong design for a fleet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you outgrow any of these — sustained &amp;gt; 60/min, need a status page, need a contractual SLA — the honest answer is to pay for Brave, Tavily, or Exa. They are all good. The point of this endpoint is the case where "do I really need a vendor here?" can be answered no with a single curl.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Python package
&lt;/h2&gt;

&lt;p&gt;There is a thin wrapper on PyPI, &lt;code&gt;scouts-ai-mcp&lt;/code&gt;, version 0.1.4 at the time of writing. It is MIT-licensed, depends on &lt;code&gt;fastmcp&lt;/code&gt; v2 and &lt;code&gt;httpx&lt;/code&gt;, and requires Python 3.10 or newer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;scouts-ai-mcp
scouts-ai-mcp                 &lt;span class="c"&gt;# stdio, default&lt;/span&gt;
scouts-ai-mcp &lt;span class="nt"&gt;--transport&lt;/span&gt; http &lt;span class="nt"&gt;--host&lt;/span&gt; 127.0.0.1 &lt;span class="nt"&gt;--port&lt;/span&gt; 8765
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package exposes a single MCP tool, &lt;code&gt;web_search&lt;/code&gt;, with the signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;web_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dict shape is exactly the &lt;code&gt;results&lt;/code&gt; array from the raw HTTP response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wire it into Claude Desktop
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;claude_desktop_config.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scouts-ai"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scouts-ai-mcp"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Claude Desktop. The &lt;code&gt;web_search&lt;/code&gt; tool appears in the tool picker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wire it into Cursor
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Settings → MCP → Add new global MCP server&lt;/code&gt;. Same shape.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wire it into any MCP host
&lt;/h3&gt;

&lt;p&gt;The server speaks stdio (default) or HTTP (&lt;code&gt;--transport http&lt;/code&gt;). Both transports are vanilla MCP. Anything that conforms to the spec works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling the endpoint directly
&lt;/h2&gt;

&lt;p&gt;You do not need the MCP server. If you are building an agent loop in Python and you want to fetch results inline, &lt;code&gt;httpx&lt;/code&gt; is enough:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;httpx&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;web_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;httpx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://scouts-ai.com/api/search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want the wrapper object too (so you can read &lt;code&gt;tookMs&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;httpx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://scouts-ai.com/api/search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;results&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; hits in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tookMs&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;ms (cached=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cached&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are doing this from a shell, &lt;code&gt;curl&lt;/code&gt; is fine. If you are doing it from a TypeScript agent, &lt;code&gt;fetch&lt;/code&gt; is fine. If you are doing it from a Go binary, &lt;code&gt;net/http&lt;/code&gt; is fine. There is nothing to install to use the endpoint; the package is only useful if you specifically need an MCP host.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas I hit (in order of how annoyed I was)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. &lt;code&gt;lang&lt;/code&gt; is a hint, not a filter.&lt;/strong&gt; I tested &lt;code&gt;lang=ru&lt;/code&gt; against a Russian query. The results came back in English, with what looked like Russian tokenization applied to the query. If you need language-specific results, translate the query client-side and use &lt;code&gt;lang=en&lt;/code&gt;, or post-filter on the &lt;code&gt;url&lt;/code&gt; or &lt;code&gt;title&lt;/code&gt; field. The README is honest about this; the parameter name is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The cache is your friend, then your enemy.&lt;/strong&gt; Re-running the same query in a 60-minute window returns &lt;code&gt;cached: true&lt;/code&gt; with a &lt;code&gt;tookMs&lt;/code&gt; 5x faster. For an agent, this is exactly what you want. For a benchmark, it means you are measuring the warm path, not the cold one. Either bust the cache (different IP, different parameter order) or accept it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The freshest results are not always the freshest.&lt;/strong&gt; The index is periodic. Queries with strong time intent ("today's news", "this week") can return results that are days or weeks old. The &lt;code&gt;engine&lt;/code&gt; field is included in the response precisely so you can decide what to do with that fact. The ranking is the upstream's, not the API's.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. &lt;code&gt;POST&lt;/code&gt; returns 405.&lt;/strong&gt; The endpoint is &lt;code&gt;GET&lt;/code&gt; only. If your code path defaults to &lt;code&gt;POST&lt;/code&gt; (some proxies, some older HTTP clients), you will get a method-not-allowed error and a one-second wait. Always use &lt;code&gt;GET&lt;/code&gt; with query parameters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. No SLA, no status page, no support tier.&lt;/strong&gt; This is a free public endpoint. Treat it accordingly. If you are putting it in front of paying users, build a fallback (a cached local index, a paid search provider) so a 503 on the upstream does not take down your agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. The MCP server's tool surface is intentionally small.&lt;/strong&gt; The tool is &lt;code&gt;web_search(query, lang, limit)&lt;/code&gt;. There is no &lt;code&gt;recency_days&lt;/code&gt;, no &lt;code&gt;site:&lt;/code&gt;, no boolean operators, no &lt;code&gt;filetype:&lt;/code&gt;. That is the design. If you need a richer query language, you are looking for a different product.&lt;/p&gt;

&lt;h2&gt;
  
  
  When I would use it, and when I would not
&lt;/h2&gt;

&lt;p&gt;Use it when you are building a personal agent, an internal demo, a hackathon project, or a low-traffic production service that needs a working search bar without the procurement. Use it when you do not want to manage API keys, billing, or rate-limit agreements. Use it when you can live with 60 req/min, a 1-hour cache, and ~1s cold-path latency.&lt;/p&gt;

&lt;p&gt;Do not use it when you need an SLA, when you are running a horizontally scaled fleet, when you need time-bounded or boolean search, when you need a custom user-agent, or when you have a data-residency requirement (the upstream is Bing; check their terms).&lt;/p&gt;

&lt;p&gt;For everything in the first list, it is the simplest thing that works. For everything in the second list, pay for something else. Both are fine; the gap between them is just bigger than the marketing pages suggest.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would build on top of it
&lt;/h2&gt;

&lt;p&gt;A few directions, in increasing order of ambition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A drop-in &lt;code&gt;WebSearch&lt;/code&gt; provider for LangChain and LlamaIndex. Both have an abstract interface; a 30-line implementation against this endpoint would let an existing RAG pipeline swap providers in a config file.&lt;/li&gt;
&lt;li&gt;A citation post-processor. The &lt;code&gt;engine&lt;/code&gt; field is there. A small helper that takes a list of search results plus an LLM answer, and re-renders the answer with inline numbered citations and a "Sources" footer, would be a useful standalone utility.&lt;/li&gt;
&lt;li&gt;An offline corpus mode. Hit the endpoint once with a query, persist the JSON to disk under a hash of the query string, serve subsequent requests from disk. Free, deterministic, perfect for tests and CI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The MIT license on the package means you can build any of these and ship them under whatever license you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Endpoint: &lt;code&gt;https://scouts-ai.com/api/search&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;MCP package on PyPI: &lt;code&gt;https://pypi.org/project/scouts-ai-mcp/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Package source: &lt;code&gt;https://github.com/kecven/scouts-ai-mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Project home: &lt;code&gt;https://scouts-ai.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;llms.txt&lt;/code&gt;: &lt;code&gt;https://scouts-ai.com/llms.txt&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>probe</title>
      <dc:creator>Aloya</dc:creator>
      <pubDate>Tue, 09 Jun 2026 15:58:42 +0000</pubDate>
      <link>https://dev.to/aloya/probe-5cj8</link>
      <guid>https://dev.to/aloya/probe-5cj8</guid>
      <description>&lt;p&gt;probe&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
