<?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: Vedaant Singh</title>
    <description>The latest articles on DEV Community by Vedaant Singh (@vedaant00).</description>
    <link>https://dev.to/vedaant00</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4046078%2F28a1a053-0638-4ab5-aa84-8a758b78d945.jpg</url>
      <title>DEV Community: Vedaant Singh</title>
      <link>https://dev.to/vedaant00</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vedaant00"/>
    <language>en</language>
    <item>
      <title>Give Your AI Agent a Web Scraper, Not Just a Browser</title>
      <dc:creator>Vedaant Singh</dc:creator>
      <pubDate>Mon, 27 Jul 2026 13:57:46 +0000</pubDate>
      <link>https://dev.to/vedaant00/give-your-ai-agent-a-web-scraper-not-just-a-browser-1ni1</link>
      <guid>https://dev.to/vedaant00/give-your-ai-agent-a-web-scraper-not-just-a-browser-1ni1</guid>
      <description>&lt;p&gt;AI agents can already browse websites. But browsing is a terrible interface for extracting data.&lt;/p&gt;

&lt;p&gt;Browsing gives you a page. Scraping gives you data. A native web fetch drops a rendered page into the model's context and quietly makes the model do the hard part: find the price, parse the table, guess which &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; is the title. That's tokens spent, and it's fragile: reword the page and the extraction breaks.&lt;/p&gt;

&lt;p&gt;A scraper does that work for you and returns &lt;strong&gt;structured fields&lt;/strong&gt; (&lt;code&gt;{title, rating, genre, ...}&lt;/code&gt;) every time. And there's a second reason that matters even more for the open-source crowd: &lt;strong&gt;not every model can browse at all.&lt;/strong&gt; A local Llama or Qwen running behind an MCP host has no internet unless you give it a tool.&lt;/p&gt;

&lt;p&gt;So I added an &lt;strong&gt;MCP server&lt;/strong&gt; to &lt;a href="https://github.com/mldsveda/PyScrappy" rel="noopener noreferrer"&gt;PyScrappy&lt;/a&gt;, a Python web-scraping toolkit I maintain, exposing its scrapers as tools that &lt;strong&gt;any &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt; client&lt;/strong&gt; can call. This post shows how to wire it up, and why the output format is the whole point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structured data, not raw pages
&lt;/h2&gt;

&lt;p&gt;The whole argument fits in one picture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Browser tool:   agent ─▶ website ─▶ raw HTML ─▶ LLM parses it ─▶ answer
   PyScrappy MCP:  agent ─▶ scraper ─▶ structured JSON ─────────────▶ answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Everything comes back as structured JSON&lt;/strong&gt;, so the agent filters, compares, and reasons over it instead of eyeballing HTML. Here's the difference in practice. Ask a browsing agent for a stock quote and it fetches a page like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"D(ib) Mend(20px)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;fin-streamer&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"182.52"&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;182.52&lt;span class="nt"&gt;&amp;lt;/fin-streamer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;fin-streamer&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"+1.24"&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;+1.24 (0.68%)&lt;span class="nt"&gt;&amp;lt;/fin-streamer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and now the model has to &lt;em&gt;find&lt;/em&gt; the number. Ask PyScrappy and you get:&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;"symbol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AAPL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;182.52&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"change"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"change_pct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.68&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;No parsing, no guessing, no wasted context. That's the case for a scraper in one screenshot.&lt;/p&gt;

&lt;p&gt;And when you &lt;em&gt;are&lt;/em&gt; driving PyScrappy from Python (not through MCP), every result is a &lt;code&gt;ScrapeResult&lt;/code&gt; that renders three ways, including clean Markdown you can drop straight into a prompt:&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;from&lt;/span&gt; &lt;span class="n"&gt;pyscrappy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;scrape&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;scrape&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://en.wikipedia.org/wiki/Web_scraping&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_markdown&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;   &lt;span class="c1"&gt;# LLM-ready: headings, text, tables
# ...or result.to_json() / result.to_dataframe()
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install
&lt;/h2&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; &lt;span class="s2"&gt;"pyscrappy[mcp]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives you a &lt;code&gt;pyscrappy-mcp&lt;/code&gt; command, a stdio MCP server.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the MCP server needs &lt;strong&gt;Python 3.10+&lt;/strong&gt; (the MCP SDK requires it). PyScrappy's core library still runs on 3.9, but the server does not, so use 3.10 or newer here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Wire it into your agent
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MCP is an open standard&lt;/strong&gt;, so this works with &lt;em&gt;any&lt;/em&gt; MCP-compatible client, not one vendor. That includes &lt;strong&gt;Claude&lt;/strong&gt; (Desktop and Code), editors like &lt;strong&gt;Cursor&lt;/strong&gt;, &lt;strong&gt;Windsurf&lt;/strong&gt;, and &lt;strong&gt;VS Code&lt;/strong&gt;, and open-source hosts such as &lt;strong&gt;LibreChat&lt;/strong&gt;, &lt;strong&gt;Cline&lt;/strong&gt;, and &lt;strong&gt;Goose&lt;/strong&gt; that connect MCP servers to &lt;em&gt;local or open models&lt;/em&gt;. The examples below use Claude because it's the fastest way to try it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Code:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add pyscrappy pyscrappy-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Claude Desktop&lt;/strong&gt;: add to &lt;code&gt;claude_desktop_config.json&lt;/code&gt; and restart:&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;"pyscrappy"&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;"pyscrappy-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;&lt;strong&gt;Cursor / Windsurf / VS Code (Cline)&lt;/strong&gt; use the same &lt;code&gt;mcpServers&lt;/code&gt; block in their own MCP settings file (for example &lt;code&gt;.cursor/mcp.json&lt;/code&gt; in Cursor):&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;"pyscrappy"&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;"pyscrappy-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;&lt;strong&gt;Local / open models (Ollama, etc.):&lt;/strong&gt; Ollama itself doesn't speak MCP, so you run a host that connects your local model to MCP servers: &lt;a href="https://block.github.io/goose/" rel="noopener noreferrer"&gt;Goose&lt;/a&gt;, &lt;a href="https://cline.bot/" rel="noopener noreferrer"&gt;Cline&lt;/a&gt;, or &lt;a href="https://www.librechat.ai/" rel="noopener noreferrer"&gt;LibreChat&lt;/a&gt;. In Goose, you add the same command as an extension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pyscrappy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stdio&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pyscrappy-mcp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Point that host at an Ollama model that &lt;strong&gt;supports tool calling&lt;/strong&gt; (Llama 3.1, Qwen 2.5, and similar) and it can now pull live web data. This is where the server earns its keep: a model with &lt;em&gt;no web access at all&lt;/em&gt; suddenly gets live, structured data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask in plain language
&lt;/h2&gt;

&lt;p&gt;Whichever client you use, you just ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Use pyscrappy to get the latest headlines from bbc.co.uk and the current AAPL quote."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent picks &lt;code&gt;scrape_news&lt;/code&gt; and &lt;code&gt;scrape_stock&lt;/code&gt;, runs them, and reasons over the structured results, with no glue code in between.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can do with it
&lt;/h2&gt;

&lt;p&gt;The server ships &lt;strong&gt;22 tools&lt;/strong&gt; spanning the sources PyScrappy covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The open web:&lt;/strong&gt; scrape any URL into structured text, links, images, and tables (&lt;code&gt;scrape_url&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference &amp;amp; research:&lt;/strong&gt; Wikipedia, dictionary definitions, book search.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finance &amp;amp; markets:&lt;/strong&gt; stock quotes, history, and profiles; crypto prices; currency conversion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;News &amp;amp; media:&lt;/strong&gt; RSS/news feeds, movies and TV (via OMDb), YouTube, SoundCloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E-commerce:&lt;/strong&gt; product search across Amazon, Newegg (tech), and IKEA (home).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jobs &amp;amp; dev data:&lt;/strong&gt; public LinkedIn job listings, GitHub repos, Hacker News.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local &amp;amp; lifestyle:&lt;/strong&gt; restaurants by city (Zomato, Uber Eats) and weather.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The range shows in a single prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Use pyscrappy to get today's tech headlines, the current NVDA quote, and a few laptops under $800."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Two tools need a little setup: &lt;strong&gt;SoundCloud&lt;/strong&gt; uses a browser backend (&lt;code&gt;pip install "pyscrappy[browser]"&lt;/code&gt;), and the &lt;strong&gt;movie tool&lt;/strong&gt; needs a free &lt;a href="https://www.omdbapi.com/apikey.aspx" rel="noopener noreferrer"&gt;OMDb&lt;/a&gt; API key passed through the client config:&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;"pyscrappy"&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;"pyscrappy-mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&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;"OMDB_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-key"&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;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;&lt;em&gt;More tools and sources are on the way, so expect this list to grow.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works under the hood
&lt;/h2&gt;

&lt;p&gt;The server is built on the official MCP Python SDK (&lt;code&gt;FastMCP&lt;/code&gt;). Each tool is a &lt;strong&gt;thin async wrapper&lt;/strong&gt; around a scraper. PyScrappy's scrapers are synchronous, so each call runs in a worker thread via &lt;code&gt;anyio.to_thread.run_sync&lt;/code&gt; to keep the event loop free.&lt;/p&gt;

&lt;p&gt;Every tool returns a typed &lt;code&gt;ScrapeToolResult&lt;/code&gt;, a stable envelope (&lt;code&gt;data&lt;/code&gt;, &lt;code&gt;count&lt;/code&gt;, &lt;code&gt;scraper&lt;/code&gt;, &lt;code&gt;source_urls&lt;/code&gt;, &lt;code&gt;errors&lt;/code&gt;) around the source-specific items. That gives clients a &lt;strong&gt;declared output schema&lt;/strong&gt; and &lt;strong&gt;validated structured data&lt;/strong&gt; rather than an opaque string.&lt;/p&gt;

&lt;p&gt;Responses are &lt;strong&gt;cached briefly&lt;/strong&gt; (a few minutes), so when an agent asks for the same thing twice, the second call is instant and doesn't hit the site again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/mldsveda/PyScrappy" rel="noopener noreferrer"&gt;https://github.com/mldsveda/PyScrappy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pip install "pyscrappy[mcp]"&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI agents don't need another browser. They need better tools. If you're building agents, give PyScrappy a try and let me know what you'd build with it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webscraping</category>
      <category>mcp</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
