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

mcp-gatehouse

โดย nickgeorgeseoรุ่น 0.5.0i★ –iรันบนเครื่อง
ชื่อใน registryio.github.nickgeorgeseo/gatehouse

ติดตั้ง

ภาพรวม

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

Permission tiers, approval gates, and audit logging for MCP servers - the server is the gatekeeper

สามเสาของ PopNx MCP

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

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

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

  • การเชื่อมต่อ: รันบนเครื่อง
  • ช่องทาง (transport): stdio
  • หมวด: อื่น ๆ

ติดตั้ง

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

ก่อนติดตั้ง

ต้องเตรียมก่อน

  • PyPIติดตั้ง uv ของ Python (มีคำสั่ง uvx) ในเครื่อง

คุณใช้แอปไหน

เลือกแอปด้านบน เราจำไว้ให้ ครั้งหน้าปุ่มจะขึ้นว่า “ติดตั้งลง …”

เปิด Claude Desktop → Settings → Developer → Edit Config แล้ววางค่านี้ในไฟล์ claude_desktop_config.json

{
  "mcpServers": {
    "gatehouse": {
      "command": "uvx",
      "args": [
        "mcp-gatehouse"
      ]
    }
  }
}

พิมพ์คำสั่งนี้ใน Terminal

claude mcp add gatehouse -- uvx mcp-gatehouse

เปิดใน Cursor

หรือคัดลอกค่าตั้งเอง

วางในไฟล์ .cursor/mcp.json ของโปรเจกต์ หรือ ~/.cursor/mcp.json

{
  "mcpServers": {
    "gatehouse": {
      "command": "uvx",
      "args": [
        "mcp-gatehouse"
      ]
    }
  }
}

เบราว์เซอร์จะถามก่อนเปิดแอป จากนั้นแอปแสดงค่าตั้งให้ตรวจแล้วกดยืนยัน ช่อง key เว้นว่างไว้ให้คุณใส่เอง

เปิดใน VS Code

หรือคัดลอกค่าตั้งเอง

วางในไฟล์ .vscode/mcp.json ของโปรเจกต์

{
  "servers": {
    "gatehouse": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "mcp-gatehouse"
      ]
    }
  }
}

เบราว์เซอร์จะถามก่อนเปิดแอป จากนั้นแอปแสดงค่าตั้งให้ตรวจแล้วกดยืนยัน ช่อง key เว้นว่างไว้ให้คุณใส่เอง

ตัวนี้รันในเครื่องคุณ แต่ ChatGPT ต่อได้เฉพาะ server บนอินเทอร์เน็ต ลองเลือกแอปอื่น

ตัวเลือกเก็บในคุกกี้บนเครื่องนี้ ไม่ต้องมีบัญชี

ค่าตั้งนี้สร้างจากข้อมูลใน registry ของผู้ทำ ถ้าไม่ตรงกับ README ให้เชื่อ README

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

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

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

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

  • ✓ ผ่าน

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

    ชื่อใน registry ยืนยันด้วยบัญชี GitHub nickgeorgeseo ซึ่งเป็นเจ้าของ repo

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

    ยังมีคนดูแล

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

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

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

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

  • – ไม่เกี่ยว

    endpoint ตอบ

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

  • – ไม่เกี่ยว

    ล็อกอินแบบ OAuth

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

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

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

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

เทียบกับตัวอื่นในหมวด อื่น ๆi

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

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

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

mcp-gatehouse ปลอดภัยไหม?

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

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

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

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

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

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

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

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

โปรแกรมที่รองรับ MCP เช่น Claude Desktop, Claude Code, Cursor และ VS Code ตัวนี้ต้องมี Python (uv) ในเครื่องด้วย

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

ในหมวดเดียวกันมี Spec Driven Development, Remote Desktop Commander, Microsoft Exchange Online MCP

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

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

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

Spec Driven Development

โดย formulahendry

MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.

รันบนเครื่อง★ 440MITอัปเดต 14 เดือนที่ผ่านมา
ติดตั้ง

Remote Desktop Commander

โดย desktop-commander

Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.

รันบนคลาวด์★ 211อัปเดต เมื่อวานซืน
ติดตั้ง

README จากผู้ทำ

เปิดอ่าน README

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

mcp-gatehouse

Project page & docs: nickgeorgeai.com/open-source/mcp-gatehouse · PyPI

Permission tiers, approval gates, and audit logging for MCP servers. The server is the gatekeeper: you decide what an AI can read, what it can write, and what's off-limits — and every action gets logged.

Most MCP servers hand the model every tool at full strength and keep no record of what it did. That's fine for a demo. It's not fine the day an agent has write access to your CRM, your books, or your order system. mcp-gatehouse is the missing gate, enforced inside the server — no proxy, no external policy service, no dependencies beyond the official mcp SDK.

pip install mcp-gatehouse

The demo server in Claude Code: the model asks to cancel an order, the gate asks *you* in Claude Code's own UI, and the audit log records the call as asked, then done.

The 1:21 demo runs the package's demo server in a terminal: the install, the one-decorator change, a cancel refused and one approved, and the audit log they left. No sound.

What you get

Permission tiersEvery tool is declared READ, WRITE, or DESTRUCTIVE — and the tier also emits honest spec ToolAnnotations (readOnlyHint / destructiveHint), which the wrapper won't let you override to lie.
Approval gatesTiers you choose require a sign-off before the tool runs, asked right in the MCP client (Claude Code, Cursor, VS Code) or by any callable you write: a terminal prompt, a Slack ping, a ticket. Fails closed: a gated tool with no approver configured is denied, not waved through.
Audit logAppend-only JSONL, one line per call — allowed, denied, failed, or cancelled — with UTC timestamps and durations. The answer to "what did the AI actually do?" six months later.
RedactionArgument keys you name (api_key, password, token, client_secret, … by default) are masked before they reach the log *or* the approver — however they're spelled: apiKey, API-Key and api_key are the same key.
DenylistBlock a tool outright, whatever its tier.

Quickstart

from mcp.server.mcpserver import MCPServer

from mcp_gatehouse import ( AccessTier, AuditLog, ElicitationApprover, Gatehouse, Policy, terminal_approver, )

mcp = MCPServer("order-desk") gatehouse = Gatehouse( mcp,

Ask in the client's own UI; prompt on the terminal if it can't show a form.

policy=Policy(approver=ElicitationApprover(fallback=terminal_approver)), audit=AuditLog(path="~/order-desk/audit.jsonl"), )

@gatehouse.tool(tier=AccessTier.READ) def lookup_order(order_id: str) -> str: """Look up an order's status.""" ...

@gatehouse.tool(tier=AccessTier.DESTRUCTIVE) def cancel_order(order_id: str) -> str: """Cancel an order. Runs only if the approver says yes.""" ...

mcp.run()

That's the whole integration: build your MCPServer exactly as the SDK docs show, but register tools through the gatehouse. Schema generation (including Annotated[..., Field(description=...)] parameter docs), transports, and everything else work unchanged — the guard preserves the function's signature. Sync tools still run in a worker thread, exactly as they would on a bare MCPServer.

Approve in the client

ElicitationApprover puts the question in front of the person using the MCP client, as a form with one box to tick, showing the tool, its tier and its arguments (secrets already masked). MCP calls this elicitation. Claude Code, Cursor and VS Code support it. The model can't answer the form, and you run nothing beside the server.

It works under both protocol revisions in use:

  • Up to 2025-11-25 the form goes to the client mid-call and the gate waits for it, under approval_timeout like any approver.
  • From 2026-07-28 there's no channel for that. The call hands the question back to the client and runs when the client calls again with the answer. The SDK seals that round's state and binds it to the tool and its exact arguments. The gate also checks that the answer is to the question it asked, that it arrived within approval_timeout (an hour if none is set), and that each approval runs its call only once.

Anything but a ticked box (decline, cancel, closing the form, an unticked box, a malformed answer) is a refusal. When the client can't be asked, the fallback decides; with no fallback, the call is denied. A tool that runs its own multi-round input flow, through Resolve(...) parameters or by returning InputRequiredResult, gets the fallback too, since one call has one such channel. Single-use is tracked per process.

Elicitation trusts the client to show the form to a person. A client or hook set to accept forms on its own can approve too. When the approval must come from outside the client, use an out-of-band approver instead.

Other approvers

terminal_approver asks on the controlling terminal (/dev/tty), never stdin — over stdio, stdin *is* the protocol pipe, so a plain input() approver would corrupt it. An approver is any callable, sync or async, that takes an ApprovalRequest and returns True to allow; sync ones run in a worker thread from a pool of their own, so a human taking their time doesn't stall other calls, and a pile of pending approvals can't take the threads your sync tools need. If the approver raises (Slack down, ticket API timing out), the call is denied and the failure is logged.

Give approvals a deadline so a sign-off nobody gives doesn't hang the call:

Policy(approver=terminal_approver, approval_timeout=120)

Past it, the call is denied and logged as approval timed out. Approvers see the deadline as request.deadline (a time.monotonic() value), and terminal_approver withdraws its prompt when it passes. A sync approver that ignores it finishes in the background and its answer is dropped. With no timeout set, the gate waits as long as the approver takes.

Under the default policy, DESTRUCTIVE requires approval and everything is audited. Gate writes too with one line:

Policy(require_approval=frozenset({AccessTier.WRITE, AccessTier.DESTRUCTIVE}), ...)

Add your own secret-bearing keys without losing the defaults:

from mcp_gatehouse import DEFAULT_REDACT

Policy(redact=DEFAULT_REDACT | {"card_pin"}, ...)

What the audit trail looks like:

{"ts": "2026-07-16T14:02:11+00:00", "tool": "lookup_order", "tier": "read", "outcome": "ok", "arguments": {"order_id": "4417"}, "duration_ms": 0.42}

{"ts": "2026-07-16T14:02:38+00:00", "tool": "add_note", "tier": "write", "outcome": "ok", "arguments": {"order_id": "4417", "note": "call back", "api_key": "«redacted»"}, "duration_ms": 1.08} {"ts": "2026-07-16T14:03:05+00:00", "tool": "cancel_order", "tier": "destructive", "outcome": "denied", "reason": "approver refused", "arguments": {"order_id": "4417"}} {"ts": "2026-07-16T14:05:40+00:00", "tool": "cancel_order", "tier": "destructive", "outcome": "cancelled", "reason": "awaiting approval", "arguments": {"order_id": "4418"}}

outcome is ok, denied (reason says why), error (the tool raised; reason is the exception type), pending, or cancelled. pending is a call whose approval was asked in the client over the 2026-07-28 round trip: the verdict follows on a line of its own when the client comes back, so a pending line with nothing after it is a question nobody answered. cancelled means the client gave up, or the server shut down, before the call finished. reason says when. awaiting approval means the tool never ran. tool running comes with duration_ms, and the tool may have done part of its work. A sync tool can't be stopped partway: its worker thread runs to the end, and the line says ok or error as usual. The gate only writes the line; the cancellation goes on as it would without it.

Try the demo

The package ships a runnable order-desk server with all three tiers wired up. Approvals are asked in the client when it can show a form, with a terminal prompt as the fallback. Add it to any MCP client that speaks stdio. For Claude Code:

claude mcp add gatehouse-demo -- uvx mcp-gatehouse --audit-log /tmp/gatehouse-audit.jsonl

For Claude Desktop, in claude_desktop_config.json:

{

"mcpServers": { "gatehouse-demo": { "command": "uvx", "args": ["mcp-gatehouse", "--audit-log", "/tmp/gatehouse-audit.jsonl"] } } }

Or run mcp-gatehouse-demo yourself after pip install mcp-gatehouse. Ask the model to list the orders and cancel one, then watch the verdict land in the audit log either way. The audit log goes to --audit-log, else $MCP_GATEHOUSE_AUDIT_LOG, else ./audit.jsonl — falling back to ~/.mcp-gatehouse/audit.jsonl when the working directory isn't writable (desktop clients often launch servers from /). The server prints the path it chose to stderr.

In a client that supports elicitation (Claude Code, Cursor, VS Code), cancel_order brings up an approval form in the client: tick the box to let it run. An approval nobody gives is denied after two minutes.

Other clients get the terminal fallback, which needs the server to have a terminal it can ask on. Whether it gets one depends on how the client starts it:

  • TypeScript SDK clients (the StdioClientTransport in 1.x and 2.x) keep the server in the client's terminal session. Start such a client from an ordinary terminal, one not running a full-screen program, and the prompt appears there. An unanswered prompt is denied after two minutes.
  • Python SDK clients (stdio_client in 1.x and 2.x), and anything built on them, start every server in a session of its own. The server has no controlling terminal even when you run the client from one, so it can't prompt: cancel_order is denied, and stderr says why.
  • Desktop apps that launch servers in the background give them no terminal, and full-screen terminal UIs are using theirs. Denied too.

Every denial is the gate failing closed, as designed. Where the prompt can't reach you, approve out-of-band instead: an approver is any callable, so it can post to Slack, open a ticket or wait on a queue. examples/orders_server.py is the same server as a copyable template.

Design notes

  • Enforcement lives inside the server, at the tool boundary. A proxy can't see your tools' semantics, and a policy service is one more thing to deploy. A 40-person plant doesn't have a platform team; this is a

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

ถาม PopNx