spagents
Give your AI agents eyes for the modern web.
Installation · Quick Start · MCP Server · Python SDK · How It Works
AI agents are blind to Single Page Applications. Tools like fetch and requests return empty HTML shells — no articles, no content, no interactive elements. SPAs render everything via JavaScript after the page loads.
spagents fixes this. It launches a real browser, intelligently waits for SPAs to finish rendering, and returns structured, agent-friendly data — articles, actions, inputs, navigation — ready for your agent to use.
How Claude handles dynamic content before spagents
How Claude handles dynamic content after spagents
Key features
- Smart content detection — Knows when a SPA is done rendering (not just
sleep(5)) - Structured extraction — Returns articles, links, metadata as typed Pydantic models
- Full interaction — Click, type, scroll, press keys, navigate — like a real user
- Action discovery — Finds every interactive element: buttons, inputs, ARIA roles, custom components
- Session persistence — Cookies, localStorage, and auth state preserved across navigations
- Three interfaces — Python SDK, CLI, and MCP server for Claude Desktop / AI agents
Installation
pip install spagents
playwright install chromium
From source
git clone https://github.com/your-username/spagents.git
cd spagents
uv sync
uv run playwright install chromium
Quick start
CLI
# Structured JSON output (default)
spagents browse "https://news.kagi.com"
# Human-readable text
spagents browse "https://news.kagi.com" --format text
# Interactive REPL session
spagents interactive "https://news.kagi.com"
Python SDK
import asyncio
from spagents import BrowserManager
async def main():
async with BrowserManager() as browser:
session = await browser.new_session()
# Browse a SPA — content is fully rendered
state = await session.navigate("https://news.kagi.com")
for article in state.content.articles:
print(f"{article.category}: {article.headline}")
# Interact with the page
for action in state.actions:
if "Technology" in action.description:
state = await session.click(action.selector)
break
# Type into inputs, press keys
state = await session.type_text("#search", "climate change")
state = await session.press_key("Enter")
await session.close()
asyncio.run(main())
MCP Server
Connect spagents to Claude Desktop or any MCP-compatible AI agent:
spagents mcp
Add to your Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"spagents": {
"command": "spagents",
"args": ["mcp"]
}
}
}
Claude Code
Add the MCP server to your project or user settings:
claude mcp add spagents -- spagents mcp
Or add it directly to your .claude/settings.json:
{
"mcpServers": {
"spagents": {
"command": "spagents",
"args": ["mcp"]
}
}
}
Now Claude can browse any SPA:
You: "What's the top story on Kagi News today?"
Claude: uses
browsetool → reads structured articles → gives you the answer
MCP tools
| Tool | Description |
|---|---|
browse |
Navigate to a URL, return rendered content + interactive actions |
click |
Click an element by CSS selector |
type_text |
Type into an input field |
press_key |
Press a keyboard key (Enter, Tab, Escape, etc.) |
list_actions |
Discover all interactive elements on the page |
navigate |
Go to a new URL within an existing session |
scroll |
Scroll up or down, trigger infinite scroll |
extract_content |
Re-extract content from the current page |
close_session |
Close a browser session and free resources |
Interactive REPL commands
click <n> Click action by number
click <selector> Click by CSS selector
type <n> <text> Type text into an input by action number
type "<selector>" <text> Type text into an input by CSS selector
press <key> Press a key (Enter, Escape, Tab, ArrowDown, etc.)
select <n> <value> Select dropdown option by action number
scroll [down|up] Scroll the page
actions List all interactive elements
extract Re-extract page content
navigate <url> Navigate to a new URL
json Dump current state as JSON
quit Exit the session
How it works
spagents wraps Playwright and adds three intelligent layers:
1. Content ready detection
A multi-signal detector that knows when a SPA has actually finished rendering:
| Signal | What it checks |
|---|---|
| Network quiescence | No pending XHR/fetch requests for 500ms (ignoring analytics noise) |
| DOM stabilization | MutationObserver sees no changes for 300ms after initial render |
| Content heuristic | Meaningful text exists, no loading spinners, real links present |
This replaces naive approaches like sleep(5) or Playwright's networkidle (which breaks on long-polling and WebSocket connections).
2. Content extraction
Extracts structured data from the rendered DOM:
- Articles with headlines, summaries, sources, highlights, quotes, and sections
- Links with surrounding context (which heading or section they're under)
- Metadata from OG tags, meta descriptions, and page title
3. Action discovery
Finds every interactive element on the page through four phases:
- Semantic HTML —
<a>,<button>,<input>,<select> - ARIA roles —
role="button",role="tab",role="listitem", etc. - Custom components —
tabindex,onclick,cursor: pointer - Disambiguation — Duplicate labels get context from parent containers
CLI reference
spagents browse <url> [OPTIONS]
--format, -f Output format: json (default) or text
--timeout, -t Content detection timeout in ms (default: 15000)
--no-headless Run browser with visible window
spagents interactive <url> [OPTIONS]
--timeout, -t Content detection timeout in ms (default: 15000)
--no-headless Run browser with visible window
spagents mcp [OPTIONS]
--transport Transport: stdio (default) or sse
--port, -p Port for SSE transport (default: 8000)
License
MIT with an amended community contribution requirement for organizations with more than 100 employees. See LICENSE.md for details.
Metadata
Release files for spagents 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| spagents-0.1.4.tar.gz | 664.2 kB | With provenance | Details for spagents-0.1.4.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| spagents-0.1.4-py3-none-any.whl | Python 3 | none | any | Details for spagents-0.1.4-py3-none-any.whl |
Total release size: 695.4 kB
Release files / spagents-0.1.4.tar.gz
| Download URL | spagents-0.1.4.tar.gz |
|---|---|
| Size | 664.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e56d4cf6f2b171d993402ef3d884598931d6200914164676dca9e6faffd3126d
|
|
BLAKE2b-256 checksum How to use checksums |
ef4870b143226810ba74c22053c4c3e518a4e9008e7e093860d722f92f2819b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 26, 2026.
Transparency logRelease files / spagents-0.1.4-py3-none-any.whl
| Download URL | spagents-0.1.4-py3-none-any.whl |
|---|---|
| Size | 31.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9790141808be32e7cd9b0fa1c3405ac8f97d0826456896cac77718d50f516bf5
|
|
BLAKE2b-256 checksum How to use checksums |
c15f04f74ef22c39a4421156c2759c99a87d13961bffc128b844d6f3bf7f5dfc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 26, 2026.
Transparency logSecurity for spagents 0.1.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for spagents-0.1.4.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 26, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.