コンテンツにスキップ
Twexapi
日本語
Esc
↑↓移動↵開く⌘Jプレビュー
このページの内容

MCP クライアントの OAuth

ユーザーを TwexAPI にサインインさせる MCP クライアントを作るためのリファレンス:ディスカバリー、動的クライアント登録、PKCE、スコープ、トークン、更新、取り消し。

TwexAPI は MCP サーバー用に OAuth 2.1 の認可サーバーを運用しています。Claude、ChatGPT、Cursor などの MCP クライアントは自動的にこれを使います。独自のクライアントを作る場合や、クライアントの問題を調べる場合はこのページを参照してください。

  • PKCE 付きの認可コードフロー(S256 のみ)。
  • パブリッククライアントのみで、クライアントシークレットはありません。動的クライアント登録(RFC 7591)で登録します。
  • ユーザーは https://twexapi.io/oauth/consent で TwexAPI アカウントにサインインし、承認します。
  • トークンは不透明な文字列で、https://api.twexapi.io/mcp でのみ使えます。TwexAPI の API キーではないため、REST API は呼び出せません。
  • 呼び出しはユーザーの API キーを通じてそのクレジットから課金されるため、承認にはクレジットの残った有効なキーが必要です。

スクリプトやバックエンドから TwexAPI を呼ぶだけなら、API キー を使ってください。

ディスカバリー

認証情報なしで https://api.twexapi.io/mcp にリクエストすると、次のヘッダー付きで 401 が返ります:

WWW-Authenticate: Bearer realm="twexapi", resource_metadata="https://api.twexapi.io/.well-known/oauth-protected-resource/mcp", scope="mcp:read mcp:write"

保護リソースのメタデータ

GET https://api.twexapi.io/.well-known/oauth-protected-resource/mcp(/.well-known/oauth-protected-resource でも同じ内容):

{
  "resource": "https://api.twexapi.io/mcp",
  "authorization_servers": ["https://api.twexapi.io"],
  "bearer_methods_supported": ["header"],
  "scopes_supported": ["mcp:read", "mcp:write"],
  "resource_name": "TwexAPI"
}

認可サーバーのメタデータ

GET https://api.twexapi.io/.well-known/oauth-authorization-server:

{
  "issuer": "https://api.twexapi.io",
  "authorization_endpoint": "https://api.twexapi.io/oauth/authorize",
  "token_endpoint": "https://api.twexapi.io/oauth/token",
  "registration_endpoint": "https://api.twexapi.io/oauth/register",
  "revocation_endpoint": "https://api.twexapi.io/oauth/revoke",
  "response_types_supported": ["code"],
  "response_modes_supported": ["query"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["none"],
  "revocation_endpoint_auth_methods_supported": ["none"],
  "scopes_supported": ["mcp:read", "mcp:write"],
  "authorization_response_iss_parameter_supported": true
}

スコープ

スコープ 許可される内容
mcp:read explore と twexapi_request(読み取り専用のエンドポイント)。常に許可されます。
mcp:write twexapi_write(ツイートとリプライの投稿)。ユーザーは同意ページで拒否できます。

両方を求めるには mcp:read mcp:write を指定します。不明なスコープは無視され、認識できるスコープが 1 つもない場合は両方を求めたものとして扱われます。ユーザーが実際に許可した内容は、トークンレスポンスの scope フィールドで確認できます。

1. クライアントを登録する

POST https://api.twexapi.io/oauth/register
Content-Type: application/json

{
  "client_name": "My Agent",
  "redirect_uris": ["http://127.0.0.1:53682/callback"]
}
{
  "client_id": "twx_client_...",
  "client_id_issued_at": 1792600000,
  "client_name": "My Agent",
  "redirect_uris": ["http://127.0.0.1:53682/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}
フィールド ルール
redirect_uris 必須。1〜10 個の URI で、それぞれ次のいずれか:https://、localhost・127.0.0.1・[::1] 上の http://、または cursor:// のようなプライベートスキーム。フラグメントやユーザー情報は使えません。
client_name 任意。最大 100 文字。同意ページとユーザーの Authorized apps(認可済みアプリ)一覧に表示されます。
token_endpoint_auth_method 任意。none のみ受け付けます。
grant_types 任意。authorization_code と refresh_token の部分集合。
response_types 任意。code のみ。

登録は IP アドレスごとに 1 時間あたり 30 クライアントまでです。クライアント登録は 180 日間有効で、ユーザーがそのクライアントで認可を始めるたびに延長されます。登録は一度だけ行い、client_id を使い回してください。

2. PKCE のペアを作る

Node.js:

import crypto from "node:crypto";

const verifier = crypto.randomBytes(32).toString("base64url");
const challenge = crypto.createHash("sha256").update(verifier).digest("base64url");

Python:

import base64, hashlib, secrets

verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b"=").decode()
challenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest()).rstrip(b"=").decode()

verifier は A-Z a-z 0-9 - . _ ~ からなる 43〜128 文字にしてください。

3. ユーザーを認可に送る

ユーザーのブラウザで次の URL を開きます:

https://api.twexapi.io/oauth/authorize
  ?response_type=code
  &client_id=twx_client_...
  &redirect_uri=http%3A%2F%2F127.0.0.1%3A53682%2Fcallback
  &code_challenge=CHALLENGE
  &code_challenge_method=S256
  &state=RANDOM_STATE
  &scope=mcp%3Aread%20mcp%3Awrite
  &resource=https%3A%2F%2Fapi.twexapi.io%2Fmcp
パラメーター 必須 補足
response_type はい code。
client_id はい 登録時に取得したもの。
redirect_uri はい 登録済みの URI と完全に一致する必要があります。ループバックの http URI は任意のポートを使えます。
code_challenge、code_challenge_method はい S256 のみ。
state 推奨 そのまま返されます。CSRF 対策として検証してください。
scope いいえ スコープ を参照。
resource いいえ 指定する場合は https://api.twexapi.io/mcp にしてください。

TwexAPI はユーザーを twexapi.io の同意ページに送ります。ユーザーはサインインし、アプリ名と戻り先のホストを確認して、書き込みを許可するかを選び、承認または拒否します。リクエストは 10 分で期限切れになります。

4. コードを受け取る

承認されると、ブラウザはリダイレクト URI に戻ります:

http://127.0.0.1:53682/callback?code=CODE&state=RANDOM_STATE&iss=https%3A%2F%2Fapi.twexapi.io

state が一致すること、iss が https://api.twexapi.io であることを確認してください。拒否された場合は、code の代わりに error=access_denied が付きます。コードは 1 回限りで、2 分で期限切れになります。

client_id が不明な場合や redirect_uri が登録されていない場合、TwexAPI はリダイレクトせずに 400 エラーを表示します。そのため、設定を誤ったクライアントがユーザーを未確認のアドレスに送ることはありません。

5. コードをトークンに交換する

POST https://api.twexapi.io/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=CODE
&redirect_uri=http%3A%2F%2F127.0.0.1%3A53682%2Fcallback
&client_id=twx_client_...
&code_verifier=VERIFIER
{
  "access_token": "twx_at_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "twx_rt_...",
  "scope": "mcp:read mcp:write"
}

redirect_uri と client_id は認可リクエストと一致させてください。resource=https://api.twexapi.io/mcp を送ることもできます。JSON のボディも受け付けます。

6. MCP サーバーを呼び出す

POST https://api.twexapi.io/mcp
Authorization: Bearer twx_at_...
Content-Type: application/json
Accept: application/json, text/event-stream

アクセストークンは /mcp でのみ使えます。期限切れ、取り消し済み、または不明なトークンには、WWW-Authenticate ヘッダーに error="invalid_token" を含む 401 が返ります。トークンを更新するか、ユーザーに再度サインインしてもらってください。

トークンの更新

POST https://api.twexapi.io/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=twx_rt_...
&client_id=twx_client_...

更新のたびに新しいアクセストークンと新しいリフレッシュトークンが返り、古いリフレッシュトークンは使えなくなります。毎回新しいペアを保存してください。古いリフレッシュトークンが再利用されると、TwexAPI は漏えいとみなして認可全体を取り消します。その認可のトークンはすべて使えなくなり、ユーザーは再度サインインする必要があります。

取り消し

POST https://api.twexapi.io/oauth/revoke
Content-Type: application/x-www-form-urlencoded

token=twx_rt_...

リフレッシュトークンを取り消すと認可全体が終了します。アクセストークンを取り消した場合は、そのトークンだけが無効になります。このエンドポイントは、不明なトークンに対しても常に 200 を返します。ユーザーは ダッシュボード の Authorized apps(認可済みアプリ)からもアプリを取り消すことができ、すぐに反映されます。

トークンの有効期間

項目 有効期間
認可リクエスト(同意ページ) 10 分
認可コード 2 分、1 回限り
アクセストークン 1 時間
リフレッシュトークン 30 日、使うたびにローテーション
30 日間使われなかった認可 失効
クライアント登録 180 日、認可のたびに延長

エラー

エラーは標準的な OAuth の形式で返ります:

{
  "error": "invalid_grant",
  "error_description": "The authorization code is invalid, expired or already used"
}
エンドポイント error 原因
登録 invalid_redirect_uri リダイレクト URI がない、形式が正しくない、または許可されていないスキームやホストを使っています。
登録 invalid_client_metadata サポートされていない token_endpoint_auth_method、grant_types、response_types。
登録 temporarily_unavailable(429) その IP アドレスからの登録が多すぎます。client_id を使い回してください。
認可 invalid_client(400、リダイレクトなし) client_id が不明です。先に登録してください。
認可 invalid_request(400、リダイレクトなし) redirect_uri がこのクライアントに登録されていません。
認可 unsupported_response_type response_type が code ではありません。
認可 invalid_request PKCE のパラメーターがない、または無効です。
認可 invalid_target resource が https://api.twexapi.io/mcp ではありません。
認可 access_denied ユーザーがアクセスを拒否しました。
トークン invalid_grant コードまたはリフレッシュトークンが無効、期限切れ、使用済み、または別のクライアントに発行されたもの。PKCE の検証に失敗した、または認可が取り消されています。
トークン invalid_target resource が一致しません。
トークン unsupported_grant_type authorization_code か refresh_token を使ってください。

ユーザーのアカウントに有効な API キーやクレジットがない場合は、同意ページが承認の前に止めるため、呼び出しに使えないトークンがクライアントに渡ることはありません。

このページは役に立ちましたか?