.cursor/mcp.json で Cursor に Shager を追加:リリースノートを全クライアントアカウント分の下書きに
Cursor に Shager のリモート MCP サーバーを設定し、変更履歴をアカウント別の SNS 下書きに変える方法を解説します。

Shager を Cursor につなぐには、プロジェクトに .cursor/mcp.json(すべてのプロジェクトで使うなら ~/.cursor/mcp.json)を作り、shager のエントリーに url として https://app.shager.ai/api/mcp を、headers で Authorization に Bearer ${env:SHAGER_API_KEY} を設定します。Cursor が環境変数から値を解決して HTTP で接続し、エージェントが Shager のツールを使えるようになります。ローカルサーバーもブリッジも要りません。
Cursor は、配信の拠点として面白い場所です。変更履歴、ドキュメント、リリースノート、ブログの下書きなど、元になる素材がすでにリポジトリにあるからです。このガイドでは、まず接続をきちんと設定し、そのうえで実際にこの用途に使ってみます。
リモートサーバー用の Cursor の MCP 設定はどんな形ですか?
Cursor の MCP ドキュメントでは、リモートサーバーは url と任意の headers オブジェクトで表され、url と headers のフィールドで ${env:NAME} による変数展開が使えると説明されています。設定の置き場所は2つあり、プロジェクト専用のツールならプロジェクト内の .cursor/mcp.json、どこでも使うツールならホームディレクトリの ~/.cursor/mcp.json です。
Shager の場合は次のとおりです。
{
"mcpServers": {
"shager": {
"url": "https://app.shager.ai/api/mcp",
"headers": {
"Authorization": "Bearer ${env:SHAGER_API_KEY}"
}
}
}
}
シェルのプロファイルには次を書きます。
export SHAGER_API_KEY="shgr_live_your_key_here"
Cursor は、自身を起動したプロセスから環境変数を読み込みます。macOS で Dock から開いたアプリには、~/.zshrc で設定した変数が見えないことがあります。キーは正しいのにサーバーが 401 で失敗する場合は、Cursor を終了し、ターミナルから cursor . で起動して、それが原因かどうか確かめてください。

プロジェクトのファイルか、グローバルのファイルか
| 置き場所 | 向いているケース | 注意点 |
|---|---|---|
リポジトリ内の .cursor/mcp.json |
コンテンツ作業をするマーケティングサイトやドキュメントのリポジトリ | コミットするのは ${env:...} の形だけ。キーをそのまま書かない |
~/.cursor/mcp.json |
どのワークスペースでも Shager を使いたい | すべてのプロジェクトのエージェントが Shager のワークスペースに届いてしまう |
複数のクライアントサイトを保守する代理店の開発者なら、たいていはプロジェクトのファイルのほうが合っています。クライアント A のリポジトリにいるエージェントが、クライアント B のワークスペースに気軽に下書きを作れてしまうのは避けたいところです。プロジェクトのファイルには、そのリポジトリにふさわしいワークスペースだけを持つオーガニゼーションのキーを組み合わせるか、少なくともプロンプトでワークスペースを明示しましょう。
キーはどこで手に入れますか?
人が https://app.shager.ai/dashboard/agents で作成し、スコープを選びます。エディタ内での作業なら、read と write がちょうどよいデフォルトです。エージェントはメディアのアップロードや下書きの作成はできますが、publish スコープがなければ Shager は予約も公開も拒否します。試作中でまだアカウントがない場合は、エージェントが自己登録でサンドボックスを作れます。手順は shager.ai/auth.md で公開しています。
Cursor にツールが見えているか確認するには?
Cursor の MCP 設定を開き、shager が connected 状態で、ツール一覧が表示されているか確認します。whoami、list_workspaces、create_workspace、list_channels、create_connect_link、list_groups、create_group、upload_media_from_url、create_post、schedule_post、request_approval、get_post、list_posts、cancel_post、get_analytics です。サーバーにエラーが出る場合、よくある原因は3つ。環境変数がない、ヘッダーの値に Bearer がない、ファイルの JSON 構文が間違っている、のいずれかです。
次に、エージェントのチャットで聞いてみます。
Call shager whoami and tell me which scopes this key has.

ワークフロー:変更履歴をアカウント別の下書きにする
Cursor にぴったりの具体的な仕事を紹介しましょう。たとえば、Facebook と Instagram に地域パートナーのページを12件持つソフトウェア販売代理店のサイトを保守しているとします。リリースのたびに、誰かが変更履歴を手作業で SNS 投稿に書き直しています。Shager をつないでおけば、最初のたたき台はエージェントに任せられます。
Read CHANGELOG.md and take the entry for v4.2 only.
In Shager workspace "Brightline Partners":
1. list_groups and use the group "Regional partners".
2. list_channels so you know each channel's name and network.
3. Write one short post about v4.2 for a non-technical audience.
4. Create a DRAFT with create_post (no schedule_at):
group_ids: the "Regional partners" group
per_channel: a caption per channel that names the region from the channel
name and varies the opening line; keep facts identical
cta_url: https://brightline.example/releases/4-2
campaign: "release-4-2"
first_comment: "Full notes: " followed by the link
5. Print the post id and a table of channel, caption first line, format.
このプロンプトには、意図して選んだポイントがいくつかあります。
事実は同じまま、言い回しだけを変えます。per_channel はアカウントごとにキャプションを上書きするもので、推奨されるパターンです。関連するページに同じ文章を12回載せるのは、大規模投稿でスパム判定を避ける方法の記事で注意している繰り返しそのもので、そのうち2つのページをフォローしている人にとっても読み心地が悪いものです。
リンクはアカウントごとに計測されます。cta_url を渡すと、Shager はアカウントごとに別の短縮リンクと UTM のセットを作り、utm_content でアカウントを識別します。あとで get_analytics を使えばアカウント別・投稿別のクリックが返ってくるので、各地域のパートナーは自分のページがどれだけ送客したかを確認できます。
出力は下書きです。公開前に、社内のレビュー担当か、承認リンク経由のクライアントが Shager で必ず目を通します。
コードから API を呼びたい場合は?
チャットではなく、リポジトリ内のスクリプトにしたいこともあるでしょう。たとえば CI のリリースワークフローは、誰かが Cursor を開くことに依存すべきではありません。同じ操作は REST でも提供されており、OpenAPI ドキュメントに記載されています。上の手順4に相当する TypeScript のコードです。
const API = "https://app.shager.ai/api/v1";
const headers = {
Authorization: `Bearer ${process.env.SHAGER_API_KEY}`,
"Content-Type": "application/json",
};
const res = await fetch(`${API}/workspaces/${workspaceId}/posts`, {
method: "POST",
headers,
body: JSON.stringify({
caption: defaultCaption,
group_ids: [groupId],
per_channel: captions.map((c) => ({ channel_id: c.channelId, caption: c.text })),
cta_url: "https://brightline.example/releases/4-2",
campaign: "release-4-2",
first_comment: "Full notes: https://brightline.example/releases/4-2",
}),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data.id, body.data.status); // a DRAFT post
レスポンスは { "data": ... } で、エラーは { "error": { "code", "message" } } で包まれているので、エラー処理はどこでも同じ書き方で済みます。一連の流れは REST クイックスタートで紹介しています。
プロジェクトに追加しておきたいルール
Cursor はプロジェクトルールに対応しており、短いルールを置いておけば、毎回のプロンプトで同じ制約を繰り返さずに済みます。たとえば次のようなものです。
When using the shager MCP server:
Never pass schedule_at unless I explicitly give a date and time.
Always use per_channel captions when posting to more than one account.
Always pass cta_url for any link instead of pasting raw URLs into captions.
Use ISO 8601 with an offset for any time, in the workspace timezone.
ルールはモデルへの指針であって、強制力はありません。強制力を持つのはキーのスコープです。エディタ用のキーに publish を付けなければ、モデルがルールを無視したとしても、1つ目のルールが破られることはありません。
よくある質問
Cursor は OAuth なしで Shager に対応していますか?
はい。Cursor は設定したヘッダーをそのまま送るので、Bearer の API キーがそのまま使えます。Shager の MCP サーバーは、それを好むクライアント向けに OAuth によるログインにも対応していますが、Cursor ならキーだけで十分です。
Cursor と Claude Code で同じキーを使えますか?
使えますが、別々のキーにしたほうがよいでしょう。呼び出しはそれぞれ、行ったキーの名前で Shager の監査ログに記録されます。キーを分けておけば、片方のツールを止めてももう片方は動き続けます。Claude Code の設定は、このシリーズの別のガイドで扱っています。
「これを公開して」と言うと、エージェントはすぐに投稿しますか?
キーに publish スコープがあり、アカウントが人によって引き継がれていて、ワークスペースが事前のクライアント承認を求めていない場合に限ります。read と write だけのキーなら、リクエストは分かりやすい 403 で失敗し、何も公開されません。
次のステップ
接続が動いたら、気の利いたプロンプトよりも、繰り返し使える手順を作るほうが大きな成果につながります。構成については Shager 用の Claude スキルの作り方を読んでみてください。同じ指示は Cursor のルールにもそのまま生かせます。すべてのツールとフィールドのリファレンスとして、エージェント向けページも手元に開いておくと便利です。


