juso-search
An MCP server (stdio) that exposes the Juso search extension's agent-bridge
search capabilities to MCP clients (Claude Desktop, Cursor, Cline, Claude
Code, …). It mirrors the CLI agent-skill juso_search subcommands over MCP
JSON-RPC 2.0, with a short-lived browser launch per call (Chromium-family or
Firefox) that the extension claims and completes through its Agent Bridge.
- Transport: stdio. JSON-RPC flows over stdin/stdout; diagnostics go to stderr (stdout stays clean — only newline-delimited JSON-RPC).
- Config: environment variables via the client's MCP
envblock. No CLI flags besides--help/--version(prints the package version). - Dual era: accepts both the legacy
initializehandshake and the modernserver/discover(2026-07-28 protocol). Tested at the wire level. - Vendored bridge:
juso_search/juso_bridge.pyis byte-identical topublic/agent-skill/scripts/juso_bridge.py(the plan's drift lock). Never edit it by hand — regenerate from the source.
Install
Published on PyPI. Requires Python
3.10+ and mcp>=2.0,<3 (installed automatically as a dependency).
pip install juso-search
From this repository (development):
python -m venv mcp-server/.venv
mcp-server/.venv/Scripts/pip install -e mcp-server/
Verify:
mcp-server/.venv/Scripts/juso-search --help
Environment variables
| Variable | Required | Meaning |
|---|---|---|
JUSO_EXTENSION_ID |
no* | The extension id (Chrome [a-p]{32} or Firefox email-style/{GUID}) — see chrome://extensions / about:addons. |
JUSO_BROWSER_PATH |
yes | Explicit browser executable (Chrome, Chromium, Edge, Firefox, …). The server refuses to guess — set it explicitly. (JUSO_CHROME_PATH is a legacy alias.) |
JUSO_BRIDGE_URL |
no* | Full bridge URL base, e.g. moz-extension://<uuid>/bridge.html — required for Firefox (the moz-extension:// host is a per-install random UUID, not derivable from the id). |
JUSO_BROWSER_PROFILE |
no | Browser profile (Chrome directory name / Firefox profile name; auto-selected if unset). (JUSO_CHROME_PROFILE is a legacy alias.) |
JUSO_TIMEOUT |
no | End-to-end per-call budget in seconds, browser launch included (default 40). When set, it is also carried to the extension as the action budget (timeout − ~6s reply reserve, clamped to 7–300 s — needs a current extension version). |
* Either JUSO_EXTENSION_ID or JUSO_BRIDGE_URL must be set. Chrome can
derive the bridge URL from the id, so only the id is needed; Firefox needs the
full bridge URL and the id is optional. JUSO_BROWSER_PATH is always required —
the server refuses to start without it (exit code 2 and a stderr message)
rather than guessing. (Browser auto-discovery is a CLI-skill convenience only;
the MCP server always needs an explicit executable because a wrong guess is a
silent failure that is hard to diagnose over stdio.)
Client configuration
Each client injects these variables differently. Pick your client:
Claude Desktop (claude_desktop_config.json)
Claude Desktop does not expand ${VAR}, so write literal values:
JUSO_BROWSER_PATHby OS — Windows:C:\Program Files\Google\Chrome\Application\chrome.exe(orC:\Program Files\Mozilla Firefox\firefox.exe) · macOS:/Applications/Google Chrome.app/Contents/MacOS/Google Chrome(or/Applications/Firefox.app/Contents/MacOS/firefox) · Linux:/usr/bin/google-chrome(or/usr/bin/firefox).
{
"mcpServers": {
"juso": {
"command": "juso-search",
"args": [],
"env": {
"JUSO_EXTENSION_ID": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"JUSO_BROWSER_PATH": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"JUSO_TIMEOUT": "40"
}
}
}
}
Cursor (.cursor/mcp.json)
{
"mcpServers": {
"juso": {
"command": "juso-search",
"args": [],
"env": {
"JUSO_EXTENSION_ID": "${env:JUSO_EXTENSION_ID}",
"JUSO_BROWSER_PATH": "${env:JUSO_BROWSER_PATH}",
"JUSO_BROWSER_PROFILE": "${env:JUSO_BROWSER_PROFILE}",
"JUSO_TIMEOUT": "${env:JUSO_TIMEOUT}"
}
}
}
}
Cline (cline_mcp_settings.json)
JUSO_BROWSER_PATHby OS — macOS:/Applications/Google Chrome.app/Contents/MacOS/Google Chrome(or/Applications/Firefox.app/Contents/MacOS/firefox) · Linux:/usr/bin/google-chrome(or/usr/bin/firefox). The example below uses the Windows path.
{
"mcpServers": {
"juso": {
"command": "juso-search",
"args": [],
"env": {
"JUSO_EXTENSION_ID": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"JUSO_BROWSER_PATH": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"JUSO_BROWSER_PROFILE": "",
"JUSO_TIMEOUT": "40"
}
}
}
}
Claude Code (.mcp.json)
Claude Code expands ${VAR} from the shell environment, with :-default
fallback:
{
"mcpServers": {
"juso": {
"command": "juso-search",
"args": [],
"env": {
"JUSO_EXTENSION_ID": "${JUSO_EXTENSION_ID}",
"JUSO_BROWSER_PATH": "${JUSO_BROWSER_PATH}",
"JUSO_BROWSER_PROFILE": "${JUSO_BROWSER_PROFILE:-}",
"JUSO_TIMEOUT": "${JUSO_TIMEOUT:-40}"
}
}
}
}
Tools
| Tool | Params | Notes |
|---|---|---|
search |
query, provider, force_refresh? |
Available providers are discovered via the list-providers tool. |
engine-search |
query, engine, max_results? |
Available engines are discovered via the list-engines tool. |
search-instance |
query, instance, force_refresh? |
Searches a configured provider instance. |
search-site |
query, site, max_results? |
Searches a configured site instance (per-site engine search). |
search-aggregate |
query, aggregate, force_refresh? |
Runs a configured aggregate instance (multi-source reranked search). |
list-providers |
— | Providers and their config state. |
list-engines |
— | Available engine ids for engine-search. |
list-instances |
— | Registered provider instances. |
list-sites |
— | Registered site instances (ids for search-site). |
list-aggregates |
— | Registered aggregate instances (ids for search-aggregate). |
All tools are annotated readOnlyHint + openWorldHint. Tool results carry
structuredContent plus a text serialization; engine-search error replies
(consent wall, challenge, timeout) and search-site / search-aggregate
error replies (unknown id, disabled engine-search sub-switch, rerank
unconfigured) surface as successful results carrying an error field —
only genuine bridge failures (e.g. Chrome not found, bridge not enabled) come
back as isError.
The search tools return leads, not evidence: titles, snippets, and AI summaries may be truncated, stale, or inaccurate. Agents should open result URLs with their own page-fetch capability and verify specifics on the source page.
Prerequisites (in the extension)
- Find your extension id: open
chrome://extensions(enable Developer mode), copy the 32-char id from the Juso card — or useabout:addonson Firefox for the email-style/{GUID}id, and export the skill from the Options page to get the fullmoz-extension://bridge URL (set it asJUSO_BRIDGE_URLinstead of the id). - Enable Agent Bridge in the extension's Options. Without it every call
fails with
extension_did_not_claim. - To use
engine-search, also enable its sub-switch in Options.
Development / tests
python -m pytest mcp-server/tests # or: npm run test:mcp
The suite covers config parsing/exit codes, tools/list schema and wire
fields, tools/call dispatch and error shapes, the dual-era handshake over
real subprocesses, and stdout cleanliness (only JSON-RPC on stdout).
Metadata
Release files for juso-search 0.4.0
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 |
|---|---|---|---|---|
| juso_search-0.4.0.tar.gz | 31.2 kB | With provenance | Details for juso_search-0.4.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| juso_search-0.4.0-py3-none-any.whl | Python 3 | none | any | Details for juso_search-0.4.0-py3-none-any.whl |
Total release size: 55.9 kB
Release files / juso_search-0.4.0.tar.gz
| Download URL | juso_search-0.4.0.tar.gz |
|---|---|
| Size | 31.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
45ab28761a5c2110ac3b7afb330b3bdb1d12b6a9eb0acb3d181d22c8ed438ebb
|
|
BLAKE2b-256 checksum How to use checksums |
0d2e971803f8f728fc5c707a7e95ad3d5f46e05a6553ca3bc361e76d95132a21
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 31, 2026.
Transparency logRelease files / juso_search-0.4.0-py3-none-any.whl
| Download URL | juso_search-0.4.0-py3-none-any.whl |
|---|---|
| Size | 24.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c8f00282d6fe8a41c97b112d217c14ee091380dad78a2548ba1609102062ac46
|
|
BLAKE2b-256 checksum How to use checksums |
bba18e1dbe3905b0792f5a9018687f4f7997f6f65e6cd55aeaf16ad2cd4ce8fd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 31, 2026.
Transparency logSecurity for juso-search 0.4.0
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
Both files in this release have been uploaded with provenance metadata.
Attestation for juso_search-0.4.0.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 Oct 31, 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.