Skip to main content
Glama
api-gateway-mcp

api-gateway-mcp

by novshi-tech

Heddleway

エージェントのための、チームのゲートウェイです(a team gateway for agents。名前は docs/adr/0006)。Claude から、既存のコネクタではできない API 呼び出しを行うための汎用の API ゲートウェイで、通り抜ける連絡を Murmur(チームの仕事の記憶)がスレッドとして整理します。Cloudflare Workers で動くリモート MCP サーバーとして、自分の組織の Cloudflare アカウントにデプロイします。

Claude(Cowork など)のコード実行のサンドボックスから、freee や Microsoft 365 などの API を、スクリプトで直接呼べるようになります。一覧の全件取得や集計、ファイルのダウンロード・アップロードのように、コネクタのツールでは手間のかかる作業を、Claude がスクリプトを書いて進めます。

しくみ

Claude ──MCP(OAuth でサインイン)──▶ ゲートウェイ ─┐
  │  issue_token で 15 分のトークンを受け取る       │ 認証情報を注入して中継
  ▼                                                 ▼
サンドボックスのスクリプト ──REST /api/<service>/...──▶ freee・Graph・Gmail などの API
  • Claude は認証情報を見ません。 API キーや OAuth のトークンは、ユーザーがゲートウェイの Web 画面で登録し、暗号化して保存されます。Claude が受け取るのは、寿命 15 分のゲートウェイのトークンだけです。

  • よく使うサービスは組み込みです。 freee、Microsoft Graph、Google(Gmail・Drive・Calendar・Docs・Analytics)、Slack、Jira、board、gBizINFO、Serper は src/catalog.ts にあり、OAuth のクライアントを登録すれば使えます。ほかのサービスは、デプロイの設定の SERVICES に書くか、管理画面から、ベース URL と認証方式(ヘッダーか OAuth 2.0)を書いて足します。OAuth のトークンの更新もゲートウェイが受け持ちます。

  • 使い方はスキルで配ります。 API の呼び方は、Claude のスキル(プラグイン)にまとめて配布します。コネクタの URL を含めていないので、どのデプロイでも同じプラグインを使えます。

Claude の Cowork で動作を確認しています。MCP の OAuth に従っているので、ほかの Claude のクライアントや ChatGPT のコネクタにも対応する設計ですが、まだ確認していません。設計の詳細は docs/concept.md と docs/auth-design.md にあります。

Related MCP server: Cloudflare Remote MCP Server

Murmur

murmur/ は、ゲートウェイの機能の 1 つ「チームの仕事の記憶」(Murmur)です。メールや Jira などの連絡から対応の要る件を拾い、誰の番かを追います。利用者は意識せず、Claude が裏で読んで「いまやるべきこと」に答えるための記憶です(docs/adr/0005)。

  • ゲートウェイの Worker に入っていて、デプロイの設定に Murmur の D1 を足すと有効になります(wrangler.example.jsonc の末尾)。足さなければ、ゲートウェイは Murmur なしで今までどおり動きます

  • 利用者ごとに、ゲートウェイの画面で有効にします(Claude から Murmur に接続をつなぐよう頼むと、有効にする画面に案内されます)。有効にした人の接続だけを、読み取りだけで使います。「つないだサービス」の画面でいつでも無効にできます

  • Claude からは、ほかのサービスと同じく issue_token(identity:murmur)と REST(/api/murmur/...)で使います。使い方はプラグイン heddleway の murmur スキルです

前提

  • Cloudflare のアカウント(Workers、Durable Objects、KV を使います)

  • サインインに使う IdP: Microsoft Entra ID か Google Workspace

  • Node.js 24 と npm

  • Claude のカスタムコネクタとコード実行を使えるプラン。Team / Enterprise では、組織の管理者がコード実行のネットワーク設定で、ゲートウェイのドメインを許可する必要があります。

はじめる

いちばん楽なのは、このリポジトリを Claude Code で開いて「ゲートウェイをデプロイしたい」と頼むことです。作業用のスキル(.agents/skills。.claude/skills はそこへのリンク)が、手順に沿って対話で進めます。

  • deploy: IdP へのアプリ登録、デプロイごとの設定(deployments/<名前>.jsonc)の作成、KV とシークレットの登録、デプロイ、コネクタの追加までと、設定を変えたあとの再デプロイ

  • add-service: 新しいサービスを足す。認証方式の調査、SERVICES の定義、OAuth のシークレット、サービス別のスキルの作成まで。例:「kintone の API をゲートウェイに足して」

手作業で進める場合は、下の「デプロイ」に従ってください。

使い方

ゲートウェイの Web 画面(https://<ゲートウェイ>/)にサインインし、「Claude につなぐ」(/setup)を開くと、1 と 2 に要るもの(コネクタの URL とおすすめの名前、Claude Code のコマンド、プラグインの zip)がそろっています。利用者にはこの画面を案内してください。

  1. コネクタを追加します。

    • Pro / Max: 個人の設定で、カスタムコネクタとして https://<ゲートウェイ>/mcp を追加します。

    • Team / Enterprise: Owner が組織の設定で同じ URL を追加し、各メンバーが接続します。

  2. プラグイン heddleway と、使う提供元のプラグイン(heddleway-google など)をインストールします(下の「スキル」)。「Claude につなぐ」から zip でダウンロードできます。

  3. 各ユーザーは https://<ゲートウェイ>/ にサインインし、連携先の認証情報を登録します(OAuth のサービスは「接続」)。

  4. あとは Claude に頼むだけです。Claude は list_credentials で認証情報を確かめ、issue_token でトークンを受け取り、スクリプトで REST を呼びます。

  5. 許可したアプリ(Claude、Murmur など)は、Web 画面のトップの「アクセスを許可したアプリ」に 1 回の許可ごとに出ます。「取り消す」で、そのアプリのアクセストークンとリフレッシュトークンが使えなくなります。

複数の組織で使う

ゲートウェイは 1 つのデプロイが 1 つの組織です(ADR 0004)。複数の組織で仕事をするなら、組織ごとにデプロイし、それぞれを別のコネクタとして Claude に並べてつなぎます。

  • コネクタには組織が分かる名前を付けます(「Acme Gateway」など)。ゲートウェイも、設定の ORGANIZATION_NAME を Claude と Web 画面に名乗ります。スキルはコネクタが複数あることを前提に書かれていて、作業する組織のコネクタを選びます。

  • 1 人がつなげるアカウントは、1 つのサービスにつき 1 つです。別の組織のアカウントは、その組織のゲートウェイでつなぎます。アカウントを替えるときは、OAuth のサービスはつなぎ直し、API キーのサービスは削除してから追加します。以前につないだ 2 つ目以降の接続は使えるまま残り、画面に「使わないほうを削除してください」と出ます。

  • コネクタを通ったデータは、そのコネクタをつないだ Claude のアカウントに入ります。どの Claude にどのゲートウェイをつなぐかは、使う側が決めます。組織が契約している Claude(Team / Enterprise)には、その組織のゲートウェイだけをつなぐのがおすすめです。

curl -H "Authorization: Bearer $TOKEN" "https://<ゲートウェイ>/api/freee/api/1/companies"

スキル

このリポジトリは Claude のプラグインのマーケットプレイスを兼ねています。共通の heddleway を入れ、使う提供元のプラグインを足します。Microsoft 365 だけ、Google だけ、という使い方ができます。

プラグイン

スキル

サービス名

できること

heddleway(必須)

heddleway

—

トークンの発行と、REST の呼び出し(gw_request.py)の共通手順。ほかのスキルはこれを前提にする

board

board

販売管理 SaaS「board」の案件・見積・請求・発注・支払・顧客などの検索・登録・更新

gbizinfo

gbizinfo

経済産業省の法人情報(gBizINFO)の検索

serper

serper

Serper 経由の Google 検索(ウェブ・画像・ニュース・地図・論文など)

murmur

murmur

Murmur(チームの仕事の記憶。このゲートウェイの機能)のスレッド・誰の番・個人のメモでのタスクの追跡・送信の記録。有効にする手順は上の「Murmur」

heddleway-microsoft

microsoft-graph

graph

Outlook メール、OneDrive / SharePoint、Teams、予定表

heddleway-google

gmail

gmail

メールの検索・送信・返信・下書き、添付ファイル

google-drive

drive

ファイルの検索・ダウンロード・エクスポート・アップロード、共有ドライブ

google-calendar

calendar

予定の検索・作成・更新、空き時間の確認

google-docs

docs

ドキュメントの本文の読み取り、作成、追記・置換・書式の編集

google-analytics

analytics・analytics-admin

GA4 のレポート取得、アカウントとプロパティの参照(読み取り専用)

heddleway-freee

freee

freee

会計・人事労務・請求書・販売の API

heddleway-slack

slack

slack

チャンネル・DM の履歴とスレッド、検索、投稿・返信、リアクション(ユーザー本人として)

heddleway-atlassian

jira

jira

Jira Cloud の課題の検索・作成・更新、コメント、遷移、担当者

インストールの方法:

  • Claude Code: /plugin marketplace add novshi-tech/heddleway のあと、/plugin install heddleway@heddleway と、使う提供元のもの(例: /plugin install heddleway-microsoft@heddleway)をインストールします。提供元のプラグインは heddleway に依存しているので、先に入れていなくても一緒に入ります。

  • Pro / Max: Customize > Plugins > Add marketplace で novshi-tech/heddleway を追加し、heddleway と使う提供元のプラグインをインストールします。

  • Team / Enterprise: Owner が Organization settings > Plugins & skills で、このリポジトリ(または、これを参照する社内のマーケットプレイス用リポジトリ)を同期し、配布方法を選びます。

  • zip: npm run plugin:zip で dist/<プラグイン>-<version>.zip をプラグインごとに作り、Plugins の Upload plugin で追加します。更新するときは plugin.json と .claude-plugin/marketplace.json の version を上げて作り直し、同じ名前でアップロードし直します。Cowork で GitHub のマーケットプレイスの同期がうまくいかないときは、zip を使ってください。

  • ゲートウェイの Web 画面: 「Claude につなぐ」(/setup)に、このリポジトリのプラグインの zip が並び、サインインした人がダウンロードできます。npm run deploy が tools/build-plugin-zip.py --bundle で zip を dist/plugins.js に書き出し、Worker 本体に同梱してデプロイするので、いつもそのゲートウェイの版のものです。静的アセットにしないのは、アセットのアップロードがアップロードごとのトークンを Authorization で送るためで、Cloudflare の API トークンを差し込むプロキシ(Claude Code のクラウドのセッションなど)の下ではデプロイが失敗するからです。ほかのプラグイン(自社のサービスのスキルなど)は、管理者が「プラグインの配布」(/admin/plugins)で zip を追加すると、同じ画面に並びます(下の「管理画面から接続先を足す」)。

2026-11-05 に、プラグインの名前を api-gateway* から heddleway* に変えました(docs/adr/0006)。前の名前のプラグインを入れている人は、入れ直してください。

  1. 前のプラグイン(api-gateway と api-gateway-<提供元>)をアンインストールします。並べて入れておくと、同じスキルが 2 つ出ます

  2. 新しいプラグイン(heddleway と、使う提供元の heddleway-<提供元>)をインストールします。Claude アプリでは「Claude につなぐ」から zip をダウンロードしてアップロードし、Claude Code では /plugin marketplace remove api-gateway-mcp のあと、上の手順でマーケットプレイス novshi-tech/heddleway を足し直します

  3. ほかのマーケットプレイスの、api-gateway に依存するプラグインは、依存を heddleway に変えた版に上げます

コネクタ(MCP の URL)は変わらないので、つなぎ直しは要りません。

以前の版の api-gateway(0.11 まで)は、全部のスキルが 1 つに入っていました。0.12 からは、使う提供元のプラグインを足します。

スキルのスクリプトが使う共通のファイル(gwlib.py、gw_request.py、google_paging.py)の原本は lib/plugin/ にあります。Claude Code はプラグインごとに別の場所にインストールし、Cowork はスキルのディレクトリを <プラグイン>:<スキル> と名付けるので、スキルからほかのスキルのファイルには届きません。そのため、各スキルの scripts/ にコピーを置いています。原本を変えたら npm run plugin:sync でコピーを更新します(テストがずれを検出します)。

ほかのサービスのスキルは、自分のプラグインに作って足します(add-service スキル)。業務に寄ったサービスのスキルは、このリポジトリに入れず、別のプラグインに分けて運用するのがおすすめです。そのスキルにも gwlib.py と gw_request.py のコピーを同梱してください。

デプロイ

1. IdP にアプリを登録する

ゲートウェイへのサインインに使うアプリを登録し、リダイレクト URI を 2 つ設定します。

  • https://<ゲートウェイ>/oauth/callback(MCP クライアントの接続)

  • https://<ゲートウェイ>/login/callback(Web 画面のサインイン)

アプリは、その組織の中だけで使える形で登録します(1 つのデプロイ = 1 つの組織)。Entra ID はシングルテナントのアプリとして登録し、OIDC_ISSUER を https://login.microsoftonline.com/<tenant-id>/v2.0 にします。Google は、Workspace のドメインを ALLOWED_DOMAINS に必ず指定します(空だと、どの Google アカウントでもサインインできてしまいます)。

2. 設定してデプロイする

デプロイ先ごとに、設定を deployments/<名前>.jsonc に置きます。名前は自由に付けてよく、1 つの clone で複数のデプロイを扱えます。deployments/ はこのリポジトリの git の管理外です。設定は、デプロイする人の private リポジトリで管理し、deployments/ に clone して使うのがおすすめです(下の「設定をリポジトリで管理する」)。wrangler.example.jsonc をコピーし、$schema と main のパスの先頭に ../ を付けます。Worker の name はデプロイごとに変え(すでに動いているデプロイの name は変えません。Durable Object の保管庫が Worker の名前に結びついているので、変えると登録済みの認証情報が見えなくなります。docs/adr/0006)、別の Cloudflare アカウントなら account_id も書きます。vars に PUBLIC_URL、組織名(ORGANIZATION_NAME)、IdP の設定を書きます。Microsoft Graph を使うなら MICROSOFT_TENANT_ID も書きます。組み込みにないサービスは SERVICES に足します。KV ネームスペースを作って、ID を kv_namespaces に設定します。

wrangler は、npm run deploy / npm run secret / npm run tail に名前を付けて呼びます(tools/wrangler.mjs が --config deployments/<名前>.jsonc を渡します)。リポジトリの直下には wrangler.jsonc を置かないので、名前を付けずに npx wrangler deploy を打っても、どこにもデプロイされません。

npm ci
mkdir -p deployments   # 設定をリポジトリで管理するなら、代わりに git clone <設定のリポジトリ> deployments
sed -e 's|"node_modules/|"../node_modules/|' -e 's|"src/index.ts"|"../src/index.ts"|' wrangler.example.jsonc > deployments/acme.jsonc
npx wrangler login
npx wrangler kv namespace create OAUTH_KV
npm run secret -- acme put OIDC_CLIENT_SECRET
openssl rand -base64 32 | npm run secret -- acme put SIGNING_KEY
openssl rand -base64 32 | npm run secret -- acme put ENCRYPTION_KEY
npm run deploy -- acme
  • ENCRYPTION_KEY を変えると、登録済みの認証情報は復号できなくなります。

  • SIGNING_KEY を変えると、発行済みのトークンと MCP の接続が無効になり、ユーザーは接続し直しになります。

  • IDENTITY_SIGNING_KEY を変えると、identity の上流が古い公開鍵をキャッシュしている間は検証に失敗します。上流が JWKS を取り直すまで待つか、上流の公開鍵を差し替えます。

  • 以前の版で設定に足した assets("directory": "../dist/assets")は、もう使いません。消してください。

  • 設定を変えたら、npm run deploy -- <名前> で出し直します。設定をリポジトリで管理しているなら、コミットしてプッシュもします。

  • 新しい版で Durable Object やその migration が増えたときは(wrangler.example.jsonc の durable_objects と migrations)、各デプロイの設定にも同じものを足してから出し直します。deploy スキルが照らし合わせて直します。

設定をリポジトリで管理する

deployments/ は、このリポジトリの git が見ないディレクトリです。そこに、設定だけを入れた別の private リポジトリを clone します(サブモジュールにはしません)。

git clone git@github.com:<組織>/heddleway-deployments.git deployments
  • 設定ファイルの main などの相対パス(../src/index.ts)は、deployments/ の中にあるので、そのまま動きます。tools/wrangler.mjs も変わりません。

  • 入れるのは <名前>.jsonc だけです。Worker の名前、account_id、PUBLIC_URL、ORGANIZATION_NAME、IdP の設定、KV の ID、SERVICES が入ります。秘密の値ではありませんが、テナント ID なども入るので、リポジトリは private にします。

  • シークレット(OIDC_CLIENT_SECRET、SIGNING_KEY、ENCRYPTION_KEY、OAUTH_*)は入れません。npm run secret で Cloudflare に入れるだけで、ファイルには残しません。

  • 別のマシンや新しい clone でデプロイするときは、ゲートウェイを clone したあと、同じように設定のリポジトリを deployments/ に clone します。

3. 連携先を設定する

ヘッダーで認証するサービス(組み込みの board・gbizinfo・serper など)は、設定は要りません。ユーザーが Web 画面で API キーやトークンを登録します。

Basic 認証のサービス(auth.type が basic)は、ユーザーが Web 画面でユーザー名とパスワードを登録し、ゲートウェイが Authorization: Basic … を組み立てて送ります。ユーザー名が決まっている上流は username に書くと、ユーザーはパスワードだけを入れます。git の smart HTTP もこれで中継できます(docs/adr/0002)。

"github-git": {
  "display_name": "GitHub(git)",
  "base_url": "https://github.com",
  "auth": { "type": "basic", "username": "x-access-token", "password_label": "GitHub の personal access token" }
}
git -c http.extraHeader="Authorization: Bearer $GW_TOKEN" clone https://<ゲートウェイ>/api/github-git/<owner>/<repo>.git

Claude からは、組み込みのプラグイン heddleway の git スキルが、トークンを .git/config に残さずに git を呼びます。

OAuth 2.0 のサービス(auth.type が oauth2)は、Web 画面から認可コード + PKCE で接続します。連携先にアプリを登録し、コールバック URL に https://<ゲートウェイ>/connect/callback を指定します。クライアント ID とシークレットは、クライアントの名前を大文字にした名前で登録します(ハイフンは _ に)。組み込みのサービスのクライアントは FREEE・GOOGLE・MICROSOFT の 3 つで、Google の 6 つのサービスは 1 組を共有します。SERVICES に足したサービスは、auth.client に書いた名前か、なければサービス名がクライアントの名前です。

npm run secret -- <名前> put OAUTH_<CLIENT>_CLIENT_ID
npm run secret -- <名前> put OAUTH_<CLIENT>_CLIENT_SECRET

クライアントが登録されていない OAuth のサービスは、Web 画面にも list_credentials にも出ません。以前のサービスごとの名前(OAUTH_GMAIL_CLIENT_ID など)は読まなくなったので、古いデプロイでは OAUTH_GOOGLE_* / OAUTH_MICROSOFT_* を登録し直してください。

アクセストークンは、期限の 1 分前からゲートウェイがリフレッシュします。リフレッシュトークンが失効したら、Web 画面に「再接続」が出ます。

管理画面から接続先を足す

デプロイの設定の ADMINS にユーザー ID をカンマ区切りで書くと、その人の画面に「接続先の管理」が出ます。ユーザー ID は、Web 画面のトップの一番下にある「アカウントの情報」を開くと表示されます(Entra は entra_<テナント ID>_<オブジェクト ID>、Google は google_<sub>)。

同じ人の画面には「プラグインの配布」も出ます。プラグインの zip(.claude-plugin/plugin.json を含むもの、2 MB まで)を追加すると、全員の「Claude につなぐ」からダウンロードできるようになります。名前と版は zip の中の plugin.json から読み、同じ名前で追加し直すと置き換わります。組み込みのプラグインと同じ名前は使えません。zip は Durable Object(Registry)に保管します。

管理画面で足した接続先(ヘッダー、Basic 認証、OAuth 2.0)は、デプロイし直さなくても、全員の「接続を追加」に出ます(反映まで最大 30 秒)。定義は Durable Object(Registry)に、OAuth のクライアントシークレットは暗号化して保管します。組み込みと同じ名前は使えず、SERVICES に同じ名前があれば SERVICES が勝ちます。ベース URL のホストやトークンの URL、クライアント ID を変えると、その接続先の既存の接続は使えなくなり、利用者はつなぎ直すことになります(鍵が新しい向き先に送られないようにするため)。

ゲートウェイのサインインを信頼する自社の API(auth.type が identity)は、ユーザーが何も登録しません。ゲートウェイがサインイン中のユーザーの ID(sub)を Ed25519 で署名し、Authorization: Bearer <JWT> として送ります。JWT は iss がゲートウェイの URL、aud が設定の audience、寿命は 5 分です。上流は https://<ゲートウェイ>/.well-known/jwks.json の公開鍵で検証します。Claude からは、list_credentials に identity:<サービス名> という認証情報として見えます。

"murmur": {
  "display_name": "Murmur",
  "base_url": "https://murmur.internal/api",
  // 公開ルートを持たない Worker には、Service Binding で中継する
  "binding": "MURMUR",
  "auth": { "type": "identity", "audience": "murmur" }
}
# 署名鍵(Ed25519 の秘密鍵の JWK)を作って登録する
node -e "crypto.subtle.generateKey({name:'Ed25519'},true,['sign','verify']).then(k=>crypto.subtle.exportKey('jwk',k.privateKey)).then(j=>console.log(JSON.stringify(j)))" | npm run secret -- <名前> put IDENTITY_SIGNING_KEY

binding を書いたサービスは、公開のインターネットではなく、デプロイの設定の services に書いた Service Binding({ "binding": "MURMUR", "service": "murmur" })で上流を呼びます。base_url のホスト名は使われず、パスだけが意味を持ちます。

人がいないときに Worker が使う接続先(client_credentials)

Murmur のように、夜中の通知や定期の見回りでユーザーがいないときにも上流を呼ぶ Worker のために、OAuth 2.0 の client credentials でゲートウェイ自身がトークンを取る接続先を置けます(設計は docs/background-access.md)。持ち主はユーザーではなくデプロイで、Web 画面にも list_credentials にも出ず、REST(/api/)からも使えません。

  • 管理画面の「接続先を追加」で認証方式に「OAuth 2.0(client credentials)」を選び、トークンの URL・スコープ・クライアント ID・シークレットを入れます。設定ファイルに書くこともできます(クライアントは OAUTH_<CLIENT>_CLIENT_ID / _CLIENT_SECRET)。

  • 呼べるのは、同じ Cloudflare アカウントの Worker が名前付きのエントリポイント Background に張った Service Binding からだけです。名前付きのエントリポイントはインターネットに出ないので、呼び出し元との間のシークレットは要りません。そのアカウントに Worker をデプロイできる人は使える、という信頼の置き方です。

  • パスは /<サービス名>/<上流のパス>(/api は付けない)。ヘッダーの扱いとリダイレクトは REST と同じです。

  • アクセストークンは期限の 1 分前まで Worker のメモリで使い回し、保管しません。

  • 上流のアプリの権限は、読ませるものだけに絞ってください。Microsoft Graph で共有メールボックスを読ませるなら、下の手順で Exchange の RBAC for Applications を使います。

Microsoft Graph で共有メールボックスだけを読ませる手順(テナントの管理者):

  1. Entra 管理センターの「アプリの登録」でアプリを登録し(シングルテナント、リダイレクト URI なし)、クライアント シークレットを作ります。クライアント ID と、「エンタープライズ アプリケーション」の側のオブジェクト ID を控えます。

  2. 「API のアクセス許可」には何も足しません。 Entra で Mail.Read などのアプリの権限に管理者の同意をすると、テナントの全員の箱に届き、Exchange のスコープでは絞れなくなります。

  3. Exchange Online の PowerShell で、権限をスコープ付きで渡します。

Connect-ExchangeOnline
New-ServicePrincipal -AppId <クライアント ID> -ObjectId <エンタープライズ アプリのオブジェクト ID> -DisplayName "<名前>"
Set-Mailbox shared@example.com -CustomAttribute15 "gateway-app"   # 読ませる箱ごとに
New-ManagementScope -Name "<スコープ名>" -RecipientRestrictionFilter "CustomAttribute15 -eq 'gateway-app'"
New-ManagementRoleAssignment -App <クライアント ID> -Role "Application Mail.Read" -CustomResourceScope "<スコープ名>"
Test-ServicePrincipalAuthorization -Identity <クライアント ID> -Resource shared@example.com   # InScope が True になる

反映には時間がかかることがあります。読ませる箱を増やすときは、その箱に同じ印を付けるだけです。詳しくは Role Based Access Control for Applications in Exchange Online。

"graph-app": {
  "display_name": "Microsoft Graph(アプリ)",
  "provider": "Microsoft",
  "base_url": "https://graph.microsoft.com",
  "auth": {
    "type": "client_credentials",
    "client": "murmur-app",
    "token_url": "https://login.microsoftonline.com/<テナント ID>/oauth2/v2.0/token",
    "scope": "https://graph.microsoft.com/.default"
  }
}
// 呼び出す側(Murmur)の wrangler の設定
"services": [{ "binding": "GATEWAY", "service": "<ゲートウェイの Worker 名>", "entrypoint": "Background" }]
// コード: await env.GATEWAY.fetch("https://gateway/graph-app/v1.0/users/shared@example.com/mailFolders/inbox/messages/delta")

freee(freee)

freee のアプリ管理でアプリを作成し、コールバック URL を設定します。シークレットは OAUTH_FREEE_CLIENT_ID / OAUTH_FREEE_CLIENT_SECRET です。

Microsoft Graph(graph)

サインイン用とは別の Entra アプリを登録します。プラットフォームは「Web」で、src/catalog.ts の GRAPH_SCOPE にある委任のアクセス許可を付けて、管理者の同意を与えます。GRAPH_SCOPE に許可が増えたとき(例: Murmur の Teams のための ChannelMember.Read.All)は、Entra のアプリにも足して管理者の同意をやり直し、利用者は「つないだサービス」で Microsoft Graph をつなぎ直します。デプロイの設定の MICROSOFT_TENANT_ID にテナント ID を書きます。シークレットは OAUTH_MICROSOFT_CLIENT_ID / OAUTH_MICROSOFT_CLIENT_SECRET です。

Google(gmail・drive・calendar・docs・analytics・analytics-admin)

Google Cloud のプロジェクトで、Gmail API、Google Drive API、Google Calendar API、Google Docs API、Google Analytics Data API、Google Analytics Admin API のうち使うものを有効にし、OAuth クライアントを「ウェブ アプリケーション」として作成します。OAuth 同意画面のユーザーの種類は、Workspace の「内部」にします(別の組織のアカウントはつなげなくなります。別の組織はその組織のゲートウェイで)。承認済みのリダイレクト URI に https://<ゲートウェイ>/connect/callback を登録し、OAuth 同意画面に src/catalog.ts のスコープを追加します。6 つのサービスで 1 つの OAuth クライアントを共有します。

npm run secret -- <名前> put OAUTH_GOOGLE_CLIENT_ID
npm run secret -- <名前> put OAUTH_GOOGLE_CLIENT_SECRET
  • スコープ: Gmail の gmail.modify はメールの読み書きと送信、Drive の drive は既存のファイルを含む全ファイルの閲覧と管理、Calendar の 3 つは予定の読み書き、カレンダー一覧の参照、空き時間の参照、Docs の documents はドキュメントの本文の読み書き、Analytics の analytics.readonly は GA4 のレポートとプロパティの読み取りに使います(Data API と Admin API はホストが別なので、サービスも 2 つに分けています)。読み取り専用にするなら、SERVICES に同じ名前でサービスを書いて、スコープを gmail.readonly / drive.readonly / documents.readonly などに変えます。詳細は Gmail、Drive、Calendar、Docs の公式ドキュメントにあります。

  • authorize_params の access_type: offline と prompt: consent は、リフレッシュトークンを受け取るための設定です。

  • REST の呼び出し先の例: /api/gmail/gmail/v1/users/me/messages、/api/drive/drive/v3/files(アップロードは /api/drive/upload/drive/v3/files)、/api/calendar/calendar/v3/calendars/primary/events、/api/docs/v1/documents/{id}、/api/analytics/v1beta/properties/{id}:runReport、/api/analytics-admin/v1beta/accountSummaries

Slack(slack)

api.slack.com/apps でアプリを作成し(配布しないなら、使うワークスペースにだけ)、OAuth & Permissions で次を設定します。

  • Redirect URLs に https://<ゲートウェイ>/connect/callback を追加します。

  • User Token Scopes に、src/catalog.ts の SLACK_USER_SCOPE を追加します(Bot Token Scopes は要りません)。ゲートウェイはユーザートークン(xoxp-)を受け取り、API はつないだ本人として動きます。

シークレットは OAUTH_SLACK_CLIENT_ID / OAUTH_SLACK_CLIENT_SECRET(Basic Information の Client ID と Client Secret)です。ワークスペースの設定でアプリの承認が要る場合は、管理者に承認してもらいます。Token Rotation は有効にしてもしなくても動きます(有効にすると、12 時間で切れるトークンをゲートウェイが更新します)。

  • REST の呼び出し先の例: /api/slack/conversations.history?channel=C0123、/api/slack/chat.postMessage

Jira(jira)

developer.atlassian.com/console/myapps で OAuth 2.0 integration のアプリを作成し、次を設定します。

  • Permissions で Jira API を追加し、src/catalog.ts の JIRA_SCOPE にあるスコープ(read:jira-work・write:jira-work・read:jira-user・manage:jira-webhook)を付けます。User identity API も追加して read:me を付けます。

  • Authorization の Callback URL に https://<ゲートウェイ>/connect/callback を設定します。

  • 社外に配布しないなら、Distribution は「Not sharing」のままで構いません(アプリの所有者のサイトにつなげます)。

シークレットは OAUTH_ATLASSIAN_CLIENT_ID / OAUTH_ATLASSIAN_CLIENT_SECRET(Settings の Client ID と Secret)です。リフレッシュトークンは使うたびに替わり、90 日使わないと切れます(切れたら Web 画面でつなぎ直します)。

  • 上流は https://api.atlassian.com です。Jira の API はサイトごとに /ex/jira/<cloudid>/rest/api/3/... の下にあり、クラウド ID は /oauth/token/accessible-resources で調べます。

  • REST の呼び出し先の例: /api/jira/oauth/token/accessible-resources、/api/jira/ex/jira/<cloudid>/rest/api/3/search/jql

board(board)

board の API 設定で API キーと API トークンを発行し、ユーザーが Web 画面で登録します。ゲートウェイは API キーを x-api-key ヘッダー、トークンを Authorization: Bearer で送ります。トークンごとに使えるエンドポイントが決まっているので、使う API の権限を付けて発行します。

gBizINFO(gbizinfo)

gBizINFO の Web API 利用申請で API トークンを取得し、ユーザーが Web 画面で登録します。ゲートウェイは X-hojinInfo-api-token ヘッダーで送ります。

Serper(serper)

serper.dev のダッシュボードで API キーを発行し、ユーザーが Web 画面で登録します。ゲートウェイは X-API-KEY ヘッダーで送ります。ページの本文取得(scrape.serper.dev)はホストが別なので、このサービスでは扱いません。

注意

  • スクリプトから直接 HTTP を送るときは、User-Agent を明示してください。Python の urllib の既定値などは、Cloudflare に Error 1010 で拒否されることがあります(付属のスクリプトは設定済み)。

  • 調べるときは npm run tail -- <名前> --format json でログを流します。ゲートウェイは、中継したリクエストごとに、ユーザー・サービス・パス・ステータスの監査ログを出します。

開発

npm install
cp .dev.vars.example .dev.vars   # 値を埋める
npm run dev       # wrangler.example.jsonc で動かす
npm run typecheck
npm test          # Worker のテストと、スキルのスクリプトのテスト

Murmur は murmur/ の中で別のパッケージになっています。ルートの npm install が murmur/ の依存も入れます(Worker が Murmur を一緒にバンドルするため)。Murmur のテストは cd murmur && npm test(詳しくは murmur/CLAUDE.md)。

License

MIT.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A Cloudflare Workers-based implementation of Model Context Protocol (MCP) server with OAuth login that allows tools like Claude to access external capabilities.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables users to deploy and host a remote MCP server on Cloudflare Workers without requiring authentication, and connect it to clients like Cloudflare AI Playground and Claude Desktop for using custom MCP tools.
    -