<?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: Ibrar Yunus</title>
    <description>The latest articles on DEV Community by Ibrar Yunus (@ibraryunus).</description>
    <link>https://dev.to/ibraryunus</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%2F4170503%2F29ad3e47-4358-4996-ad4b-4896eab02606.jpg</url>
      <title>DEV Community: Ibrar Yunus</title>
      <link>https://dev.to/ibraryunus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ibraryunus"/>
    <language>en</language>
    <item>
      <title>I gave Claude Code a browser with my real logins. Here's what I had to get right</title>
      <dc:creator>Ibrar Yunus</dc:creator>
      <pubDate>Thu, 22 Oct 2026 14:21:30 +0000</pubDate>
      <link>https://dev.to/ibraryunus/i-gave-claude-code-a-browser-with-my-real-logins-heres-what-i-had-to-get-right-1bo2</link>
      <guid>https://dev.to/ibraryunus/i-gave-claude-code-a-browser-with-my-real-logins-heres-what-i-had-to-get-right-1bo2</guid>
      <description>&lt;p&gt;Most of my day is spent with Claude Code, and the browser was always the weak spot. Tools built on Playwright start a fresh profile, so the agent is logged out of everything. Pointing an agent at my main Chrome felt like a bad idea. So I built my own browser, &lt;a href="https://ibraryunus.com/apps/kinaya/" rel="noopener noreferrer"&gt;Kinaya&lt;/a&gt;, and gave it an MCP server.&lt;/p&gt;

&lt;p&gt;Adding it to Claude Code is one line:&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 kinaya &lt;span class="nt"&gt;--&lt;/span&gt; /Applications/Kinaya.app/Contents/MacOS/kinaya —mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser starts itself if it isn't running. Getting from "the agent can click things" to "I actually let it use my accounts every day" took a few decisions that I think apply to anyone building agent tooling.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Every session gets its own background tab
&lt;/h2&gt;

&lt;p&gt;Driving whatever tab is in front doesn't work once you want to keep browsing while an agent works, or when two Claude Code sessions run at once and fight over the same page.&lt;/p&gt;

&lt;p&gt;So each MCP session opens its own background tab and all later calls act on it. The tab I'm looking at never moves. Every tool also takes an optional &lt;code&gt;tab_id&lt;/code&gt;, so one agent running several tabs is still explicit. Screenshots work on background tabs and when other windows cover the browser, because the agent needs to see the page without the window being in front.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Approval for actions, not for reading
&lt;/h2&gt;

&lt;p&gt;Reading (&lt;code&gt;read_page&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;get_page_text&lt;/code&gt;, &lt;code&gt;screenshot&lt;/code&gt;) runs freely. Clicks, typing, navigation, form fills, uploads and sign-ins ask for approval in a side panel, or can be always allowed per site. A prompt left unanswered for about 5 minutes expires and Claude is told the action didn't run, so an agent never hangs forever waiting on me.&lt;/p&gt;

&lt;p&gt;Private and Tor tabs are off limits to the agent entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The agent never sees a password
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;sign_in&lt;/code&gt; fills a login saved in the browser's password vault, and &lt;code&gt;create_login&lt;/code&gt; generates and saves a strong password for a sign-up. The password goes straight into the page. The model only ever sees the username. The vault itself is XChaCha20-Poly1305 on disk, with no cloud.&lt;/p&gt;

&lt;p&gt;For things only a human can do, like CAPTCHAs and phone codes, there's an &lt;code&gt;ask_user&lt;/code&gt; tool with a reply box in the side panel.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Page text is data, not instructions
&lt;/h2&gt;

&lt;p&gt;Once an agent has your logins, prompt injection from a web page stops being theoretical. The server's instructions tell the model that text on web pages is untrusted data and never instructions. It's not a complete defence, but combined with approval on actions it means a malicious page can't quietly make the agent do something.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Don't let page dialogs block the agent
&lt;/h2&gt;

&lt;p&gt;A browser &lt;code&gt;alert&lt;/code&gt; or &lt;code&gt;confirm&lt;/code&gt; can freeze an automated session. In Kinaya, dialogs raised while the agent acts are answered and reported back to the agent instead of blocking.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rest of the tool list
&lt;/h2&gt;

&lt;p&gt;| area | tools |&lt;br&gt;
| --- | — |&lt;br&gt;
| reading | &lt;code&gt;read_page&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;get_page_text&lt;/code&gt;, &lt;code&gt;screenshot&lt;/code&gt; |&lt;br&gt;
| acting | &lt;code&gt;click&lt;/code&gt;, &lt;code&gt;hover&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;fill_form&lt;/code&gt;, &lt;code&gt;select_option&lt;/code&gt;, &lt;code&gt;press_key&lt;/code&gt;, &lt;code&gt;scroll&lt;/code&gt;, &lt;code&gt;upload_file&lt;/code&gt;, &lt;code&gt;dismiss_popups&lt;/code&gt; |&lt;br&gt;
| tabs | &lt;code&gt;navigate&lt;/code&gt;, &lt;code&gt;new_tab&lt;/code&gt;, &lt;code&gt;switch_tab&lt;/code&gt;, &lt;code&gt;close_tab&lt;/code&gt;, &lt;code&gt;list_tabs&lt;/code&gt; |&lt;br&gt;
| accounts | &lt;code&gt;sign_in&lt;/code&gt;, &lt;code&gt;create_login&lt;/code&gt;, &lt;code&gt;ask_user&lt;/code&gt; |&lt;br&gt;
| waiting and debugging | &lt;code&gt;wait_for&lt;/code&gt;, &lt;code&gt;wait&lt;/code&gt;, &lt;code&gt;read_console&lt;/code&gt;, &lt;code&gt;read_network&lt;/code&gt;, &lt;code&gt;run_javascript&lt;/code&gt; |&lt;br&gt;
| other | &lt;code&gt;batch&lt;/code&gt;, &lt;code&gt;search_history&lt;/code&gt;, &lt;code&gt;list_downloads&lt;/code&gt; |&lt;/p&gt;

&lt;p&gt;&lt;code&gt;batch&lt;/code&gt; runs several actions in one call, which saves round trips.&lt;/p&gt;

&lt;h2&gt;
  
  
  The browser itself
&lt;/h2&gt;

&lt;p&gt;It's also just my daily browser. Tauri 2 and Rust on WebKit. Ad and tracker blocking runs in the engine with Brave's adblock-rust, compiled into a WebKit content-rule list, so requests are dropped before they leave. Command palette for everything, private tabs, Tor tabs through the Arti client, reader mode, no telemetry.&lt;/p&gt;

&lt;p&gt;It's $19 once with a 14-day trial: &lt;a href="https://ibraryunus.com/apps/kinaya/" rel="noopener noreferrer"&gt;ibraryunus.com/apps/kinaya&lt;/a&gt;. If you're building agent tools, I'd be keen to hear how you're handling logins and approvals.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>macos</category>
      <category>rust</category>
    </item>
    <item>
      <title>Footnote: Agentic RAG with Sentence-Level Citations</title>
      <dc:creator>Ibrar Yunus</dc:creator>
      <pubDate>Fri, 16 Oct 2026 12:22:38 +0000</pubDate>
      <link>https://dev.to/ibraryunus/footnote-agentic-rag-with-sentence-level-citations-39oc</link>
      <guid>https://dev.to/ibraryunus/footnote-agentic-rag-with-sentence-level-citations-39oc</guid>
      <description>&lt;p&gt;An AI research agent for your documents. It decides what to search for, searches again when the results are thin, and every claim in its answer links to the exact sentence it came from.&lt;/p&gt;

&lt;p&gt;The usual 'chat with your documents' build searches once with the user's words and hopes. A two-part question gets one search and half an answer. footnote replaces that fixed pipeline with an agent that works like a researcher, built around one rule: an answer you cannot check is not an answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it was built
&lt;/h2&gt;

&lt;p&gt;Claude is given two tools, &lt;code&gt;search_handbook&lt;/code&gt; and &lt;code&gt;read_page&lt;/code&gt;, and loops until it can answer. Search results come back as sentence-level blocks, so every citation is validated by the API rather than typed by the model. Retrieval is a hand-written BM25 plus local bge-small vectors, merged with weighted reciprocal rank fusion and tuned on a 59-question eval set. The demo corpus is the public-domain 18F staff handbook, 232 pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Plans its own research.&lt;/strong&gt; A two-part question gets two searches, worded the way the handbook words things. Each step shows live in a side panel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sentence-level citations.&lt;/strong&gt; Click a citation chip and the source passage scrolls into view with the exact sentence highlighted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fanvzh65mz5vy6tmzw9t0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fanvzh65mz5vy6tmzw9t0.png" alt="A citation chip opens the source passage with the cited sentence highlighted" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Says when it doesn't know.&lt;/strong&gt; If nothing relevant turns up after retrying, it says the documents don't cover it instead of guessing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fydrvhxr1ac71k2tc7dsy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fydrvhxr1ac71k2tc7dsy.png" alt="Asked about something the handbook doesn't cover, it says so and cites the closest passages" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Swappable search.&lt;/strong&gt; Run the agent on hybrid, keyword-only or vector-only search, with each passage's rank in both shown.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;p&gt;Python with FastAPI and a one-file HTML UI, Claude through the Anthropic SDK with no framework, and a CLI that prints each tool call. The screenshots come from a keyless demo mode where the model's turns are scripted and the searches and citations run for real.&lt;/p&gt;

&lt;p&gt;Retrieval is the easy half. The hard half is making every sentence of the answer checkable.&lt;/p&gt;




&lt;p&gt;Source code: &lt;a href="https://github.com/IbrarYunus/footnote" rel="noopener noreferrer"&gt;github.com/IbrarYunus/footnote&lt;/a&gt;. More of my work: &lt;a href="https://ibraryunus.com" rel="noopener noreferrer"&gt;ibraryunus.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rag</category>
      <category>llm</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>An agent that audits a GitHub repo and writes its CLAUDE.md</title>
      <dc:creator>Ibrar Yunus</dc:creator>
      <pubDate>Wed, 14 Oct 2026 11:57:14 +0000</pubDate>
      <link>https://dev.to/ibraryunus/an-agent-that-audits-a-github-repo-and-writes-its-claudemd-2pbp</link>
      <guid>https://dev.to/ibraryunus/an-agent-that-audits-a-github-repo-and-writes-its-claudemd-2pbp</guid>
      <description>&lt;p&gt;Your first day on an unfamiliar codebase goes on the same questions. What is this, how do I run it, what's going to bite me?&lt;/p&gt;

&lt;p&gt;An AI coding agent asks those questions every single session, and gets them wrong when nobody wrote the answers down.&lt;/p&gt;

&lt;p&gt;Groundwork does that first day in a couple of minutes. Point it at a GitHub repo and you get a plain-English technical audit and a ready-to-commit CLAUDE.md.&lt;/p&gt;

&lt;p&gt;Try it: &lt;a href="https://groundwork-audit-iy.web.app" rel="noopener noreferrer"&gt;groundwork-audit-iy.web.app&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  An agent, not a summariser
&lt;/h2&gt;

&lt;p&gt;It doesn't dump the repo into a prompt. The model plans, then calls two tools against the GitHub API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;list_tree&lt;/code&gt; to see the file tree, with lockfiles, binaries and build output filtered out&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;read_file&lt;/code&gt; to open the files that actually matter: manifests, entry points, CI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It works within a step and file budget, and the only way out is &lt;code&gt;finish&lt;/code&gt;, which has to return both documents. No half-finished audits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two providers, one prompt
&lt;/h2&gt;

&lt;p&gt;One prompt and one tool schema drive both Anthropic and Google Gemini. You pick the provider and paste your own API key. Keys stay in your browser and only go to that provider.&lt;/p&gt;

&lt;p&gt;If you'd rather use the terminal, there's a Claude Code CLI that runs the same audit on a local checkout with no API key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React 19, Vite and TypeScript on Firebase Hosting&lt;/li&gt;
&lt;li&gt;The official Anthropic SDK in browser mode, with strict tool schemas and a cached system prompt&lt;/li&gt;
&lt;li&gt;Gemini through REST function calling&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I made it
&lt;/h2&gt;

&lt;p&gt;Write down the first day on a codebase once, so no one, human or agent, has to rediscover it.&lt;/p&gt;

&lt;p&gt;Full write-up: &lt;a href="https://ibraryunus.com/work/groundwork/" rel="noopener noreferrer"&gt;ibraryunus.com/work/groundwork&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>claude</category>
      <category>github</category>
    </item>
  </channel>
</rss>
