プロトタイプ · プレビュー版:公式レジストリのすべてのサーバーを掲載し、30分ごとに同期しています。レビューとアカウント機能は今後のステップで始まります。
PopNx MCPAIを使う人のためのMCPサーバー · やさしい言葉で解説

CTRLRun Operator

作者:CTRLRunバージョン 0.12.2i★ –iパソコンで動く
レジストリ名io.github.CTRLRun/ctrlrun-mcp-operator

インストール

概要

作者による説明(英語の原文)

Answer CTRLRun approvals from an MCP client: list what is held, inspect it, grant or deny.

PopNx MCPの3つの柱

この3つを1つのスコアにまとめることはしません。意見、測定、人気はそれぞれ別のものだからです。

できること

このサーバーのやさしい解説はまだ書いていません。以下はレジストリから読み取った事実です。

  • 接続方法: パソコンで動く
  • トランスポート: Streamable HTTP
  • カテゴリ: その他

インストール

使っているAIアプリを選んで、設定をコピーしてください。

インストールの前に

  • 基本チェック:1項目中1項目に合格
  • あなたのパソコンで、あなたのユーザーと同じ権限(ファイル、ネットワーク、アプリ)で動きます。
  • レジストリには、入力が必要なキーは載っていません。

必要なもの

  • PyPIPythonのuvのインストール(uvxコマンドに必要)

どのアプリを使っていますか?

上でアプリを選んでください。選んだアプリを覚えておくので、次からはボタンに「…にインストール」と表示されます。

Claude Desktop → Settings → Developer → Edit Config を開き、claude_desktop_config.json にこれを貼り付けます

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

ターミナルでこれを実行します

claude mcp add ctrlrun-operator -- uvx ctrlrun mcp-operator

Cursorで開く

または、設定を自分でコピーする

プロジェクトの .cursor/mcp.json、または ~/.cursor/mcp.json に貼り付けます

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

ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。

VS Codeで開く

または、設定を自分でコピーする

プロジェクトの .vscode/mcp.json に貼り付けます

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

ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。

これはパソコンで動くサーバーですが、ChatGPTがつなげるのはインターネット上のサーバーだけです。ほかのアプリを選んでください。

選んだアプリは、この端末のCookieに保存されます。アカウントは不要です。

この設定は、作者のレジストリ登録情報から作成しています。READMEと違う場合は、READMEに従ってください。

できること

パソコンで動くサーバーです。インストールすると、ツール一覧がAIアプリに表示されます。

基本チェックi

誰でも見られる情報をチェックしており、コードは読んでいません。当てはまらない項目は数に入れていません。 · 2026年11月6日にチェック

  • ✓ 合格

    作者とリポジトリが一致

    レジストリ名は、リポジトリを所有するGitHubアカウント CTRLRun で確認済みです

  • … 未チェック

    今もメンテナンスされている

    このリポジトリはまだGitHubから読み取っていません

  • … 未チェック

    ライセンスがある

    このリポジトリはまだGitHubから読み取っていません

  • – 対象外

    エンドポイントが応答する

    これはパソコンで動くため、インターネット上のエンドポイントはありません

  • – 対象外

    OAuthでサインイン

    パソコンで動き、代わりにローカルの設定を使います

  • … 未チェック

    ツールの説明に隠れた指示がない

    パソコンで動くサーバーです。ツール一覧を読み取れるのは、インターネット上のエンドポイントがある場合だけです

その他のほかのサーバーとの比較i

  • このカテゴリのほかの32380件のうち0%よりスターが多い
  • このカテゴリのほかの32380件のうち43%より最近レジストリに公開
  • 基本チェックの結果が、このカテゴリのほかの32380件のうち100%と同じかそれ以上

レジストリでこのカテゴリにある有効なすべてのサーバーと比較しています。スターは、公開者がリポジトリの所有者である場合だけ数えます。

よくある質問

CTRLRun Operatorは安全ですか?

当てはまる基本チェック1項目のうち1項目に合格しました。コードは読んでいません。キーやトークンを追加する前に、サーバーがどんなアクセスを求めているかを確認し、必要な権限だけを持つキーを使ってください。

どんなキーやコードが必要ですか?

レジストリには必須のキーは載っていません。ただし、最初に使うときにサインインを求めるサーバーもあります。

パソコンで動きますか、それともクラウドですか?

あなたのパソコンで動きます。必要なときにAIアプリが起動し、データは作者のサーバーを通りません(サーバー自体がオンラインサービスを呼び出す場合を除きます)。

今もメンテナンスされていますか?

GitHubリポジトリの最終更新は–、最新バージョン(0.12.2)がレジストリに届いたのは2 か月前です。

どのアプリで使えますか?

Claude Desktop、Claude Code、Cursor、VS CodeなどのMCP対応アプリで使えます。パソコンにPython (uv)も必要です。

代わりに使えるものは?

同じカテゴリには:Spec Driven Development, Remote Desktop Commander, Dechonet MCP

代わりの候補

同じカテゴリで、ほかの作者が作ったサーバー。スターの多い順。

カードの見方:★ GitHubスターi3つの柱:レビュー · チェック · 利用状況i更新=最新バージョンをレジストリに公開した日i

Remote Desktop Commander

作者:desktop-commander

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

クラウドで動く★ 211昨日更新
インストール

Dechonet MCP

作者:node-man

30 security tools for AI agents: phishing links, exposure maps, DNS, SSL, PQC, history, pivots.

パソコンでもクラウドでも今日更新
インストール

作者のREADME

READMEを開く

作者のリポジトリから書かれたとおりにコピーしたものです。PopNx MCPは内容を確認・推奨していません。HTML、画像、スクリプトは取り除いています。リンクはこのサイトの外へ移動します。

ctrlrun stops AI agents from taking wrong, restricted, or malicious actions in your workflows.

Every action is checked against your rules before it runs. Allowed actions go through.

Sensitive ones wait for a person. Forbidden ones are blocked.

Execution safety for AI agents. A Python library that sits between the decision to act and the call that acts.

A consequential action happens at most once, exactly as approved, and leaves a receipt.

When the outcome is unknown, ctrlrun says so instead of guessing.

Runs in production on a single file, or on Postgres across hosts. Apache-2.0.

pip install ctrlrun && ctrlrun demo

What it does

The model guesses. ctrlrun does not. The ticket says refund €500. The agent asks for €5,000, one extra zero. The tool is in its list, the arguments are well formed, and the model is completely confident. Nothing above the call disagrees, because nothing above the call is a check: a tool being callable is not permission to call it with those arguments.

Without ctrlrunWith ctrlrun
Nothing checks the amount. The call goes through. €4,500 too much.Your rule checks the amount. The call never leaves. €0 wrongly paid.

ctrlrun is that check. It reads the arguments about to leave your process and answers what may happen to them: let it run, ask a human, or stop it cold. Four rules do the work, and each one is a test in this repository before it is a sentence here.

Exact means exactChanged arguments need a new approval.
Once stays onceSame effect key, shared store, no repeat.
Unknown means waitConfirm the outcome before retrying.
Every answer is keptRequests, decisions and results, refusals included.

The third one is the half people forget. A correct €500 refund commits at the provider and the reply is lost coming back, so the agent retries. Retry libraries, agent frameworks and tool loops collapse *this failed* into *I do not know what happened*. ctrlrun keeps them apart: a lost reply is AMBIGUOUS, never FAILED, and a retry against an AMBIGUOUS effect is refused until a human, or a reconcile hook, says what happened.

What ctrlrun demo shows: five failures and five refusals, byte for byte

$ ctrlrun demo

ctrlrun demo — five ways an agent action goes wrong, and what stops it. Policy: refunds up to €1,000 are autonomous, up to €10,000 need a human, above that are denied.

  1. Duplicate effect after a lost response

refund €500 → remote commits → response lost → effect: AMBIGUOUS agent retries the same refund ✗ BLOCKED — effect may already have committed; blind retry refused remote refund calls: 1 only a human moves it on: ctrlrun resolve refund:txn_1 --committed|--failed

  1. Approval mutation

agent proposes refund €2,000 → human approves apr_0aa78e0380ba55d77a601dc782f57095 (bound to the action hash) agent executes refund €5,000 → ✗ BLOCKED — approved action ≠ requested action (mismatch)

  1. Concurrent agents, same effect

Agent A reserve refund:txn_123 → ACQUIRED → executes Agent B reserve refund:txn_123 → ✗ BLOCKED — already reserved (in_progress)

  1. Approval replay

approval apr_dbc8bc6f06690cdf2e2c55a4e591ef3b used once → consumed same approval presented again → ✗ BLOCKED — single-use approval already consumed

  1. Authority escalation

human €100,000 delegable → finance agent €25,000 → support agent €2,000 support agent's grant: dlg_5f8d41938a3f29972d5489d676cd9edb support agent requests €50,000 → ✗ BLOCKED — outside the delegated grant (authority_constraint) remote refund calls: 0 finance agent tries to delegate €50,000 under its own €25,000 → refused (containment: constraints) support agent requests €1,500 → authority permits it, and the policy asks a human (apr_f86eca24dd80206ab5189ccb1b62aa55) two axes, and an action needs both: the stricter of the pair wins

Receipts (8): .ctrlrun/demo/receipts.jsonl Events: .ctrlrun/demo/events.jsonl

Read them: CTRLRUN_STATE=.ctrlrun/demo/state.db ctrlrun receipts

Approval and delegation ids are generated per run; everything else is exactly what the demo prints, and a test fails if the two drift apart. No network, no external service, under a second. pip install ctrlrun && ctrlrun demo runs it locally in about the same time.

Where it stops. It does not detect prompt injection: it contains the consequence rather than reading the cause. It cannot promise exactly-once against a remote it does not control, it refuses to *knowingly* act twice, and it rolls nothing back. Receipts are chained, so an alteration is detected; a truncation at the end and a forged append are not, because the head that would catch them is a row in the same database, and closing that is what ctrlrun anchor is for. They are not signed: alteration is not authorship. The badge above means the declared guarantees pass in the setup they ran against, and it does not mean secure, safe, compliant, certified or audited: what the badge means · OWASP-AGENTIC-TOP10.md names the four entries this does not address.

If an agent only reads and answers, you do not need ctrlrun. The moment it can send, pay, refund, delete, deploy, grant, revoke, approve, submit, purchase or cancel, you do.

Use it in three steps

The animation above is this section, recorded against the real library: one policy file, two short programs, four commands, nothing staged.

1. Install it.

pip install ctrlrun

2. Write down what the agent may do. One file, ctrlrun.yaml. Amounts are integer minor units, so 50000 is €500. Both ends of every band are bound, because an upper bound alone lets a negative amount through, and a refund of a negative amount is a charge. Anything not listed is denied; there is no default-allow.

schema: ctrlrun.policy/v2

actions: stripe.refund: effect: "refund:{payment_id}" rules:

  • when: { amount_gte: 0, amount_lte: 50000 } decision: allow # up to €500: the agent acts alone
  • when: { amount_gte: 0, amount_lte: 1000000 } decision: approve # up to €10,000: a human decides
  • decision: deny # above that: never

3. Wrap the call that has the consequence. The decorator names the action, the effect key names the consequence it has in the world, and the context names who is acting. stripe here is a stand-in that records calls instead of making them.

import sys

import ctrlrun

class FakeStripe: """Stands in for the provider: it records calls instead of making them."""

def init(self) -> None: self.calls: list[tuple[str, int]] = []

def refund(self, payment_id: str, amount: int) -> dict: self.calls.append((payment_id, amount)) return {"id": f"re_{payment_id}", "amount": amount, "status": "succeeded"}

stripe = FakeStripe()

@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}") def refund(payment_id: str, amount: int) -> dict: return stripe.refund(payment_id, amount)

if name == "main": with ctrlrun.context(agent="support-agent"): print("€500 ->", refund(payment_id="txn_1", amount=50_000)["status"]) try: refund(payment_id="txn_2", amount=500_000) except ctrlrun.ApprovalRequired as pending: print("€5,000 -> a human decides:", pending.request_id) with open("request_id.txt", "w") as handle: handle.write(pending.request_id) else: sys.exit("the €5,000 refund ran without a human; the policy is not in force") print("calls that reached the provider:", len(stripe.calls))

The €500 refund runs on its own. The €5,000 one stops and names the request a human answers:

€500   -> succeeded

€5,000 -> a human decides: apr_63e80076f2cccfee52b17491a4b2e125 calls that reached the provider: 1

A human answers from the shell. The grant names the hash of the exact action the human read, and when it lapses. Ids, hashes and dates are generated per run; yours differ.

ctrlrun approve "$(cat request_id.txt)"
granted apr_63e80076f2cccfee52b17491a4b2e125 for sha256:22ec1c398e4b93d080b6cba61e5e11b0e21879552ac5dbf63c192d2b2e6af752

expires 2026-09-13T20:10:11.367Z

The agent presents it, then tries to spend it on something else. The first call is exactly what the human app

冒頭だけを表示しています。続きはリポジトリで読めます

PopNxに聞く