ต้นแบบ · รุ่นทดลอง: มีทุก server ในทะเบียนทางการ อัปเดตทุก 30 นาที รีวิวและบัญชีผู้ใช้จะมาในขั้นถัดไป
PopNx MCPที่รวม MCP สำหรับคนใช้ AI · อธิบายเป็นภาษาคน

Search that shows its work

โดย AG-Bureauรุ่น 0.3.5i★ –i–
ชื่อใน registrycom.ag-bureau/search

ติดตั้ง

ภาพรวม

คำอธิบายจากผู้ทำ (ภาษาอังกฤษตามต้นฉบับ)

Self-hosted web search that reports how much of each answer to believe

สามเสาของ PopNx MCP

สามเรื่องนี้ไม่รวมเป็นคะแนนเดียว เพราะความเห็น การวัด และความนิยม เป็นคนละเรื่องกัน

ใช้ทำอะไรได้

ตัวนี้ยังไม่ได้เรียบเรียงเป็นภาษาไทย ด้านล่างคือข้อเท็จจริงที่เราอ่านจาก registry

  • การเชื่อมต่อ: –
  • ช่องทาง (transport):
  • หมวด: ค้นข้อมูลและความจำของ AI

ติดตั้ง

เลือกโปรแกรม AI ที่คุณใช้ แล้วคัดลอกค่าตั้งไปวาง

ก่อนติดตั้ง

ผู้ทำยังไม่ได้ใส่วิธีติดตั้งใน registry ให้ดู README ของผู้ทำด้านล่าง

ทำอะไรได้บ้าง

รันในเครื่องคุณ รายการเครื่องมือจะขึ้นในแอป AI หลังติดตั้ง

ผลตรวจเบื้องต้นi

เราตรวจจากข้อมูลที่ใครก็เปิดดูได้ ยังไม่ได้อ่านโค้ด ข้อที่ไม่เกี่ยวกับตัวนี้ไม่นับในตัวหาร · ตรวจเมื่อ 7 พ.ย. 2569

  • ✓ ผ่าน

    ตัวตนผู้ทำตรงกับ repo

    ชื่อใน registry ยืนยันโดเมน ag-bureau.com แล้ว (registry ตรวจความเป็นเจ้าของโดเมน)

  • … ยังไม่ตรวจ

    ยังมีคนดูแล

    ยังไม่ได้อ่านข้อมูล repo จาก GitHub

  • … ยังไม่ตรวจ

    มีสัญญาอนุญาต (license)

    ยังไม่ได้อ่านข้อมูล repo จาก GitHub

  • – ไม่เกี่ยว

    endpoint ตอบ

    ตัวนี้รันบนเครื่องคุณ ไม่มี endpoint บนอินเทอร์เน็ต

  • – ไม่เกี่ยว

    ล็อกอินแบบ OAuth

    ตัวนี้รันบนเครื่อง ใช้ค่าที่ตั้งในเครื่องแทน

  • … ยังไม่ตรวจ

    คำอธิบายเครื่องมือไม่มีคำสั่งแอบแฝง

    รันในเครื่องคุณ เราอ่านรายการเครื่องมือได้เฉพาะตัวที่มี endpoint บนอินเทอร์เน็ต

เทียบกับตัวอื่นในหมวด ค้นข้อมูลและความจำของ AIi

  • ดาวมากกว่า 0% ของอีก 7264 ตัวในหมวดนี้
  • ส่งรุ่นใหม่เข้า registry ล่าสุดกว่า 48% ของอีก 7264 ตัวในหมวดนี้
  • ผลตรวจเบื้องต้นดีกว่าหรือเท่ากับ 100% ของอีก 7264 ตัวในหมวดนี้

เทียบกับทุก server ที่ยังใช้งานในหมวดนี้ทั้งทะเบียน ดาวนับเฉพาะเมื่อผู้ลงทะเบียนเป็นเจ้าของ repo

คำถามที่พบบ่อย

Search that shows its work ปลอดภัยไหม?

จากการตรวจเบื้องต้นของเรา ผ่าน 1 จาก 1 ข้อที่ตรวจได้ เรายังไม่ได้อ่านโค้ด ก่อนใส่กุญแจหรือ token ให้ดูว่า server ขอสิทธิ์อะไร และเลือกกุญแจที่ทำได้เท่าที่จำเป็น

ต้องใช้กุญแจหรือรหัสอะไรบ้าง?

registry ไม่ได้ระบุว่าต้องใช้กุญแจ แต่บางตัวจะขอให้ล็อกอินตอนใช้ครั้งแรก

ตัวนี้รันบนเครื่องหรือบนคลาวด์?

รันบนเครื่องของคุณ โปรแกรม AI จะเปิด server ขึ้นมาเองเมื่อใช้ ข้อมูลไม่ต้องผ่านเซิร์ฟเวอร์ของผู้ทำ (ยกเว้นตัวที่ไปเรียกบริการออนไลน์ต่อ)

ยังมีคนดูแลอยู่ไหม?

repo บน GitHub มีการแก้โค้ดล่าสุด – และส่งรุ่นล่าสุด (0.3.5) เข้า registry 42 วันที่ผ่านมา

ใช้กับโปรแกรมไหนได้บ้าง?

โปรแกรมที่รองรับ MCP เช่น Claude Desktop, Claude Code, Cursor และ VS Code

มีตัวไหนใช้แทนได้บ้าง?

ในหมวดเดียวกันมี Context7, Codebase Memory, Exa

ตัวที่ใช้แทนได้

server หมวดเดียวกันจากผู้ทำคนอื่น เรียงตามดาว

อ่านการ์ด:★ ดาว GitHubiสามเสา: รีวิว · ผลตรวจ · การใช้งานiอัปเดต = วันที่ส่งรุ่นล่าสุดเข้า registryi

Context7

โดย upstash

ส่งคู่มือการใช้ไลบรารีและเฟรมเวิร์กรุ่นล่าสุดให้ AI อ่านก่อนตอบ ช่วยให้โค้ดที่ AI เขียนไม่ใช้คำสั่งเก่าที่เลิกใช้แล้ว

บนเครื่องหรือคลาวด์★ 64,224MITอัปเดต เมื่อวาน
ติดตั้ง

Codebase Memory

โดย DeusData

Codebase knowledge graph for AI agents — 162 languages, sub-ms queries, 99% fewer tokens.

รันบนเครื่อง★ 48,148MITอัปเดต 21 วันที่ผ่านมา
ติดตั้ง

Exa

โดย exa-labs

Connect AI agents to Exa for web search, content fetching, and multi-step research.

รันบนคลาวด์★ 5,213MITอัปเดต เดือนที่แล้ว
ติดตั้ง

README จากผู้ทำ

เปิดอ่าน README

ส่วนนี้คัดจาก repo ของผู้ทำตามต้นฉบับ PopNx MCP ไม่ได้ตรวจหรือรับรองเนื้อหา ตัด HTML รูปภาพ และสคริปต์ออกแล้ว ลิงก์จะพาออกนอกเว็บ

search

A self-hosted MCP server for web search that reports how much of each answer to believe


A search tool fails in ways that look exactly like success. An engine answers with somebody else's subject. A page returns text that is an anti-bot shield. Sixteen sources turn out to be two engines counted eight times. None of that raises an error, and the model on the other end builds on it.

This server's job is to make those cases distinguishable, in fields you can branch on. It runs on your machine, over your own metasearch instance, with your own model key — or none at all.

🔧 Tools

ToolWhat it doesRequiredNotable options
web_searchFinds pages and reads the top ones — one call, links with their textqueryread: false for links only · read_top how many to read · min_engines to force breadth · engines to name the engines yourself
web_readReads pages by address: text, PDF, or a scan recognised by a vision modelurlsmode: browser for JS-rendered pages · expect to assert what must be there · offset to continue
web_image_searchFinds images: the address of the FILE and, separately, of the page it sits onquerymax_results, page
web_screenshotA PNG of a page plus its text from the same visit, so the two can be cross-checkedurlmax_chars for how much text · full_page · expect
web_deep_searchComposes its own queries, reads in waves, and answers from several sources — saying what it could not confirmquestionwaves

Full argument reference, response shapes and failure modes: [HOWTO-CALL.md](HOWTO-CALL.md).

📦 Install

From an open repository page to a working answer. Nothing is assumed to be on your disk already:

git clone https://github.com/AG-Bureau/mcp-search

cd mcp-search cp .env.example .env echo "SEARXNG_SECRET=$(openssl rand -hex 32)" >> .env echo "BROWSER_WS_SECRET=$(openssl rand -hex 16)" >> .env echo '{}' > door-tokens.json && mkdir -p tls docker compose -f docker-compose.yml -f wiring/expose-localhost.yml up -d --build curl -s http://127.0.0.1:8081/healthz

The fourth and fifth lines are not decoration. Without a value in SEARXNG_SECRET the up command refuses — and that refusal is deliberate: with no key of its own the metasearch does not fail, it comes up with a publicly known one from its image template, silently. BROWSER_WS_SECRET is the secret path of the browser sidecar's endpoint, and up refuses without it too: on a guessable path, anything that can open a WebSocket to the sidecar — any container on the compose network, and any page the browser itself opens — gets a browser of its own, outside every check the module applies to the pages it reads. The compose file hands the same value to the sidecar and, at the end of BROWSER_WS_URL, to the adapter; neither prints it.

The sixth line creates the two paths the compose file mounts for caller authentication and TLS — both off by default. A path that does not exist is created by Docker as a root-owned DIRECTORY, and a token "file" that is a directory reads as an unreadable list (see Configuration below). Both are in .gitignore: they hold secrets once you use them.

The overlay publishes the port on loopback only. A published container port does not go through the host firewall's usual chain, so exposing it more widely is a separate, deliberate step — see Deployment.

Two transports

MCP has two, and they answer different questions. HTTP — the commands above — is for a server that is already running somewhere. stdio is the protocol's default: the client starts the server as a process and talks to it through the pipes, which is how most desktop clients and wrappers work.

docker compose exec -T ag-search python /app/server.py --stdio   # or MCP_TRANSPORT=stdio

outside compose: SEARXNG_URL=http:// python adapter/server.py --stdio

One JSON-RPC object per line in, one answer per line out. The mode is chosen explicitly and never guessed from whether a terminal is attached — that sign merely sits next to the subject, and one day it answers for a case nobody meant.

In stdio mode stdout is the protocol: answers and nothing else, with the log on stderr. One stray line of anything else breaks the client reading it.

Each process started this way is an instance of its own, even inside the running container: its browser sessions (BROWSER_MAX_SESSIONS), its engine and domain pacing and its /stats counters are separate from the HTTP server's. Several stdio clients on one sidecar add up in its pids_limit like several adapters do.

The sidecars do not depend on the choice; the metasearch does: SEARXNG_URL must reach one, or every search refuses with cause: upstream (the default, http://searxng:8080, is a name only the compose network knows). Started by a client with no compose project around it, the module names what else is missing instead of pretending: the browser path reports not_wired_up, and trouble carries pool_unmeasured — the engine pool was never computed from observation.

⬆️ Upgrading to 0.3.5 — no new variable

From 0.3.4: the same command as the install block, with the same -f files. Only the adapter image changes (ag-mod-search/adapter:0.3.5, used by the adapter and the prober); the sidecar stays ag-mod-search/browser:1.49.1-3. Two things you may notice: the door now logs one line per request (the caller's address, the path, the status and the caller's token name — never the token, the body or the query string), and a model call that runs out of the time its caller had now returns a refusal that says so instead of running on. From 0.3.3 or earlier, the 0.3.4 steps below apply too.

⬆️ Upgrading to 0.3.4 — no new variable, one stricter one

From 0.3.3: the same command as the install block, with the same -f files. Only the adapter image changed; the sidecar stays ag-mod-search/browser:1.49.1-3. Check AG_DOOR_AUTH first: a value that is not off, warn or on (in any case, spaces around it ignored) now stops the adapter from starting, where it used to mean off. From 0.3.2 or earlier, the 0.3.3 steps below apply too.

⬆️ Upgrading to 0.3.3 — one new required variable

BROWSER_WS_SECRET must be in .env before up: add it as the install block does, with openssl rand -hex 16. Then run the install block's own command, with the same -f files you installed with: docker compose -f docker-compose.yml -f wiring/expose-localhost.yml up -d --build. It rebuilds both images and recreates the adapter, the prober and the sidecar, since the image or the environment of each changed. Name no services on it: up … browser ag-search leaves the prober on the old image, and leaving out the -f overlay recreates the adapter without its published port. The sidecar image is ag-mod-search/browser:1.49.1-3; with the old sidecar, or with only one side recreated, the browser path reads "not responding".

A malformed secret stops the whole module. Compose checks only that the value is not empty. Characters outside A-Z a-z 0-9 _ - (base64 gives + / =) make the sidecar exit with 78 in a loop; the adapter waits for a healthy sidecar, so it never starts and up says "dependency failed to start".

If you run the door in warn or on, also read "Moving to on" under Configuration: the prober now takes a token, a token with no scopes (or with scopes written as a string) may call no tool, and /healthz?deep=1 needs a token that may search or read.

⬆️ Upgrading from 0.2.x — the answer changed shape

If you already run 0.2.1 or earlier, read this before updating. Nothing here is a new feature you may ignore; it is what your existing calls will return differently.

The search and image answers carry fewer fields by default, and they say so in their name: ag.search/3 and ag.images/3 instead of /2. A caller that branched on contract will break loudly, which is the intent — a field that simply vanished would read as "nothing was wrong" in most languages.

in 0.2.xin 0.3
search_aborted, engines_unaskedtrouble.search_aborted, trouble.engines_unasked
unresponsive_enginestrouble.unresponsive_engines
engines_irrelevanttrouble.engines_irrelevant
pool_source: "seed"trouble.pool_unmeasured, with the reason
arguments_adjustedtrouble.arguments_adjusted
corroborated_by_url, corroborated_by_domain — always present, 1 on the cheap pathabsent when only one engine found results: there 1 meant "nobody else was asked", not a measurement
count, query, page, read, read_top, pages_*, timing_ms, engines_skipped, engines_used, tiers_used, pool_source, pool_reasonreturned when you ask: verbose: true

trouble is always present and empty when nothing went wrong, so if not trouble replaces the four separate checks. Nothing was deleted from the module — the accounting moved behind a request.

Booleans are now parsed rather than cast. In 0.2.x "read": "false" over MCP read the pages anyway — eight times the wall clock — while the plain door understood the same word correctly. Both doors now accept true/false, 1/0, yes/no, on/off, y/n, t/f and Python's True/False, case-blind. A value that cannot be read turns the flag off and is named in `arguments_adjusted`, and an EMPTY value counts as unreadable: read="" no longer buys the expensive default in silence.

`read_top: 0` means "no preference", not "read nothing" — for nothing, use read: false. The schema used to declare minimum: 1 while accepting zero.

The field-by-field table is in the contracts: contracts/ag.search.v3.md and contracts/ag.images.v3.md, section "What changed against /2". Reading (ag.read/2), deep search (ag.deep/2) and screenshots (ag.shot/1) kept their numbers: they gained fields, and an addition breaks nobody.

⚙️ Configuration

VariableRequiredWhat it is
SEARXNG_SECRETyesSession key for the metasearch. Any long random string that is not from somebody's history.
BROWSER_WS_SECRETyesThe browser sidecar's secret endpoint path, 16-256 characters of A-Z a-z 0-9 _ - (openssl rand -hex 16). The sidecar exits at start without it, and the compose file refuses first. A value with other characters passes the compose file and stops the whole module: the sidecar exits with 78, and the adapter, which waits for a healthy sidecar, never starts. To rotate, change it and run the same up -d as at install, with the same -f files: both browser and ag-search are recreated, because the environment of both changed.
LLM_API_KEYnoKey for any OpenAI-compatible endpoint. Secret.

| LLM_API_BASE | no | Base URL of that endpoint. Take it from your provider's documentation, not by analogy — the obvious guess can answer with a billing error such as 429: Insufficient balance, because some providers serve a subscription on a different

ตัดมาแค่ช่วงต้น อ่านต่อใน repo

ถาม PopNx