Nodaro ドキュメント
ドキュメントノードリファレンスモデルAI エージェント(MCP)開発者向けセルフホスティングリサーチ
TypeScript SDK

OAuth と開発者アプリ

client.developerApps で Nodaro の OAuth アプリを登録・管理し、client.oauth でコードの交換、トークンの取り消し、同意画面用データの読み取りを行います。

client.developerApps は、あなたが所有する OAuth アプリを管理します。これは、ほかの Nodaro ユーザーが自分のアカウントへのアクセスをあなたのソフトウェアに許可するためのアプリです。client.oauth は、OAuth 2.0 フローのサーバー側を担います。認可コードをアクセストークンと交換し、トークンを取り消し、同意画面が表示する公開データを返します。同意フローの全体については、OAuth で説明しています。

メソッド

メソッド内容
developerApps.list()自分のアプリを一覧表示します
developerApps.get(id)1 つのアプリを読み取ります
developerApps.create(input)アプリを登録し、そのシークレットを取得します
developerApps.update(id, input)アプリを変更します
developerApps.delete(id)アプリを削除します
developerApps.rotateSecret(id)アプリのシークレットを置き換えます
oauth.exchangeCode(input)認可コードをアクセストークンと交換します
oauth.revoke(token)アクセストークンを取り消します
oauth.getAppInfo(clientId, redirectUri?)同意画面用に、アプリの公開データを読み取ります

スコープ

アプリはスコープを要求し、ユーザーがそれを承認します。サーバーは、次のスコープを受け付けます。

スコープ許可される操作
workflows:readワークフローの読み取り
workflows:writeワークフローの作成と変更
workflows:executeワークフローの実行
jobs:readジョブの読み取り
assets:readキャラクター、ロケーション、オブジェクトなどのアセットの読み取り
assets:writeアセットの作成と変更
credits:readクレジット残高の読み取り
apps:read公開されたアプリの読み取り
pipelines:readパイプラインの読み取り
pipelines:executeパイプラインの開始とキャンセル
pipelines:approveパイプラインのステージの承認と却下
presets:readノードプリセットの読み取り
workspaces:readユーザーが所属するワークスペースの一覧表示
workspaces:writeアプリが動作するワークスペースの選択

各スコープについて同意画面に表示される内容は、OAuth アプリに記載されています。必要なスコープがない呼び出しは、missingScope にそのスコープが示された ForbiddenError をスローします。スコープと不足している権限を参照してください。

client.developerApps

アプリを読み取ったり変更したりできるのは、所有者だけです。シークレットが返されるのは 1 回だけです。

developerApps.list()

自分のアプリを一覧表示します。

list(): Promise<{ data: DeveloperApp[] }>
const { data: apps } = await client.developerApps.list()
const mine = apps.filter((app) => (app.kind ?? "user") === "user")

DeveloperApp は、id、name、description、logoUrl、homepageUrl、redirectUris、allowedOrigins、scopesRequested、clientId、status(active、suspended、pending_review のいずれか)、kind、createdAt、updatedAt を持ちます。kind は、あなたが登録したアプリでは "user" です。それ以外の値である dynamic_mcp、first_party_mcp、community_instance は、自己登録したクライアントを示します。5 つまでの上限に数えられるのは、"user" のアプリだけです。

developerApps.get(id)

1 つのアプリを読み取ります。シークレットが含まれることはありません。

get(id: string): Promise<{ data: DeveloperApp }>

Prop

Type

const { data: app } = await client.developerApps.get(appId)

developerApps.create(input)

アプリを登録します。応答には clientSecret が含まれます。サーバーはそのハッシュしか保存しないため、今すぐ保管してください。

create(input: CreateDeveloperAppInput): Promise<{ data: DeveloperApp & { clientSecret: string } }>

Prop

Type

const { data } = await client.developerApps.create({
  name: "My integration",
  redirectUris: ["https://example.com/oauth/callback"],
  scopesRequested: ["workflows:read", "workflows:execute"],
})
console.log(data.clientId, data.clientSecret) // save both now

アプリは 5 つまで登録できます。6 つ目は 400 limit_reached で失敗します。

developerApps.update(id, input)

アプリを変更します。変更するフィールドだけを渡してください。それぞれに create() と同じルールが適用されます。

update(id: string, input: UpdateDeveloperAppInput): Promise<{ data: DeveloperApp }>

Prop

Type

await client.developerApps.update(appId, {
  redirectUris: ["https://example.com/oauth/callback", "https://staging.example.com/oauth/callback"],
})

developerApps.delete(id)

アプリを削除します。

delete(id: string): Promise<{ success: true }>

Prop

Type

await client.developerApps.delete(appId)

ID が存在しない場合や、そのアプリがあなたのものではない場合は、NotFoundError をスローします。

developerApps.rotateSecret(id)

新しいクライアントシークレットを作成し、古いものを即座に無効にします。新しいシークレットが返されるのは 1 回だけです。

rotateSecret(id: string): Promise<{ clientSecret: string }>

Prop

Type

const { clientSecret } = await client.developerApps.rotateSecret(appId)

古いシークレットでのコード交換は機能しなくなるため、サーバーのシークレットはすぐに更新してください。

client.oauth

あなたのアプリのサーバーが呼び出す、OAuth 2.0 のエンドポイントです。フィールド名は、OAuth の標準と同じく snake_case です。

oauth.exchangeCode(input)

同意後のリダイレクトから得た認可コードを、アクセストークンと交換します(POST /v1/oauth/token)。SDK が grant_type: "authorization_code" を自動的に追加します。

ブラウザーから呼び出さないでください。このリクエストにはクライアントシークレットが含まれており、サーバーに置いたままにする必要があります。

exchangeCode(input: {
  client_id: string
  client_secret: string
  code: string
  redirect_uri: string
}): Promise<{ access_token: string; token_type: "Bearer"; scope: string; expires_in: number }>

Prop

Type

import { createClient, StaticTokenAuth } from "@nodaro/sdk"

const tokens = await client.oauth.exchangeCode({
  client_id: process.env.NODARO_CLIENT_ID!,
  client_secret: process.env.NODARO_CLIENT_SECRET!,
  code: req.query.code as string,
  redirect_uri: "https://example.com/oauth/callback",
})

// Act for the user who approved your app
const userClient = createClient({
  baseUrl: "https://app.nodaro.ai",
  auth: new StaticTokenAuth(tokens.access_token),
})

scope には、付与されたスコープが空白区切りで並び、expires_in はトークンの有効期間を秒単位で示します。

oauth.revoke(token)

アクセストークンを取り消します(POST /v1/oauth/revoke、RFC 7009)。標準仕様により、トークンが有効だったかどうかを明かすことが禁じられているため、未知のトークンに対しても、常に { success: true } を返します。

revoke(token: string): Promise<{ success: true }>

Prop

Type

await client.oauth.revoke(accessToken)

oauth.getAppInfo(clientId, redirectUri?)

同意画面用に、アプリの公開データを返します(GET /v1/oauth/app-info)。トークンは不要です。

getAppInfo(clientId: string, redirectUri?: string): Promise<OAuthAppInfo>

Prop

Type

const info = await client.oauth.getAppInfo(clientId, "https://yourapp.com/oauth/callback")
if (!info.redirectUriRegistered) throw new Error("Unregistered redirect URI")

応答には、name、description、logoUrl、homepageUrl、scopesRequested、redirectUriRegistered が含まれます。redirectUriRegistered は、URI が正確に登録されている場合だけ true になり、redirectUri を渡さなかった場合は null になります。これにより、同意画面は、URI の一覧を明かすことなく、未登録のリダイレクトを拒否できます。

よくある質問

最終更新

目次