Index is the SOTA open-source browser agent for autonomously executing complex tasks on the web.
- Powered by reasoning LLMs with vision capabilities.
- Gemini 2.5 Pro (really fast and accurate)
- Claude 3.7 Sonnet with extended thinking (reliable and accurate)
- OpenAI o4-mini (depending on the reasoning effort, provides good balance between speed, cost and accuracy)
- Gemini 2.5 Flash (really fast, cheap, and good for less complex tasks)
-
pip install lmnr-index
and use it in your project -
index run
to run the agent in the interactive CLI - Index is also available as a serverless API.
- You can also try out Index via Chat UI.
- Supports advanced browser agent observability powered by open-source platform Laminar.
prompt: go to ycombinator.com. summarize first 3 companies in the W25 batch and make new spreadsheet in google sheets.
local_agent_spreadsheet_demo.mp4
Check out full documentation here
The easiest way to use Index in production is via the serverless API. Index API manages remote browser sessions, agent infrastructure and browser observability. To get started, sign up and create project API key. Read the docs to learn more.
from lmnr import Laminar, LaminarClient # you can also set LMNR_PROJECT_API_KEY environment variable # Initialize tracing Laminar.initialize(project_api_key="your_api_key") # Initialize the client client = LaminarClient(project_api_key="your_api_key") for chunk in client.agent.run( stream=True, model_provider="gemini", model="gemini-2.5-pro-preview-03-25" prompt="Navigate to news.ycombinator.com, find a post about AI, and summarize it" ): print(chunk)
pip install lmnr-index
# Install playwright
playwright install chromium
Setup your model API keys in .env
file in your project root:
ANTHROPIC_API_KEY=
GEMINI_API_KEY=
OPENAI_API_KEY=
You can run Index via interactive CLI. It features:
- Browser state persistence between sessions
- Follow-up messages with support for “give human control” action
- Real-time streaming updates
- Beautiful terminal UI using Textual
You can run the agent with the following command. Remember to set API key for the selected model in the .env
file.
Output will look like this:
Loaded existing browser state
╭───────────────────── Interactive Mode ─────────────────────╮
│ Index Browser Agent Interactive Mode │
│ Type your message and press Enter. The agent will respond. │
│ Press Ctrl+C to exit. │
╰────────────────────────────────────────────────────────────╯
Choose an LLM model:
1. Gemini 2.5 Flash
2. Claude 3.7 Sonnet
3. OpenAI o4-mini
Select model [1/2] (1): 3
Using OpenAI model: o4-mini
Loaded existing browser state
Your message: go to lmnr.ai, summarize pricing page
Agent is working...
Step 1: Opening lmnr.ai
Step 2: Opening Pricing page
Step 3: Scrolling for more pricing details
Step 4: Scrolling back up to view pricing tiers
Step 5: Provided concise summary of the three pricing tiers
import asyncio from index import Agent, AnthropicProvider async def main(): llm = AnthropicProvider( model="claude-3-7-sonnet-20250219", enable_thinking=True, thinking_token_budget=2048) # llm = OpenAIProvider(model="o4-mini") you can also use OpenAI models agent = Agent(llm=llm) output = await agent.run( prompt="Navigate to news.ycombinator.com, find a post about AI, and summarize it" ) print(output.result) if __name__ == "__main__": asyncio.run(main())
async for chunk in agent.run_stream( prompt="Navigate to news.ycombinator.com, find a post about AI, and summarize it" ): print(chunk)
To trace Index agent’s actions and record browser session you simply need to initialize Laminar tracing before running the agent.
from lmnr import Laminar Laminar.initialize(project_api_key="your_api_key")
Then you will get full observability on the agent’s actions synced with the browser session in the Laminar platform.

)
llm = AnthropicProvider(model=”claude-3-7-sonnet-20250219″, enable_thinking=True, thinking_token_budget=2048)
agent = Agent(llm=llm, browser_config=browser_config)
output = await agent.run(
prompt=”Navigate to news.ycombinator.com and find the top story”
)
print(output.result)
if __name__ == “__main__”:
asyncio.run(main())” dir=”auto”>
import asyncio from index import Agent, AnthropicProvider, BrowserConfig async def main(): # Configure browser to connect to an existing Chrome DevTools Protocol endpoint browser_config = BrowserConfig( cdp_url="" ) llm = AnthropicProvider(model="claude-3-7-sonnet-20250219", enable_thinking=True, thinking_token_budget=2048) agent = Agent(llm=llm, browser_config=browser_config) output = await agent.run( prompt="Navigate to news.ycombinator.com and find the top story" ) p
11 Comments
purplecats
got a video demo that isn't behind a sign up wall?
noleary
> Index is the SOTA open-source browser agent for autonomously executing complex tasks on the web.
I've written a handful of pretty hacky Python scripts that just pull down all of the HTML content from a page and toss it over to OpenAI. As you can imagine, these were all extremely simple tasks, e.g., "find out if there's a login button"
What's a good example of a complex task that Index is well-suited for? What's the threshold of minimal complexity where you guys are a really good fit?
androng
Can it actually do something difficult like apply for jobs? So far I know of five or so websites that claim they can apply to jobs for you like sonara.ai and usemassive.com and Skyvern AI but when you try to actually use them all they can do is the one-page job applications and not the much more common Workday 10-page job applications with annoying "create an account" and annoying questions like "Do you have any relatives that work at Sony" and annoying "fill out all your work experience" where you have to click 50 times for one application. That's like half of all job applications. https://jobs.spectrum.com/job/-/-/4673/76746020384?utm_sourc…
shekhar101
Can you open up the options to use other model/versions, especially Gemini-2.5 pro experimental models available through aistudio? Would love to try this but gemini flash fails for even simple tasks. Example: I asked it to extract all the links from comment section of a hackernews comment section and it just scrolled all the way to the end and then nothing. Maybe pro models can do it better.
xena
How do I block it from my services? Does it obey robots.txt?
ho_lee_phuk
[dead]
jrvarela56
My first reaction was to look for MCP server so that I could connect it to Cursor. Just pointing this out in case it helps with new user onboarding. MCP server would work to hook it up to the Claude Desktop Website and most agentic-IDEs (Cursor, Cline, Roo, Windsurf, etc).
mulmboy
Nice.
Can run with `uvx –from lmnr-index –python 3.12 index run`
hackerknew
How well does it work with bank websites with non-conventional multi-click logins that sometimes include an "important message" that you have to click through just to get your balance?
badmonster
What’s the most surprising or complex real-world task you’ve seen it succeed at so far?
keyle
Impressive and potentially very interesting future work.
One thing I couldn't help but notice was the crazy amount of HTTP requests going on in the demo on the github readme page, and the video looks to be sped up.
I'm all for AI assisting but I wouldn't want to create even 1/10th of these HTTP requests, as a good netizen; unless I'm missing the point.