自分用のDesklyにRemote MCPとOAuthを付け、Cloudflare Workers上の入口をClaude Codeから読み書きできるところまで進めました。つまずいたのは、同意のボタンと、直したはずの道具をスマホが古いまま覚えていたことです。
https://code.claude.com/docs/en/mcp
※ 2026年10月11日時点の、10月10日から11日にかけての作業記録です。製品の画面や動きは変わりうるため、確認できたアプリと操作を分けて書きます。
作ったのは本人の名義で案件を読み書きする入口です。書き込みの見本と適用を分け、接続を確かめながら進めました。書き込みの承認はアプリ側の設定にかかるので、確かめた範囲は分けて書きます。
自分の案件を、AIアプリから触れるようにしたい
Desklyは、自分用の案件ダッシュボードです。案件と、その節目になるマイルストーン、個々の作業を、AIアプリから本人の名義で読み書きできるようにするのが今回の目的でした。
MCPは、AIアプリと外部のデータや道具をつなぐための共通の決まりです。今回はネットワーク越しに呼び出すRemote MCPとして入口を用意しました。公式の説明にも外部システムとの接続が挙げられています。
https://modelcontextprotocol.io/docs/2026-07-28/getting-started/intro
入口を置いたCloudflare Workersは、サーバーの管理を自分で抱えずに処理を動かせる実行基盤です。既存のダッシュボードに、AIアプリ向けの読み書きの経路を加えました。
https://developers.cloudflare.com/workers/
OAuthは、利用者がアプリに操作の範囲を許可するための仕組みです。今回は誰でも使える入口にはせず、持ち主である自分だけが接続し、アプリごとに読むだけか、書くところまでかを選ぶ形にしました。
https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization
もともと機械用の読み取り経路はありましたが、見える範囲を絞った別の主体です。その主体に書き込みまで許すのではなく、本人として接続する経路を新しく分けました。
書く前に、見本を挟めるだろうか
守りたかったのは、書き込みを見本と適用に分けること、変更の履歴に誰がどのアプリから書いたかを残すこと、使う人を本人に限ることです。機械の読み取り経路は、引き続き読むだけにしました。
本人が許可したAIアプリはWorkerの入口を通って台帳へ進みます。機械の読み取り専用の主体は別に扱い、書き込みの権限を広げません。
道具は6つにしました。案件、マイルストーン、作業、履歴を読む4つと、書き込み用の見本を作る道具、見本を適用する道具です。連絡や受付、外部サービスへの書き込みは今回の対象にしていません。
deskly_previewは変更の見本を作るだけで、保存しません。deskly_applyに、その見本と署名付きの情報を改変せずに渡して適用します。期限や対象、見本を作ったアプリとの結び付きも確認する作りにしました。
人が書き込みを確認する場面は、AIアプリ側のツール承認にあります。ただ、今回の1件の書き込みで承認の画面が出たかどうかは、記録に残っていません。サーバーは見本の改変や対象の違いなどを確かめますが、人が画面で承認したことまでは証明できません。
ここは言い切れないところです。consent:trueはAIが送る引数なので、それだけで「本人が承認した証拠」にはなりません。接続時の「書くまで許可」と、個々の書き込みを人が確認する設定は、分けて考える必要がありました。
claude.aiの本人の設定画面では、適用の道具は「承認が必要」でした。ただし、実際の書き込み時の承認画面や、道具の注記の反映は未確認です。サーバー側の見本の検査と、アプリ側で人が確認することは、同じ保証としては扱いません。
https://claude.ai/
履歴には、MCP経由の変更であることと、許可を受けたアプリの登録に結び付く情報を残します。アプリが自分で名乗った表示名は「自己申告」と添えました。名前が出るだけで、その製品の正規のアプリだと確かめたことにはならないためです。
接続の許可を、どこで受け付けるか
認証まわりでは、Cloudflare Accessの機能を使う案と、WorkerにOAuthの受付を内蔵する案を比べました。Accessは、ブラウザで本人を確認するために既に使っていた入口の門です。
https://developers.cloudflare.com/cloudflare-one/access-controls/
記録にある比較では、前者は新しい依存や保管場所を増やさずに済む案でした。ただ、アプリの区別や個別の取り消しをどう扱えるかに未確認が残っていました。今回は、後者の内蔵する案を選びました。
選んだ理由は4つです。どのアプリからの変更かを履歴で分かるようにすること、読む範囲と書く範囲を分けること、接続を1つだけ止められること、発行する鍵をMCPの道具だけに効かせることでした。
同意画面は、アプリに何を許可するかを本人が選ぶ画面です。読むだけ、書くところまで、拒否する、の選択肢を置きました。自分で接続を始めたときだけ許可するよう注意を出し、求める範囲と戻り先、アプリの自己申告名を見られるようにしています。
アプリの登録にはDCRを使いました。これはOAuthの利用アプリを動的に登録する仕組みです。自分の環境では、自動登録する設定で接続を確認しました。
https://www.rfc-editor.org/info/rfc7591/
なお、確認した現行のMCP仕様では、DCRは後方互換のために残された方式として扱われています。今回のDesklyは、別方式のClient ID Metadata Documentsには対応していません。この記事は、その状態で接続した記録です。
https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization
本人のログインと同意は、本人が画面で行います。一方、アプリが機械的に通信するための受付口は、ブラウザ向けの門の外に置きました。画面や既存のAPIまで広く除外する形にはしていません。
作る作業と確かめる作業を、どう分けたか
作業は、まず読み書きの道具と伝送部分を作り、その後にOAuthの受付、同意画面、接続中のアプリの一覧と取り消し、履歴の表示を加える順でした。読み書きの中身と接続の許可を、一度に作り切る進め方にはしませんでした。
AIの使い方も分けました。手元のセッションは統合や実機の接続確認を進め、クラウドのセッションには文書の作成と、壊れる条件を探すレビューを依頼しました。記録上、クラウドはpush済みのコードを扱い、手元の秘密や配置先の操作は任せていません。
レビューで出た指摘の修正や、文書とコードの突き合わせには、指示を渡して結果を受け取るclaude -pも使いました。配置は別の担当が手順に沿って進め、方式の選択やpush、配置、取り消しは本人が確認しています。
https://code.claude.com/docs/en/headless
レビューを一度通せば終わり、とはなりませんでした。手元でのレビュー、クラウドでのレビュー、修正後のレビューで、それぞれ重大な指摘が出ています。登録の枠を分ける修正や、使われた登録を消さない修正も、その往復で入りました。
試験が通った状態で実機へ進んでも、あとで同意の画面と道具の定義で止まりました。コードの試験、実際のブラウザの送信、AIアプリが受け取っている定義は、それぞれ確かめる必要がありました。
Claude Codeでは、どこまで読み書きできたか
10月11日の朝、Claude CodeにHTTPのMCPとして追加しました。公式DocsにもHTTPのリモートサーバーの追加と認証の手順がありますが、ここから先は自分の環境の結果です。
https://code.claude.com/docs/en/mcp
ログインは最初から通ったわけではありません。stateのエラー、続いてPKCEのエラーで失敗しました。PKCEは、認可を始めたアプリとコードを交換するアプリを結び付け、認可コードの横取りを防ぐための仕組みです。
https://www.rfc-editor.org/info/rfc7636/
記録では、ログイン用のURLを手で写した際に、戻ってきたstateへ空白が混ざっていました。PKCE側にも同じような混入があった可能性はありますが、そこは未確認です。URLを既定のブラウザで直接開き、本人が許可すると接続できました。
読み取りでは、案件の一覧と作業を取得し、画面から貼った1件の詳細と全項目が一致しました。書き込みは、自分が「YES」と答えた後に検証用の作業を1件作り、履歴を確認しました。
画面には「AI アプリ(MCP 経由)」と「Claude Code(自己申告)」が出ました。確認できた書き込みは、この1件です。Webやスマホからも書けたことにはしていません。
https://code.claude.com/docs/en/mcp
接続の取り消しも試しました。許可を得た手元のAIが取り消しを実行し、その後の呼び出しと鍵の更新が拒否された記録があります。ただし、別の地域への反映までは測っていないので、取り消せば必ず即座に止まるとは言えません。
同意のボタンを押しただけなのに、403になった
朝の接続確認より前に、同意画面で止まっています。「書くまで許可」を押すと、画面には {"error":"forbidden"} と表示されました。拒否を表す403の応答です。
本人が同じ画面のボタンを押していても、サーバーの照合で止まりました。画面の設定と、ブラウザが実際に送った情報の組み合わせを調べました。
同意画面では、アプリが求める範囲や戻り先を見て許可します。ここで起きた失敗は、許可の選択後にブラウザが送る要求にありました。
調べると、Originヘッダーがnullでした。Originは、要求の送り元のオリジンを伝える情報で、方式、ホスト、ポートから成ります。今回の照合は、自分の画面からの送信かをそこでも確認していました。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Origin
原因は、画面に付けていたReferrer-Policyでした。これは送信時に参照元の情報をどこまで付けるかを決める設定で、今回のフォーム送信ではno-referrerがOriginにも影響していました。MDNにも、この条件でOriginがnullになる説明があります。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referrer-Policy
修正は、画面の方をsame-originにすることでした。転送の応答の設定はそのままにしています。照合を外して通す方向にはせず、ブラウザが送る情報を修正前後で確かめました。
試験ではヘッダーを手で組み立てていたため、この動きを見逃していました。修正後は、画面を表示せずに動くheadless Chromeで実際に描画したボタンを押し、Originを比べています。画面が表示されるかに加えて、押したときに何が出ていくかを見る確認になりました。
https://developer.chrome.com/docs/chromium/headless
直したのに、スマホがまだIDを聞いてくる
次はスマホです。案件の一覧を頼むと、コネクタは使えるのに、ワークスペースIDが必要だと聞かれて止まりました。道具の定義を見ると、6つともworkspaceが必須でした。
接続先は決まっていても、道具の必須引数を埋められず一覧を取得できませんでした。アプリには、そのIDを調べるための道具もありませんでした。
接続は既に1つのワークスペースに結び付いています。そこでworkspaceを省略できるようにし、省略時は接続先の値を使う形へ直しました。明示された値が違う場合の検査と、見本を対象へ結び付ける仕組みは残しています。
配置した後も、スマホは同じIDを求めました。直す、試す、まだ止まる、を繰り返したところで、自分から手元のAIへこう伝えています。
「あの そもそもさこんなのさ あの直してできました だめですっての繰り返すぐらいだったら全部ログみりゃいいんじゃねえの ログ 仕込み だよ」
サーバーに要求が届いているかを見られるようにすると、調べる場所を絞れました。本文や秘密の値を並べず、道具名や引数の名前、結果などの形を記録しました。
そのうえで、記録を取る仕組み自体が動くことを確かめてから、もう一度試しました。PCのclaude.aiで頼んだ間、サーバーへの要求は0件でした。新しいチャットにしても取り直されず、接続したときの古い定義を使い続けていた、と記録から見立てました。
https://claude.ai/
自分のサーバーは状態を持たず、道具の一覧の変更通知も出さない作りでした。仕様には一覧の変更を通知する仕組みがありますが、今回の観察を「すべてのMCPが必ずこうなる」という話には広げられません。
https://modelcontextprotocol.io/specification/2026-07-28/server/tools
PCのclaude.aiでコネクタを切断して接続し直すと、道具の一覧を取り直す要求が届きました。そこでworkspaceが必須でない定義を受け取り、workspace引数を省略した案件一覧と作業一覧の呼び出しが通りました。
今回の環境では、名前、引数、説明という道具の定義を変えたときに取り直しが必要でした。定義を変えない中の処理の修正は、サーバーの再配置だけで効きます。
このときは「これでそもそも構造的に問題じゃない?mcp 直したら毎回つなぎ直すの?」とも聞きました。毎回という説明にはせず、道具の定義を変えた場合だけ、取り直しとその記録の確認を配置の手順に入れています。
PCでは案件と作業の一覧を確認できました。この後のスマホの記録で確認できたのは、案件一覧の呼び出しです。
Webでは「読めた」、スマホでも「スマホでも動いた」と返しています。ただ、スマホから作業一覧を呼んだ記録はありません。画面で動いた感触と、どの道具を実際に呼んだかは分けて残しました。
また、自分の環境では、コネクタを切断してもDeskly側の古い許可が残っていました。本人が許可したうえで、手元のAIが対象を確認して取り消しています。切断と許可の取り消しが同時に済んだと考えず、管理画面まで確認しました。
まだ、同じように使えるとは言えないところ
今回の書き込みの実績はClaude Codeの1件です。claude.aiのWebは案件と作業の読み取り、スマホは案件の読み取りまでで、どちらも書き込みはまだ記録にありません。
https://code.claude.com/docs/en/mcp
Claude Desktopは未確認で、PCの確認に使ったのはclaude.aiのWebです。Codex CLIとChatGPTも未確認なので、対応を想定した設定があることを、実機で使えた結果には数えません。
https://claude.ai/
人の承認はアプリ側の設定に依存し、登録の上限も厳密な同時実行制御にはなっていません。更新用の鍵の再利用を検知して接続を取り消す仕組みも、現在の実装にはありません。「安全になった」で締められる状態ではないと思っています。
日をまたいだ鍵の更新や、別の地域へ取り消しが反映されるまでの動きも未確認です。さらに、レビューで出た軽微な指摘には判断の記録がないものがあり、取り消した登録が画面で二重に数えられる表示も残っています。
次は、小さな実案件で確かめたい
接続と検証用の書き込みまでを終え、実案件の登録はまだこれからです。残っている確認を含めて、次に進める範囲を小さくしておきます。
設計で決めた見本と適用、アプリごとの許可、履歴は、実機での確認につながりました。一方で、ブラウザが送る情報と、アプリが覚えている道具の定義は、実際に観察するまで取りこぼしていました。
次は、未実施の実案件の登録です。道具の定義を変えたら取り直しまで確認する、記録を取る仕組みが動いているかも先に確かめる。その手順を添えて、まずは次の1件に進みたいと思っています。
本文と画像の素材はdotsが作成し、事実の整理は手元で行いました。独立の検収、画像の仕上げと公開は手元が担当しました。
※ ヘッダー画像とインフォグラフィックの絵は AI(画像生成)で作成しています。
※ 本文の挿絵も AI(画像生成)で作成しています。
書いた人: ishizakahiroshi
群馬の北部で、保護猫2匹と暮らす、在宅エンジニア(何でも屋)
https://ishizakahiroshi.com/
https://github.com/ishizakahiroshi
X(業務委託・各種相談はこちら):
https://x.com/ishizakahiroshi
バックエンド・インフラ・AI連携まわりで、業務委託のご相談を受け付けています。フルリモートです。スポットや週2〜3時間からでも歓迎で、いろんな案件に携われたらうれしいです。こんな相談、歓迎です。










