iPhone でメールやメモを書いている最中、「この文章の語尾だけ整えてほしい」「3 行に要約してから貼り付けたい」と感じることはないでしょうか。私はアプリの説明文を 1 日に何十回も書き直すので、その都度 Claude のアプリに切り替えてプロンプトを打ち込む手間が、地味に作業のリズムを壊していました。
そこで使い始めたのが iOS のショートカット.app から直接 Claude API を呼ぶ運用です。共有シートに「選択テキストを整形」「3 行で要約」などのアクションを並べておけば、メモやメッセージから 1 タップで Claude に投げて、結果を貼り付けられます。慣れるとアプリ切り替えの摩擦が消えて、移動中の隙間時間で文章のリライトが完結するようになりました。
全体像 — なぜプロキシ Worker を挟むのか
ショートカットの「URL の内容を取得」アクションには、HTTP ヘッダーや POST ボディを設定する機能があります。ここに Anthropic の https://api.anthropic.com/v1/messages を直接指定すれば一見動きそうに見えるのですが、運用上は次の 2 つの理由でおすすめしません。
- API キーが端末側に常駐する: ショートカットの中身は iCloud 同期や AirDrop 共有で簡単に持ち出されます。誰かにレシピを共有した瞬間、キーごと渡してしまう事故が起きやすい構造です。
- モデル名や
max_tokensを一括変更しづらい: 端末に置いたショートカットは、複数台 iPhone を持っているとそれぞれを編集する必要があります。
そこで Cloudflare Workers を薄いプロキシとして挟みます。Worker 側に API キーを Secrets として置き、ショートカットからは「自前のエンドポイント + 端末固有の共有秘密」だけを送る構成にします。プロキシ層があれば、後からモデルを claude-sonnet-4-6 から別のものに差し替えるのも 1 ファイルの編集で済みます。
iPhone Shortcut
↓ POST { text, mode } + X-Shortcut-Token
Cloudflare Workers (proxy, secrets で API key を保護)
↓ Anthropic Messages API
Claude
API の送信構造そのものを最初に把握したい方は、ストリーミングレスポンスの実装 — Claude API でリアルタイム応答を実現するも参考になります。今回は短文整形なのでストリーミングは使わず、一括レスポンスで戻します。
ステップ 1 — Cloudflare Workers でプロキシを建てる
wrangler init shortcut-claude-proxy から始めます。コードはこれだけです。実際に私が運用しているものをコメント付きで整理しました。
// src/index.ts — iOS Shortcuts からの単発リクエストを Anthropic に中継する
export interface Env {
ANTHROPIC_API_KEY: string; // wrangler secret put で投入
SHORTCUT_TOKEN: string; // 端末ごとに変えたい場合は env を分ける
}
const SYSTEM_PROMPTS: Record<string, string> = {
polish: "次の日本語を、意味は変えずに語尾と接続詞だけ自然に整えて返してください。前置きや引用符は付けない。",
summary: "次の文章を 3 行以内・各行 50 文字以内で要約してください。箇条書きで。",
english: "次の日本語を、英語ネイティブが書いたように自然な英訳で返してください。",
};
export default {
async fetch(req: Request, env: Env): Promise<Response> {
if (req.method !== "POST") return new Response("Method Not Allowed", { status: 405 });
// 端末識別用の単純な共有秘密。盗まれたら Worker 側で 1 行書き換えれば失効する
if (req.headers.get("X-Shortcut-Token") !== env.SHORTCUT_TOKEN) {
return new Response("Unauthorized", { status: 401 });
}
const { text, mode = "polish" } = await req.json<{ text: string; mode?: string }>();
const system = SYSTEM_PROMPTS[mode] ?? SYSTEM_PROMPTS.polish;
const apiRes = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: {
"x-api-key": env.ANTHROPIC_API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
},
body: JSON.stringify({
model: "claude-sonnet-4-6",
max_tokens: 1024,
system,
messages: [{ role: "user", content: text }],
}),
});
if (!apiRes.ok) {
// ショートカット側で表示しやすいよう、エラー本文をそのまま返す
return new Response(await apiRes.text(), { status: apiRes.status });
}
const data = await apiRes.json<{ content: { type: string; text: string }[] }>();
const out = data.content.find((c) => c.type === "text")?.text ?? "";
return new Response(out, { headers: { "content-type": "text/plain; charset=utf-8" } });
},
};期待される出力はプレーンテキストです。あえて JSON にせず文字列を直接返すことで、ショートカット側のパース処理を 1 アクション減らせます。「結果をコピー」だけで済む形にしておくのが実用上いちばん速いです。
デプロイは次の 3 コマンドで完了します。
# Anthropic のキーを Secrets として登録(端末側には絶対に置かない)
wrangler secret put ANTHROPIC_API_KEY
# 端末用の共有トークン。任意の長い乱数で良い
wrangler secret put SHORTCUT_TOKEN
wrangler deployレート制限の挙動が気になる方は、Claude API レート制限・429エラー対処法 — リトライ戦略と実装ガイドをあわせて読むと、Worker 側で軽くリトライを追加するときの判断軸が整理しやすくなります。
ステップ 2 — iPhone 側のショートカットを組む
ショートカット.app を開き、新規ショートカットを次の流れで作ります。共有シートから受け取れるよう、上部のショートカット情報で「共有シートに表示」「テキスト」を許可しておきます。
- 「ショートカットの入力」を受け取る(共有シートからの選択テキスト)
- 「テキスト」アクションで JSON 文字列を組み立てる:
{"text":"<入力>","mode":"polish"} - 「URL」アクションに自分の Worker のエンドポイントを書く(例:
https://shortcut-claude-proxy.example.workers.dev) - 「URL の内容を取得」を以下の設定で配置
- メソッド: POST
- ヘッダ:
Content-Type: application/json/X-Shortcut-Token: <発行したトークン> - 本文を要求: ファイルを選択 → 直前のテキスト
- 「クリップボードにコピー」+「結果を表示」
この 5 ステップだけで、Mail でも Notes でも Slack でも、選択した文章を共有シート → Claude 整形 → クリップボードへ、を 2 タップで回せるようになります。私はモードを変えた 3 種類(整形 / 要約 / 英訳)を別ショートカットとして並べていて、用途で使い分けています。
「英訳」モードについて 1 つだけ補足です。英訳結果を貼り付ける用途なら、Worker 側のシステムプロンプトに「翻訳前後の改行を保持してください」と一文足しておくと、リスト形式のメモを翻訳したときの見た目が崩れません。プロンプトの調整は Worker をデプロイし直すだけで全端末に即反映されます。
私が実際に運用してわかった 3 つのつまずきポイント
つまずき 1: 「URL の内容を取得」が長文で 30 秒前後黙る
Sonnet クラスのモデルは 2,000 字程度の入力でも 5〜10 秒待たされることがあり、ショートカット側はこの間ずっと無反応に見えます。最初は「壊れた」と勘違いして同じテキストを 3 回投げてしまい、無駄なリクエストが走りました。私は wait アクションを入れる代わりに、共有シート側に 「処理中...」と書いた通知バナー を 1 件出してから fetch を呼ぶようにしています。視覚的に「動いている」と分かるだけで誤連打が消えました。
つまずき 2: メモから取った日本語に「不可視文字」が混じっている
iOS のメモ.app から共有する文章には、見えないリッチテキストの装飾コードが混ざることがあります。これを生のまま JSON に入れるとパースで弾かれ、Worker が 400 を返します。対策としてはショートカット側で「テキストをマッチ」ではなく「不要な文字を取り除く」アクションを 1 段挟むのが確実です。具体的には (ゼロ幅スペース)と (BOM)を空文字に置換します。私はここで 2 時間溶かしたので、最初から仕込んでおくことを強くおすすめします。
つまずき 3: トークンを 1 つだけにしていると、家族と共有したときに失効しづらい
最初は SHORTCUT_TOKEN を 1 つだけ発行していました。妻にも同じショートカットを渡したのですが、彼女が古い iPhone を売却するときにトークンを抜き忘れて、私の Worker が外部から叩かれかけたことがあります。現在は SHORTCUT_TOKEN_MASAKI、SHORTCUT_TOKEN_FAMILY のように env を分け、Worker 側で許可リストとして照合する形に変えました。これだけで「特定の端末だけ無効化」が 1 行の編集で済みます。
派生レシピ — 用途を増やすときに私が試して効いたもの
整形・要約・英訳に慣れてくると、文章以外にも応用できる場面が増えます。私が実際に毎日使っているレシピをいくつか共有します。
- タスク分解モード:
mode=splitを追加して、システムプロンプトを「次の文章から具体的な作業項目を箇条書きで 5 つ以内に抜き出してください」に。アイデアメモから ToDo を生やすのに重宝します。 - タイトル候補モード: ブログ下書きの先頭段落を選択して
mode=titlesを呼ぶと、3〜5 候補のタイトルが返ってきます。私はこれを App Store Connect の「プロモーション用テキスト」を捻り出すのにも使っています。 - 会議録のフォロー化モード: 録音から書き起こした文字列を選択して
mode=followupsを呼ぶと、決定事項と次回の宿題が分けて返ってきます。会議直後にメモへ貼り付けるだけで議事録の半分が完成します。
このうちタイトル候補モードは、私の運用ではアプリ説明文の改善ツールとしても使っています。ASO の文脈で「タイトルから差し替えた方が CTR が上がる」と感じる場面が増えていて、最近は意図的にこのモードで毎週見直すようにしています。ASO 自体に興味がある方は、Claude API の構造化出力実践マスター で扱っている JSON 出力テクニックをうまく組み合わせると、JSON 形式でタイトル候補と説明文をセットで返すような派生も簡単に作れます。
今回のように外部サービスとの薄いプロキシを設計する勘所が、語彙込みで身につきやすい一冊です。
次のステップ
すでに iPhone を使っている方なら、所要時間は 30 分です。Cloudflare アカウントだけ用意して、まずは「polish」モード 1 種類を立てて 1 日使ってみてください。それだけで「文章を整える」プロセスが手に馴染むはずです。気に入ったら Worker 側に mode を 1 つ追加するだけで、ショートカットの数を増やせます。私は最初の 1 週間で 5 種類まで増やしました。
API キーをローカルに置かない構成は、家族や友人に同じレシピを配るときの安心感も大きく変わります。「便利だから渡したい、でもキーは渡したくない」をきれいに切り分けられるのが、Worker プロキシ方式の地味だけれど大事な利点です。