Skip to main content
Glama
erpuae

Synapse

by erpuae

Synapse

Frappe および ERPNext 向けの、権限を認識する MCP サーバーです。LLM クライアントがサイトのデータを実在のユーザーとして、そのユーザー自身の権限の下で、OAuth 経由で読み書きできるようにし、すべての呼び出しを監査ログに記録します。

POST https://<your-site>/api/method/synapse.mcp.handle_mcp

なぜもう一つなのか

ほとんどの Frappe MCP サーバーは特権で実行され、モデルに生の SQL や ignore_permissions によるドキュメントアクセスを渡します。それは個人用サンドボックスでは問題ありませんが、業務システムでは受け入れられません。Synapse は逆の立場を取ります:

  • どこにも ignore_permissions はありません。 すべてのツールは呼び出し元ユーザーとして実行されます。DocType 権限、ユーザー権限、共有ルール、提出/キャンセル権限がすべて適用され、書き込みは Document.insert/save/submit/cancel を経由するため、検証、フック、ワークフローはデスクとまったく同じように発火します。

  • 権限の上に第二の境界線があります。 「このユーザーはデスクで売上請求書を編集できる」ことと「このユーザーのトークンを保持するエージェントが売上請求書を編集できる」ことは別の判断だからです。

  • すべてが記録されます。 ツールに到達する前に拒否された呼び出しも含みます。

  • 依存関係はありません。 MCP サーバーはベンダリングされているため、bench install-app がインストール全体であり、bench update は安全なままです。

Related MCP server: Frappe Assistant Core

インストール

bench get-app https://github.com/erpuae/synapse
bench --site <your-site> install-app synapse

その後、サイトの状態をいつでも確認できます:

bench --site <your-site> execute synapse.mcp_tools.check.report

何が設定されていて何が不足しているかを、修正すべき順序で出力します。新規インストールは完全に閉じています。明示的に許可するまで何も到達できません。

ツール

ツール

必要なアクション

list_available_doctypes, describe_doctype

読み取り

get_doc, get_value, get_list, get_count

読み取り

create_doc, update_doc, set_value

書き込み

submit_doc

提出

cancel_doc

キャンセル

delete_doc

削除

run_sql_query

MCP SQL Reader ロール — 下記参照

日付は MCP 設定で設定された形式で返され、デフォルトは ISO です。書き込みは ISO または DD-MM-YYYY のどちらでも受け付けるため、読み取り-変更-書き込みの往復で日と月が入れ替わることはありません。

意図的に公開していないもの: frappe.db.set_value(検証とフックをスキップする — set_value ツールは代わりにドキュメントをロードして保存します)、任意のホワイトリスト登録メソッドの実行、リネーム、修正。

4つのゲート

すべての呼び出しは4つすべてを通過します。これらは独立しており、最も狭いものが優先されます。

  1. 認証。 エンドポイントはゲストに対して閉じられているため、認証されていない POST はツールコードが実行される前にフレームワークによって拒否されます。

  2. ツールに対するロール。 ドキュメントツールには MCP Agent が必要で、SQL ツールには MCP SQL Reader が必要です。ロールがないとツールは一覧にすら表示されません。

  3. MCP アクセスリスト(MCP 設定)。許可リストまたは拒否リストです。読み取り以外の操作には、呼び出し元はサイトがそのアクションを許可したロールも保持している必要があります。

  4. Frappe 自身の権限。 上記のとおりです。

Administrator も例外ではありません。すべてのロールを保持しているためゲート2と3のロールチェックは通過しますが、DocType リストは依然として拘束されます。

アクセスモード

許可リスト — 一覧に記載された DocType のみが、チェックされたアクションごとに到達可能です。フェイルクローズドです。新しい DocType は、誰かが明示的に許可するまで到達不能のままです。これがデフォルトであり、新規インストールではリストが空なので、何も到達できません。

拒否リスト — 一覧に記載されたものを除くすべての DocType が到達可能です。ユーザー自身の Frappe 権限が実質的な境界となり、リストは、ユーザーが何をしてもエージェントが触れてはならないものを除外します。各行はデフォルトですべてをブロックします。読み取りブロックのチェックを外すと、DocType を読み取り可能のまま変更不可にできます。

拒否リストは完全な ERP では運用しやすいです。その代償として、新しい DocType は到達可能な状態で追加されるため、そのモードでは誰もリストに登録していなくても2つのセットが強制されます:

  • 決して到達不能: OAuth Bearer Token、OAuth Authorization Code、OAuth Client、Token Cache、Social Login Key、Connected App、Webhook、Email Account、Integration Request、User Social Login、Access Log。これらを読み取ることは、読み取り専用者が書き込み者になる方法です。

  • 常に読み取り専用: DocType、DocField、DocPerm、Custom DocPerm、Custom Field、Property Setter、Server Script、Client Script、Print Format、Report、Role、Has Role、User、User Permission、System Settings、Workflow、Scheduled Job Type。Custom DocPerm を編集できるエージェントは、自分自身に何でも許可できます。

許可リストモードではどちらのセットも適用されません — そこではテーブルが唯一の権威です。

子テーブルは直接到達できません。親を通じて読み書きされます。マッチングは大文字小文字を区別せず、DocType 名はリストが参照される前にサイトに対して正規化されるため、salary slip が Salary Slip という行をすり抜けることはできません。

数百のグリッド行をチェックせずに大きな許可リストを埋めるには:

bench --site <your-site> execute synapse.mcp_tools.allowlist.grant_all --kwargs "{'dry_run': 1}"
bench --site <your-site> execute synapse.mcp_tools.allowlist.grant_all
bench --site <your-site> execute synapse.mcp_tools.allowlist.show

grant_all はデフォルトで読み取り専用で、同じ2つの保護セットを適用します。すべてを到達可能にしたい場合、空のリストを持つ拒否リストモードは、700行の許可リストよりも正直にそれを示します。

セットアップ

1. OAuth。 Frappe 16 は OAuth サーバーメタデータを公開し、動的クライアント登録をサポートしています。これにより、MCP クライアントは OAuth Client レコードを手作業で作成せずに接続できます。これはデフォルトでオフです。OAuth 設定で 認証サーバーメタデータを表示、保護リソースメタデータを表示、動的クライアント登録を有効化 をオンにします。Synapse はこれらを変更しません — これらは MCP だけでなくサイト全体の OAuth 動作に影響します。

トークンが何を許可するかを明確にしてください: Frappe OAuth トークンは MCP にスコープされていません。そのユーザーとして /api サーフェス全体を認可します。

2. エージェントが代理で動作するユーザーに MCP Agent を割り当てます。 認証する人は誰でも、すべてのツールが実行されるアイデンティティです。そのため、Administrator を使用するのではなく、エージェントが見るべきものにそのユーザーをスコープしてください。

3. MCP 設定を入力します。 MCP エンドポイントを有効化 にチェックを入れ、アクセスモード を選択し、表示されるリストを入力します。この時点で読み取りは機能します。書き込みには、書き込みツールを有効化 にもチェックを入れ、ロール権限 で特定のロールにアクションを許可します。そのテーブルが空の場合、他の設定に関係なくエンドポイントは読み取り専用のままです。

クライアントの接続

claude mcp add --transport http mysite https://<your-site>/api/method/synapse.mcp.handle_mcp

その後、認証します — ブラウザがサイトのログインで開きます。Streamable HTTP と OAuth を話す MCP クライアントはどれも同じように動作します。Claude Desktop では、設定 → コネクタ → カスタムコネクタの追加で同じ URL を使用します。

生 SQL — 有効化する前にこれを読んでください

run_sql_query は Frappe の権限システムを完全にバイパスします。MCP SQL Reader を保持するユーザーは、DocType 権限に関係なくサイト上のすべてのテーブルを読み取ることができます。すでに完全なデータベースアクセスを持つユーザーにのみ許可してください。

読み取り専用 SQL ツールを有効化 にチェックが入るまでオフであり、DocType アクセスリストは使用しません — DocType を指定しないため使用できません。get_list と get_doc を優先し、SQL はそれらが表現できない結合や集計にのみ使用してください。エージェントが常に SQL に手を伸ばしている場合、ドキュメントツールに必要なものが欠けています。

背後には2つの層があります:

  1. 読み取り専用データベースユーザー。MariaDB によって強制されるため、テキストフィルターを通過したクエリでも書き込みはできません。

  2. mcp_tools/guard.py — ステートメントタイプ、コメントなし、スタックステートメントなし、キーワードブロックリスト、テーブルブロックリスト、長さ上限。テキストマッチングなので、ベルトとして扱い、サスペンダーとしては扱わないでください。

レイヤー1をサイトごとに設定します。MariaDB の root として:

CREATE USER 'mcp_ro'@'localhost' IDENTIFIED BY '<STRONG_PASSWORD>';
GRANT SELECT ON `<DB_NAME>`.* TO 'mcp_ro'@'localhost';
REVOKE FILE ON *.* FROM 'mcp_ro'@'localhost';
FLUSH PRIVILEGES;

次に site_config.json で(リポジトリには決して入れないでください):

{
  "mcp_ro_db_user": "mcp_ro",
  "mcp_ro_db_password": "<STRONG_PASSWORD>"
}

これらのキーがない場合、ツールはサイト自身の読み書き接続にフォールバックし、各クエリの後にロールバックします。 機能はしますが、ガードが唯一の境界になります。2番目のデータベースユーザーが不可能なホスト型プラットフォームでは、そのフォールバックが唯一の選択肢です — そこで SQL を有効化する前に意識的に決定してください。

サイトごとのテーブルブロックリストは、site_config.json の mcp_sql_blocked_tables で拡張します。MariaDB のみです。connection.py は他のバックエンドでは NotImplementedError を発生させます。

監査

すべての呼び出しは MCP Access Log 行を書き込みます — 成功、拒否、エラー — ツール、ユーザー、認証方法、IP、操作対象ドキュメント、行数、タイミングを含みます。書き込みは送信された値と、変更された各フィールドの変更前/変更後も記録します。ツール本体が実行される前に拒否された呼び出し(不明なツール、ロール不足、適合しない引数)も記録されます: 権限のないツールを探索するエージェントは、まさに監査証跡の目的です。

ログに完全に存在しない呼び出しは、サーバーに到達していません。 ツールがブロックされているように見えてログに何もない場合、ブロックはクライアント側、多くの場合クライアント自身のツール権限プロンプトにあります。それが最初に確認すべきことです。

行はロールバック後に独自のコミットで書き込まれるため、失敗または拒否された書き込みでも記録は残ります。System Manager による読み取りとレポートが可能で、デスクから作成や編集はできません。reference_doctype と reference_name は意図的に Link フィールドではなく Data です — 監査行が記録対象の削除をブロックしてはならないからです。日次ジョブが保持期間を過ぎた行を削除します。データ自体をログに複製してはならない場合は フィールド値の記録 のチェックを外します。パスワードのようなフィールドはどちらの場合もマスクされます。

テスト

bench --site <your-site> run-tests --app synapse

アクセスリスト、SQL ガード、ツールスキーマ、値変換は frappe から何もインポートしないため、サイトなしでも実行できます:

python -m unittest discover -s apps/synapse -p 'test_mcp_*.py'

ライセンス

GNU Affero General Public License v3.0 以降。 LICENSE を参照してください。

AGPL は意図的です: 変更した Synapse をネットワークサービスとして実行する場合、それを利用する人々はあなたの変更を受け取る権利があります。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables LLMs to interact with any ERPNext instance through comprehensive CRUD operations, advanced permissions, and a web chat interface.
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server that enables LLMs to interact with ERPNext/Frappe sites for document CRUD, search, reports, workflows, and analytics, respecting user permissions and logging all actions.
    320
    AGPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI models to securely interact with Frappe Framework/ERPNext instances, supporting document CRUD, RPC methods, file management, workflows, reporting, and more via the Model Context Protocol.
    379 npm
    ISC
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to interact with ERPNext data and functionality through the Model Context Protocol, including document CRUD, report running, and API method calls.
    MIT