README.md
README.md
simpleSearch gives a local model in LM Studio web search and page reading through your own browser. Searches and page loads come from a dedicated Zen browser profile on your own connection, so there is no API key, no account and no third-party search service.
It has two parts:
The two talk over a WebSocket on 127.0.0.1 only, and every message in both directions is signed with a secret the extension makes when it is installed. The extension can only close or focus tabs it opened itself.
about:profiles and create a profile named llm-browser. Use it only for this. The extension opens and reads any page the model asks for, with whatever sign-ins that profile has, so it should never share a profile with your email, bank or other accounts.search_self_test. Its first failing line names the problem.If you used the simpleSearch MCP server before, remove its simplesearch entry from LM Studio's mcp.json. The plugin replaces it and uses the same port and the same secret.
| Tool | What it does |
|---|---|
web_search | Searches through the browser and returns numbered results with title, URL and description. Engines are tried in order (DuckDuckGo, Startpage, Mojeek); if one is blocked or its parser fails, the next is used and the response says so. A captcha stops the search, brings the tab to the front, and asks the model to have you solve it. |
read_webpage | Opens a page, waits for it to load, extracts the main text with Mozilla's Readability, and closes the tab. With a goal, a long article comes back as its outline plus the passages most relevant to the goal; source files and raw text always come back whole; full: true returns the whole text. Long text comes 12,000 characters at a time. |
search_self_test | Checks the settings, the browser connection and every engine, and reports engine history. |
inspect_search_layout | Repair step one: loads a fresh results page for one engine, using a neutral test query, and returns a compact sample of its structure. |
propose_parser_rules | Repair step two: submits new CSS selectors for that engine. They are tested against the sample page before anything is saved. |
Every call answers within about 50 seconds. Every response starts with a status: line and ends with a next: line telling the model what to do. Page text is wrapped in markers that label it as web content, never instructions.
web_search and take an optional , the user's question in one sentence. Every response repeats the task in a line, so it stays in the newest part of the context, which is the part context-compression plugins keep word for word.Search engines change their result pages from time to time, which breaks the selectors that pick results out. When that happens the next engine is tried, and the model can repair the broken one with inspect_search_layout and propose_parser_rules. A proposal is accepted only if it extracts at least three results with titles and links from the sample page, and only selectors can change: the search addresses are fixed in code, and nothing the model proposes is run as code.
By default an accepted proposal waits for you. Send these as chat messages in a chat with the plugin on; the plugin answers them itself and the model only shows the result:
rollback restores the rules from before the last change, and reset restores the built-in rules. Turn on Apply parser repairs without asking to skip the approval.
| Setting | Default | Meaning |
|---|---|---|
| Secret | empty, required | The secret from the extension's options page. |
| Browser profile | llm-browser | The Zen profile that has the extension. |
| Browser program | found automatically | Full path of zen.exe, if Zen is not in a standard install location. |
| Port | 8790 | Must match the port on the extension's options page. |
| Search engines | duckduckgo, startpage, mojeek | Engines to use, in order. |
| Apply parser repairs without asking | off | Off holds repaired rules for /simplesearch approve. |
| Research budget (tokens) | 24000 | Tool output per request before the model is told to wrap up. |
| Page reads per request | 6 | Page reads per request before the model is told to wrap up. |
| Stop at the budget | on | Off turns the refusal into advice only. |
The plugin starts the browser with the configured profile the first time a search needs it and nothing is connected, and never starts a second copy: when the profile is already open, it waits for the extension instead.
Everything is kept in .lmstudio/simplesearch in your home folder:
rules/: active selectors per engine, proposals waiting for approval, and earlier versions.health.json: success, failure and captcha counts per engine, with timestamps.snapshots/: the latest results page fetched by inspect_search_layout, which always uses the neutral query "open source software", never your searches.launch.json: when the browser was last started.Search queries, addresses and page contents are never written to disk or logged.
mcp.json. Remove its entry; the plugin opens the port on the next search.This folder is also the source of a standalone MCP server for other setups (src/main.ts, built with npm run build). npm test runs the tests.
Page extraction in the extension uses Readability by Mozilla, under the Apache License 2.0. The extension-and-server design follows the approach of Browser Control MCP.
PolyForm Noncommercial 1.0.0: free for personal and other noncommercial use. Selling it, or using it in a paid product or service, needs permission from attitudejacket. See LICENSE.txt.
simpleSearch gives a local model in LM Studio web search and page reading through your own browser. Searches and page loads come from a dedicated Zen browser profile on your own connection, so there is no API key, no account and no third-party search service.
It has two parts:
The two talk over a WebSocket on 127.0.0.1 only, and every message in both directions is signed with a secret the extension makes when it is installed. The extension can only close or focus tabs it opened itself.
about:profiles and create a profile named llm-browser. Use it only for this. The extension opens and reads any page the model asks for, with whatever sign-ins that profile has, so it should never share a profile with your email, bank or other accounts.search_self_test. Its first failing line names the problem.If you used the simpleSearch MCP server before, remove its simplesearch entry from LM Studio's mcp.json. The plugin replaces it and uses the same port and the same secret.
| Tool | What it does |
|---|---|
web_search | Searches through the browser and returns numbered results with title, URL and description. Engines are tried in order (DuckDuckGo, Startpage, Mojeek); if one is blocked or its parser fails, the next is used and the response says so. A captcha stops the search, brings the tab to the front, and asks the model to have you solve it. |
read_webpage | Opens a page, waits for it to load, extracts the main text with Mozilla's Readability, and closes the tab. With a goal, a long article comes back as its outline plus the passages most relevant to the goal; source files and raw text always come back whole; full: true returns the whole text. Long text comes 12,000 characters at a time. |
search_self_test | Checks the settings, the browser connection and every engine, and reports engine history. |
inspect_search_layout | Repair step one: loads a fresh results page for one engine, using a neutral test query, and returns a compact sample of its structure. |
propose_parser_rules | Repair step two: submits new CSS selectors for that engine. They are tested against the sample page before anything is saved. |
Every call answers within about 50 seconds. Every response starts with a status: line and ends with a next: line telling the model what to do. Page text is wrapped in markers that label it as web content, never instructions.
web_search and take an optional , the user's question in one sentence. Every response repeats the task in a line, so it stays in the newest part of the context, which is the part context-compression plugins keep word for word.Search engines change their result pages from time to time, which breaks the selectors that pick results out. When that happens the next engine is tried, and the model can repair the broken one with inspect_search_layout and propose_parser_rules. A proposal is accepted only if it extracts at least three results with titles and links from the sample page, and only selectors can change: the search addresses are fixed in code, and nothing the model proposes is run as code.
By default an accepted proposal waits for you. Send these as chat messages in a chat with the plugin on; the plugin answers them itself and the model only shows the result:
rollback restores the rules from before the last change, and reset restores the built-in rules. Turn on Apply parser repairs without asking to skip the approval.
| Setting | Default | Meaning |
|---|---|---|
| Secret | empty, required | The secret from the extension's options page. |
| Browser profile | llm-browser | The Zen profile that has the extension. |
| Browser program | found automatically | Full path of zen.exe, if Zen is not in a standard install location. |
| Port | 8790 | Must match the port on the extension's options page. |
| Search engines | duckduckgo, startpage, mojeek | Engines to use, in order. |
| Apply parser repairs without asking | off | Off holds repaired rules for /simplesearch approve. |
| Research budget (tokens) | 24000 | Tool output per request before the model is told to wrap up. |
| Page reads per request | 6 | Page reads per request before the model is told to wrap up. |
| Stop at the budget | on | Off turns the refusal into advice only. |
The plugin starts the browser with the configured profile the first time a search needs it and nothing is connected, and never starts a second copy: when the profile is already open, it waits for the extension instead.
Everything is kept in .lmstudio/simplesearch in your home folder:
rules/: active selectors per engine, proposals waiting for approval, and earlier versions.health.json: success, failure and captcha counts per engine, with timestamps.snapshots/: the latest results page fetched by inspect_search_layout, which always uses the neutral query "open source software", never your searches.launch.json: when the browser was last started.Search queries, addresses and page contents are never written to disk or logged.
mcp.json. Remove its entry; the plugin opens the port on the next search.This folder is also the source of a standalone MCP server for other setups (src/main.ts, built with npm run build). npm test runs the tests.
Page extraction in the extension uses Readability by Mozilla, under the Apache License 2.0. The extension-and-server design follows the approach of Browser Control MCP.
PolyForm Noncommercial 1.0.0: free for personal and other noncommercial use. Selling it, or using it in a paid product or service, needs permission from attitudejacket. See LICENSE.txt.
read_webpagegoaltask:budget: line counting searches, page reads and tokens of tool output so far. Past the budget (24,000 tokens or 6 page reads by default) the model is told to answer unless one specific gap remains. Well past it, further searches and reads in that reply are refused without loading anything, because a local model can ignore advice in a tool result but not a refusal. Your next message gets a new budget.changes.log: every rule change with its reason./simplesearch status
/simplesearch approve duckduckgo
/simplesearch reject duckduckgo
/simplesearch rollback duckduckgo
/simplesearch reset duckduckgo
read_webpagegoaltask:budget: line counting searches, page reads and tokens of tool output so far. Past the budget (24,000 tokens or 6 page reads by default) the model is told to answer unless one specific gap remains. Well past it, further searches and reads in that reply are refused without loading anything, because a local model can ignore advice in a tool result but not a refusal. Your next message gets a new budget.changes.log: every rule change with its reason./simplesearch status
/simplesearch approve duckduckgo
/simplesearch reject duckduckgo
/simplesearch rollback duckduckgo
/simplesearch reset duckduckgo