---
author: OOMOL
author_url: https://oomol.com/ja/about/
dateModified: 2026-09-10
title: OOMOL Connector SDK ガイド
description: TypeScript SDK を使って、OOMOL Connector の機能を product backend にすばやく追加します。
lang: ja
canonical_url: https://oomol.com/ja/docs/connector-sdk/
markdown_url: https://oomol.com/ja/docs/connector-sdk.md
---

# OOMOL Connector SDK ガイド

[`@oomol-lab/connector`](https://github.com/oomol-lab/connector-sdk) は OOMOL Connector gateway の TypeScript client です。connector infrastructure を自分で運用せずに、product backend へ app integrations をすばやく追加したいときに使います。あなたのコードは SDK 経由で OOMOL の hosted gateway を呼び出します。OAuth、token refresh、provider credential storage は gateway 側に残ります。

この package は軽量で依存関係がありません。SDK は request を組み立て、response を解析します。`gmail.search_threads`、`slack.post_message`、`notion.append_block` のような action は codegen も CLI も不要です。

主な内容：

- SDK のインストール、API key の取得、最初の call。
- モデル全体を表す 5 つの語：gateway、provider、action、connection、team。
- 2 つの call path（dynamic string と namespace）と execution metadata の読み方。
- codegen なしで action ごとの precise types を有効にする方法。
- まだ model 化されていない endpoint の proxy、catalog の introspection、connected apps の listing。
- `ProjectConnector` を使って、あなたの end users のために accounts を接続し、その users の behalf で actions を実行する方法。
- `OpenConnector` を使って、self-host した open-source Connector runtime に対して同じ actions を実行する方法。
- error の形、retry 可能な error、scope、timeout、cancel の指定方法。

## インストール

```sh
npm install @oomol-lab/connector   # または：bun add / pnpm add / yarn add
```

組み込みの `fetch` と `AbortController` を使うため、Node ≥ 18 が必要です。SDK は `dist` だけを配布し、runtime dependency はなく、`sideEffects: false` のため clean に tree-shaking できます。Node、Bun、Deno、edge runtime、標準 `fetch` を持つ browser-based apps で動作します。ブラウザでは host から API key を inject してください。

## API key を取得する

OOMOL Connector の **personal API key** が必要です。形式は `api_…` です。OOMOL Console で作成します：

<https://console.oomol.com/api-key>

環境変数として設定します。このガイドでは一貫して `OOMOL_API_KEY` を使います。gateway はすべての request を authorize し、key を `Authorization: Bearer <apiKey>` として受け取ります。

> personal `api_…` key は **あなた自身の** connections 上で actions を実行します。*あなたの* end users の accounts を接続するには、別の **project** key（`oo_proj_…`）と `ProjectConnector` client を使います。詳しくは[ユーザーのアカウントを接続する](#ユーザーのアカウントを接続する)を参照してください。hosted gateway ではなく runtime を self-host する場合、open-source server は独自の optional runtime token（`oct_…`）と `OpenConnector` client を使います。詳しくは[セルフホスト runtime](#セルフホスト-runtime)を参照してください。

## クイックスタート

client を作成してから action を呼び出します。以下の 2 つの形式は同じです。

```ts
import { Connector } from "@oomol-lab/connector";

const oomol = new Connector({ apiKey: process.env.OOMOL_API_KEY! });

// Path 1：dynamic string。任意の action id を呼び出せます。
const { threads } = await oomol.execute("gmail.search_threads", { query: "from:boss" });

// Path 2：namespace sugar。内部では同じ call です。
const result = await oomol.gmail.search_threads({ query: "is:unread" });
```

`execute` は action output を直接返します。execution metadata も必要な場合は `executeRaw` を使います：

```ts
const raw = await oomol.executeRaw("gmail.search_threads", { query: "from:ceo" });
raw.data;        // execute() が返す値と同じ
raw.executionId; // server が割り当てた execution id（support / log correlation に有用）
raw.actionId;    // echo された action id
raw.message;     // success envelope の human-readable message
```

中心となる call flow は `execute` と `executeRaw` です。

## 概念

SDK model には 5 つの core concepts があります。authentication、credentials、provider calls は gateway が処理します：

| 用語 | 内容 |
| --- | --- |
| **Gateway** | この client が通信する hosted OOMOL Connector service。credentials を保持し、実際の provider calls を実行し、uniform envelope を返します。SDK は local で integration logic を**実行しません**。 |
| **Provider / service** | 第三者 API（`gmail`、`slack`、`github`、`notion` など）。action id の `<service>` prefix です。 |
| **Action** | provider 上の 1 つの operation。`"<service>.<action>"`（例：`gmail.search_threads`）で識別されます。actions は gateway が提供し、client が呼び出します。 |
| **Connection** | provider 用に保存済みで authorization 済みの credential。token を直接扱うことはありません。`connectionName` で使用する connection を指定します。OAuth と credential lifecycle は gateway の仕事です。 |
| **Team** | optional な tenant scope。`x-oo-team-name` header として送信されます。 |

同じ vocabulary が SDK surface 全体で使われます。action id は常に `"<service>.<action>"`、`connectionName` は保存済み connection を選択し、project client では `externalUserId` があなたの end user の 1 人を識別します。

## よく使う操作

| したいこと | 使うもの | Notes |
| --- | --- | --- |
| model 化済み action を実行する | `execute` / `executeRaw` | typed one-liner。`executeRaw` は `{ executionId, actionId, message }` も返します。 |
| まだ action として model 化されていない endpoint を呼び出す | `proxy` | upstream API への passthrough。connection の credentials は gateway が inject します。 |
| actions を LLM に渡す / dynamic forms を作る | `catalog` | 任意の action または provider の runtime JSON Schema（2020-12）。 |
| 何が接続済みか確認する | `apps.list` | すでに link 済みの connections の read-only list。 |
| *あなたの* users に *自分の* accounts を接続させる | `ProjectConnector` | end users の behalf で accounts を接続し、actions を実行する project-scoped client。 |

provider と操作の対応範囲は gateway が提供します。[OOMOL 公開カタログ API](https://connector.oomol.com/v1/catalog) でカタログ全体の provider 数と操作数を確認するか、[アプリ一覧](/ja/apps/directory/)を参照してください。設定した gateway の provider は runtime で `oomol.catalog.providers()` を使って確認できます。呼び出し可能な操作はアカウントの認可とアクセスポリシーによって異なります。

## 正確な型（任意）

dynamic string path は**任意の** `actionId` で compile できます。デフォルトでは各 action は loose type（input/output とも `Record<string, any>`）で、新しい actions をすぐに呼び出せます。action ごとの precise input/output types と JSDoc が必要な場合は、companion types package を install し、使う **provider ごとに side-effect import を 1 行**追加します：

```ts
import { Connector } from "@oomol-lab/connector";
import "@oomol-lab/connector-types/gmail";   // gmail.* の precise types + JSDoc
import "@oomol-lab/connector-types/slack";   // …および slack.*

const oomol = new Connector({ apiKey: process.env.OOMOL_API_KEY! });

await oomol.gmail.search_threads({ query: "from:boss" }); // input + output が precise になります
await oomol.notion.append_block({ pageId, text });        // notion は import していない → まだ loose に呼び出せます
```

```sh
npm install -D @oomol-lab/connector-types
```

codegen なし、commit する generated files なし、CLI なしです。registered actions は literal completion と exact input/output types を得ます。**unregistered actions は `Record<string, any>` に degrade します**。types package が backend より遅れていても、新しい actions は loose fallback で呼び出せます。core runtime は types package に依存しません。

> subpath imports（`@oomol-lab/connector-types/gmail`）を解決するため、`moduleResolution` は `bundler`、`node16`、`nodenext` のいずれかにしてください。設定の詳細は [`@oomol-lab/connector-types`](https://github.com/oomol-lab/connector-types) repository を参照してください。

## 設定

`apiKey` 以外のすべての field は optional です：

```ts
new Connector({
  apiKey: process.env.OOMOL_API_KEY!,        // required
  baseUrl: "https://connector.oomol.com/v1", // default
  team: "acme",                              // default team → x-oo-team-name
  connectionName: "work",                    // default connection（per-call / using() を推奨）
  timeoutMs: 30_000,                         // default per-request timeout
  maxRetries: 2,                             // default；429 / 5xx / network を backoff + jitter で retry
  fetch: customFetch,                        // tests / proxies / tracing 用に inject
});
```

| Field | Default | Notes |
| --- | --- | --- |
| `apiKey` | — | 必須。`Authorization: Bearer <apiKey>` として送信されます。 |
| `baseUrl` | `https://connector.oomol.com/v1` | 手動 override のみ。env-based auto-switching はありません。 |
| `team` | — | call が実行される tenant。 |
| `connectionName` | — | provider に複数の connection があるとき、使用する stored connection。simple setup では client default として使えます。複数 connections では per call または `using()` で設定してください。 |
| `timeoutMs` | `30_000` | per-request timeout（milliseconds）。 |
| `maxRetries` | `2` | 429 / 5xx / network errors を exponential backoff と jitter で retry します。 |
| `fetch` | global `fetch` | tests、proxy agents、tracing 用に custom `fetch` を inject します。 |

### スコープと呼び出しごとのオプション

3 つの layer はこの優先順位で解決されます：**per-call options > `using()` scope > client defaults。**

`using()` は指定した defaults を merge した immutable scoped sub-client を返します。元の client は変更されません：

```ts
const work = oomol.using({ connectionName: "work", team: "acme" });
await work.gmail.search_threads({ query: "label:urgent" }); // "work" / "acme" の下で実行
```

per-call options はその call にだけ適用され、最も高い priority を持ちます：

```ts
await oomol.execute(
  "gmail.search_threads",
  { query: "from:ceo" },
  {
    team: "acme",           // この call の team を override
    connectionName: "alt",  // この call で別の connection を選ぶ
    timeoutMs: 10_000,      // この call 用の短い timeout
    retries: 0,             // この call では retries を無効化
    signal: controller.signal, // AbortSignal を forward
  },
);
```

`connectionName` も同じ layering で解決されます。wire 上では `x-oo-connector-alias` header として運ばれます（gateway field name は `alias`）。SDK surface では `connectionName` を使います。

## 3 つのクライアント概要

この package は 3 つの clients を export します。personal connections 用、project 配下の end-user connections 用、そして self-host する runtime 用です。transport と error model は共有しますが、credentials、methods、types は分かれています。

| | `Connector` | `ProjectConnector` | `OpenConnector` |
| --- | --- | --- | --- |
| Auth | personal `api_…` key | project `oo_proj_…` key | optional runtime token `oct_…` |
| 通信先 | OOMOL の hosted gateway | OOMOL の hosted gateway | **あなたが**動かす open-source runtime |
| 作用対象 | **あなた自身の** connections | **あなたの end users の** connections | あなたの server 上の**あなた自身の** connections |
| user の識別 | — | `externalUserId`（あなたが選ぶ） | — |
| Surface | `execute`、`executeRaw`、`proxy`、`catalog`、`apps`、namespaces | `connect.*`、`waitForConnection`、`getUserProfile`、`execute`、`executeRaw`、`forUser` | `execute`、`executeRaw`、`proxy`、`catalog`、`apps`、`health`、namespaces |
| 用途 | 接続済み providers を呼び出す | 各 user が自分の accounts を link する SaaS product を作る | runtime 全体を self-host する（localhost、Docker、your infra） |

この section は personal `Connector` から始まります。`ProjectConnector` は[ユーザーのアカウントを接続する](#ユーザーのアカウントを接続する)、`OpenConnector` は[セルフホスト runtime](#セルフホスト-runtime)で扱います。

## Proxy：まだ action がない endpoint を呼び出す

gateway が endpoint を action として model 化していない場合は、`proxy` で直接呼び出します。gateway は connection の credentials を引き続き inject します。request と response は upstream API の shape を保ちます。

```ts
// typed GET。field は `endpoint` であり、`path` ではありません。
const repos = await oomol.proxy<Array<{ name: string }>>("github", {
  endpoint: "/user/repos",
  method: "GET",
  query: { per_page: 5, sort: "updated" },
});
repos.status;               // upstream HTTP status
repos.data.map((r) => r.name);

// body と upstream headers を持つ POST（これらは gateway ではなく provider に送られます）。
await oomol.proxy("github", {
  endpoint: "/repos/acme/widgets/issues",
  method: "POST",
  headers: { "X-GitHub-Api-Version": "2022-11-28" },
  body: { title: "Tracking issue", labels: ["chore"] },
});
```

`endpoint` は path（provider の base URL に対して解決）または full URL を受け付けます。`https://eu.posthog.com/api/...` のような regional hosts を持つ providers で便利です。`method` は `GET | POST | PUT | PATCH | DELETE` のいずれかです。response は `{ status, headers, data }` です。proxy body は backend で strict に検証されます。不明な top-level keys は `invalid_input` として reject されます。

## Catalog：providers と actions を確認する

catalog は dynamic forms、validation、LLM tool definitions 向けの read-only runtime metadata を提供します。input/output schemas は JSON Schema（2020-12）を使い、compile-time types package から独立しています。

```ts
// providers を list。必要に応じて server-side で絞り込みます。
const all = await oomol.catalog.providers();                       // すべての providers
const mailish = await oomol.catalog.providers({ q: "mail" });      // free-text search → ?q=
const some = await oomol.catalog.providers({ service: ["gmail", "slack"] }); // restrict → ?service=…

// 1 つの service のすべての actions。
const actions = await oomol.catalog.actions("gmail");

// runtime JSON Schema を含む、1 つの action の full metadata。
const meta = await oomol.catalog.action("gmail.search_threads");
meta.name;          // human-readable name
meta.requiredScopes;// action が必要とする OAuth scopes
meta.inputSchema;   // input 用 JSON Schema（2020-12）
meta.outputSchema;  // output 用 JSON Schema（2020-12）
```

各 provider は `{ service, displayName, iconUrl, homepageUrl, categories, authTypes }` を持ちます。

## Apps：接続済み accounts を一覧表示する

`apps.list()` は gateway がすでに保持している connections の read-only view を返します。connection の作成と削除は Console で行います。

```ts
const apps = await oomol.apps.list();
for (const app of apps) {
  // { id, service, status, connectionName, … }；未設定の場合 connectionName は null です。
  console.log(`${app.service}: id=${app.id} status=${app.status} connectionName=${app.connectionName}`);
}

// 特定の connection を target するには、その connectionName を per-call selector として渡します。
const work = apps.find((a) => a.connectionName === "work");
if (work) {
  await oomol.execute("gmail.search_threads", { query: "is:unread" }, { connectionName: "work" });
}
```

## エラー処理

失敗すると typed `ConnectorError` が throw されます。caller cancellation（abort された `AbortSignal`）は標準の `AbortError` で reject されるため、gateway error や transport error と分けて扱えます。

```ts
import { Connector, ConnectorError, isRetryable } from "@oomol-lab/connector";

try {
  await oomol.slack.post_message({ channel: "#general", text: "shipped" });
} catch (err) {
  if (err instanceof ConnectorError) {
    err.code;        // discriminable union、例："rate_limited", "credential_expired"
    err.status;      // HTTP status（client-side / network errors では 0）
    err.requestId;   // failure-correlation id
    err.actionId;    // applicable な場合
    err.executionId; // applicable な場合
    err.data;        // upstream response body、例：provider_error 時
    if (isRetryable(err)) {
      // 429 / 5xx / network / rate_limited / proxy_upstream_timeout / request_in_progress
    }
  } else {
    throw err; // non-ConnectorError、例：caller cancellation の AbortError；再 throw
  }
}
```

`err.code` は **open** union です。既知の backend codes は autocompletion され、新しい backend codes も string として pass through されます。処理時は default branch を残してください。よく使う codes は以下の group です：

| Group | Codes |
| --- | --- |
| Input / request | `invalid_input`, `invalid_request_payload`, `invalid_request_signature` |
| App / provider | `app_not_found`, `app_not_ready`, `app_auth_type_mismatch`, `provider_not_found`, `provider_not_configured`, `provider_config_not_found`, `provider_error`, `profile_not_found` |
| Credential / auth | `credential_expired`, `scope_missing`, `user_oauth_client_required` |
| Connection selection | `connection_ambiguous`, `connection_account_conflict`, `connection_alias_conflict`, `connection_request_not_found`, `connected_account_not_found` |
| Proxy | `proxy_not_supported`, `proxy_upstream_error`, `proxy_upstream_timeout`, `proxy_response_too_large` |
| Rate / concurrency | `rate_limited`, `request_in_progress`, `request_key_conflict`, `request_key_used` |
| Client-only（status 0、request 未送信または transport failure） | `client_invalid_request`, `client_timeout`, `client_network_error`, `client_wait_timeout` |

`isRetryable(err)` は `rate_limited`、`proxy_upstream_timeout`、`request_in_progress`、HTTP 429、任意の 5xx、transport failures（status 0）で `true` を返します。client validation errors（`client_invalid_request`）と `waitForConnection` の上限（`client_wait_timeout`）では `false` を返します。これらは通常、call または waiting-flow の変更が必要です。

### キャンセルとタイムアウト

cancel するには `AbortSignal` を渡します。single call を制限するには `timeoutMs` を設定します。組み込みの retry layer は transient failures を処理します。deterministic な 1 回だけの試行には `retries: 0` を使います。

```ts
const controller = new AbortController();
setTimeout(() => controller.abort(), 50);
try {
  await oomol.execute("gmail.search_threads", { query: "huge" }, { signal: controller.signal });
} catch (err) {
  (err as Error).name; // "AbortError"
}
```

## ユーザーのアカウントを接続する

`Connector` は **あなた自身の** connections 上で actions を実行します。`ProjectConnector` は SaaS products 向けです。*あなたの* end users があなたの app を通じて *自分の* Gmail / Slack / GitHub / … accounts を link し、あなたの backend がその behalf で actions を実行します。これは [Composio](https://composio.dev) や [Pipedream Connect](https://pipedream.com/docs/connect) などの products で使われる managed-auth model です。

managed auth では、**credentials があなたの application や model を通過することはありません**。user は gateway-hosted page で authorize します。gateway が credential を保存し、token を自動 refresh します。あなたの code は opaque identifiers だけを持ちます。

### エンドユーザー識別子

**`externalUserId`** は project client の user-isolation key です。通常は自分の user database から選びます。account 接続、connection 待機、action 実行などの project operations はこれに scope されます。同じ `externalUserId` を一貫して渡すことで、gateway は各 user の connections を隔離します。

### プロジェクトクライアントを作成する

`ProjectConnector` は **separate client** で、**project API key**（`oo_proj_…`）を使って作成します。project-scoped operations だけを expose し、personal client の `execute` / namespace / `proxy` / `catalog` / `apps` surface は含みません。

```ts
import { ProjectConnector } from "@oomol-lab/connector";

const project = new ProjectConnector({ apiKey: process.env.OOMOL_PROJECT_API_KEY! }); // oo_proj_...
```

> **先に Console setup が必要です。** backend が accounts を接続する前に、administrator が OOMOL Console で project、provider config、project API key を作成します。one-time setup と対応する backend REST flow は [OOMOL Connector SaaS ガイド](/ja/docs/connector-saas/)で説明しています。この SDK は同じ runtime API の typed wrapper です。

### OAuth：リンクを作成し、完了を待つ

OAuth は 2 steps です。pending connection request を作成し、user を authorize に送り、その後 completion を待ちます。

```ts
// 1. あなたの user の 1 人に対して pending connection request を作成します。
const request = await project.connect.oauth("user_42", {
  service: "gmail",
  connectionName: "work",                          // 割り当てる名前。後でこの account を target するために再利用します
  returnUri: "https://app.example.com/connected",  // callback 後に gateway が user を戻す先
});

// 2. user を provider の authorization page に送ります。
redirectUserTo(request.authorizationUrl);

// 3. user が完了するまで poll します（または失敗 / 期限切れ）。final connection request を返します。
const connected = await project.waitForConnection(request);
connected.status;             // "connected" | "failed" | "expired"
connected.connectedAccountId; // connected 後の stored account id
```

`authorizationUrl` はまず Connector-hosted entry page を開き、あなたの project と user が authorize しようとしている provider を表示してから、provider の OAuth page へ user を送ります。

![Gmail に redirect する前に my-saas が Gmail に接続することを示す Connector authorization entry](/img/docs/connector-sdk/en/authorization-entry.webp)

`waitForConnection` は request が `initiated` state を離れるまで poll し、それを返します。user が authorization を完了しない場合、request は自然に `expired` になります。`maxWaitMs`（default `600_000` ms、request expiry と同じ）が先に経過すると、code `client_wait_timeout` の `ConnectorError` を throw します。abort された `signal` は標準の `AbortError` で reject されます。

あなたの `returnUri` に到達すると、gateway は callback page で読める query parameters を追加します：

```text
status=success
service=gmail
providerConfigId=pc-1
externalUserId=user_42
connectedAccountId=ca-1
```

…または cancellation / provider error の場合：

```text
status=error
code=<connector-error-code>
message=<human-readable-message>
```

### API key / カスタム認証情報：同期

API-key と custom-credential の接続は account をすぐに返します。`waitForConnection` が必要なのは OAuth だけです。

```ts
// end user 自身の upstream key（例：OpenAI sk-…）であり、あなたの oo_proj_ key ではありません。
const account = await project.connect.apiKey("user_42", { service: "openai", apiKey: "sk-..." });
account.available; // この account が今 action を実行できるか

// provider-specific credential fields。gateway が provider config に照らして validate します。
await project.connect.customCredential("user_42", {
  service: "jira",
  values: { email: "user@acme.com", token: "..." },
});
```

すべての `connect.*` call は `service` または `providerConfigId` の**ちょうど 1 つ**で provider を識別します。1 つの project に同じ service の configs が複数ある場合は `providerConfigId` を使います。simple case では `service` を使います。

### どのアカウントで接続したか

`getUserProfile` は connected account の背後にいる third-party のアカウント本人、つまり end user が provider 上で実際に誰なのかを読み取ります。gateway が provider から都度取得し、provider をまたいで 1 つの形に正規化します。

```ts
const { service, profile, fetchedAt } = await project.getUserProfile(account.connectedAccountId);

profile.id;          // provider 側の安定した user id
profile.kind;        // "user" | "bot" | "service_account" | "unknown"（open union）
profile.username;    // ユーザー名 / handle、または null
profile.displayName; // 表示名、または null
profile.avatarUrl;   // アバターの URL、または null
profile.email;       // email。付与された scopes が公開しない場合は null
profile.metadata;    // gateway が公開する provider 固有のフィールド
```

provider が公開していないフィールド（または付与された scopes の対象外のフィールド。多くは `email`）は、欠落ではなく `null` で返ります。`fetchedAt` は gateway が profile を読み取った Unix ミリ秒タイムスタンプです。`connectedAccountId` には `connect.apiKey` / `connect.customCredential` の結果か、`connected` に到達した `ConnectionRequest` のものを渡します。未知の id は `connected_account_not_found`、`userProfile` capability のない provider は `profile_not_found`、inactive または使用不能な account は `app_not_ready`、`app_auth_type_mismatch`、または `credential_expired` で reject されることがあります。1 人にスコープした sub-client にも同じメソッドがあります: `user.getUserProfile(connectedAccountId)`。

### ユーザーの代理で実行する

```ts
// provider service は actionId prefix（"gmail"）から導出されます。
// connectionName / connectedAccountId がない場合、その user の latest active account が使われます。
const out = await project.execute(
  "user_42",
  "gmail.search_threads",
  { query: "is:unread" },
  { connectionName: "work" },
);
```

account selection precedence：`connectedAccountId`（specific account）が `connectionName`（name による account）より優先されます。どちらもない場合、gateway はその user の provider における latest active account を使います。`project.executeRaw` は personal client と同じ `{ data, executionId, actionId, message }` envelope を返します。

### 1 人のユーザーに限定する

`forUser` は `externalUserId` を一度 bind し、以後の calls で id を繰り返さずに済みます：

```ts
const user = project.forUser("user_42");
const request = await user.connect.oauth({ service: "slack" });
const slack = await user.waitForConnection(request);
if (slack.status === "connected") {
  await user.execute(
    "slack.post_message",
    { channel: "#general", text: "shipped" },
    { connectedAccountId: slack.connectedAccountId },
  );
}
```

`project.execute` は personal path と同じ [`@oomol-lab/connector-types`](https://github.com/oomol-lab/connector-types) registry を再利用します。import 済み providers は precise input/output を得て、それ以外は loose に呼び出せます。

### Connection のライフサイクル

| Object | 取得するタイミング | Key fields |
| --- | --- | --- |
| `ConnectionRequest` | `connect.oauth` が返す。`getConnectionRequest` / `waitForConnection` で再読込 | `id`, `status`（`initiated` → `connected` / `failed` / `expired`）, `authorizationUrl`, `connectedAccountId`, `externalUserId`, `connectionName`, `expiresAt` |
| `ConnectedAccount` | `connect.apiKey` / `connect.customCredential` が同期的に返す。完了した OAuth request からも参照される | `id` / `connectedAccountId`, `status`（`active`, `reauth_required`, `error`, `disconnected`）, `available`, `externalUserId`, `connectionName`, `service` |

`available` が `true` になるのは、実行に必要なものがすべて揃っている場合だけです。provider config が active、account が active、underlying app が active、credential が存在している必要があります。両方の status fields は **open** unions です。新しい backend statuses に対応できるよう default branch を残してください。

### Composio / Pipedream から来た場合

| Composio / Pipedream | `@oomol-lab/connector` |
| --- | --- |
| `userId` / `external_user_id` | `externalUserId` |
| `connectedAccounts.initiate` / `createConnectToken`（OAuth） | `project.connect.oauth` |
| `connectedAccounts.initiate` + `AuthScheme.APIKey` | `project.connect.apiKey` |
| `waitForConnection()` | `project.waitForConnection()` |
| `tools.execute(slug, { userId, arguments })` | `project.execute(externalUserId, actionId, input)` |
| `composio.getEntity(userId)` | `project.forUser(externalUserId)` |

## セルフホスト runtime

open-source Connector server を localhost、Docker、または自分の infra で実行しますか？ **`OpenConnector`** はそのための personal client です。`Connector` surface（2 つの call paths、`proxy`、`catalog`、`apps`）を、*あなたが*実行する server に向けます。すでに書いた code はほとんど変わりません。server の立ち上げは別の topic です。[OpenConnector セルフホスティングガイド](/ja/docs/openconnector-self-hosting/)を参照してください。

open-source runtime は **personal** product の self-hostable counterpart です。1 つの server、1 人の user、その user 自身の connections 上で actions を実行します。ここに `team` や end-user model はありません。server はあなたのものです。

```ts
import { OpenConnector } from "@oomol-lab/connector";

const open = new OpenConnector(); // default は http://localhost:3000。fresh instance は auth 不要

await open.execute("hackernews.get_top_stories", {});             // path 1 — dynamic string
await open.gmail.search_threads({ query: "from:boss" });          // path 2 — namespace sugar。同じ registry types
await open.proxy("github", { endpoint: "/user", method: "GET" }); // path 3 — まだ model 化されていない endpoint への passthrough
await open.catalog.search("send email", { limit: 5 });            // catalog extras：search、services
await open.apps.list();                                           // runtime connections の read-only view
```

2 つの call paths と precise-types workflow は personal `Connector` と同じです。同じ `@oomol-lab/connector-types` side-effect imports が使えます。`proxy` も同じように動作しますが、runtime では 1 点だけ違いがあります。`endpoint` は `/` で始まる **relative path** である必要があります。runtime は absolute URL を `invalid_input` として reject しますが、hosted gateway は full URL も受け付けます。proxy executor を持たない providers は `proxy_not_supported` を返します。

### 自分の server に向ける

`baseUrl` は server **origin** であり、`/v1` URL ではありません。client が path prefix を自分で追加します。auth は単一の **optional** runtime token（`oct_…`）です。runtime の web console（Access tab）で mint します。token がない fresh instance は token なしで応答します。一度 token が存在すると、server は token を強制します。

```ts
const open = new OpenConnector({
  baseUrl: "https://connect.internal.example.com",       // server ORIGIN — /v1 url ではありません
  runtimeToken: process.env.OOMOL_CONNECT_RUNTIME_TOKEN, // oct_…；instance に token がない間は省略
  connectionName: "work",                                // optional client-level default connection
});
```

すべての field は optional です。`timeoutMs`、`maxRetries`、`fetch` は hosted client とまったく同じように動作します。

### Runtime 専用インターフェース

`OpenConnector` は hosted client にはない members をいくつか追加し、適用されないものを外します：

```ts
await open.health();                                    // { ok, runtime } — connectivity / auth probe
await open.catalog.services();                          // actions を持つすべての service id
await open.catalog.search("top stories", { limit: 3 }); // free-text relevance で actions を rank
await open.apps.listByService("github");                // 1 つの service の connections
await open.apps.authenticated(["github", "notion"]);    // REAL credential が保存されているもの
```

**`using()` はありません。** connection selection は 2 layers だけです。per-call `connectionName` が client-level default を override し、どちらもない場合 runtime は `"default"` connection に fallback します。

> **management は web console にあり、SDK にはありません。** connections の作成、OAuth clients の設定、runtime tokens の mint は server administration です。この SDK の外に意図的に置いています。`OpenConnector` は console が設定したものを *consume* するだけです。その側は[セルフホスティングガイド](/ja/docs/openconnector-self-hosting/)で扱います。hosted client と同様、member name（`execute` / `executeRaw` / `health` / `proxy` / `catalog` / `apps`）と衝突する service id も `execute("<service>.<action>", …)` で動作し続けます。shadow されるのは namespace sugar だけです。

完全な runnable tour — [`examples/open.ts`](https://github.com/oomol-lab/connector-sdk/blob/main/examples/open.ts)。

## リファレンス

### `Connector`（個人 `api_…` key）

```ts
new Connector(config: ClientConfig)

oomol.execute(actionId, input, options?)     // → action output
oomol.executeRaw(actionId, input, options?)  // → { data, executionId, actionId, message }
oomol.<service>.<action>(input, options?)    // execute の namespace sugar
oomol.using(scope)                           // → immutable scoped sub-client
oomol.proxy(service, { endpoint, method, query?, headers?, body? }, options?) // → { status, headers, data }
oomol.catalog.action(actionId, options?)     // → ActionMetadata
oomol.catalog.actions(service, options?)     // → ActionMetadata[]
oomol.catalog.providers(query?, options?)    // → ProviderMetadata[]   query: { service?: string[]; q?: string }
oomol.apps.list(options?)                    // → ConnectedApp[]
```

### `ProjectConnector`（project `oo_proj_…` key）

```ts
new ProjectConnector(config: ProjectConnectorConfig)

project.connect.oauth(externalUserId, input, options?)            // → ConnectionRequest（pending）
project.connect.apiKey(externalUserId, input, options?)           // → ConnectedAccount（synchronous）
project.connect.customCredential(externalUserId, input, options?) // → ConnectedAccount（synchronous）
project.getConnectionRequest(connectionRequestId, options?)       // → ConnectionRequest
project.waitForConnection(requestOrId, options?)                  // → ConnectionRequest   options: { pollIntervalMs?, maxWaitMs?, signal?, timeoutMs? }
project.getUserProfile(connectedAccountId, options?)              // → ConnectedAccountProfile
project.execute(externalUserId, actionId, input, options?)        // → action output
project.executeRaw(externalUserId, actionId, input, options?)     // → { data, executionId, actionId, message }
project.forUser(externalUserId)                                   // → ProjectUser（同じ methods、id bound）
```

`connect.*` input は `{ service | providerConfigId } & { connectionName?, … }` です（`service` / `providerConfigId` のちょうど 1 つ）。`execute` options は `{ providerConfigId?, service?, connectedAccountId?, connectionName? }` を追加します。

### `OpenConnector`（セルフホスト runtime、任意の `oct_…` token）

```ts
new OpenConnector(config?: OpenConnectorConfig)   // すべての field は optional。baseUrl default は http://localhost:3000

open.execute(actionId, input, options?)       // → action output
open.executeRaw(actionId, input, options?)    // → { data, executionId, actionId, message }
open.<service>.<action>(input, options?)      // execute の namespace sugar
open.health(options?)                         // → { ok, runtime }
open.proxy(service, { endpoint, method, query?, headers?, body? }, options?) // → { status, headers, data }   (endpoint は relative path である必要があります)
open.catalog.action(actionId, options?)       // → OpenActionMetadata
open.catalog.actions(service, options?)       // → OpenActionMetadata[]
open.catalog.services(options?)               // → string[]   (actions を持つ service ids)
open.catalog.providers(query?, options?)      // → ProviderMetadata[]
open.catalog.search(q, query?, options?)      // → OpenActionSearchResult[]   query: { service?, limit? }
open.apps.list(options?)                      // → ConnectedApp[]
open.apps.listByService(service, options?)    // → ConnectedApp[]
open.apps.authenticated(services, options?)   // → string[]   (real credential を持つ services)
```

`options` は `{ connectionName?, signal?, timeoutMs?, retries? }` です（`team` なし、`using()` なし）。`config` は `{ baseUrl?, runtimeToken?, connectionName?, timeoutMs?, maxRetries?, fetch? }` を追加します。

### エクスポート

```ts
import {
  Connector,
  ProjectConnector,
  OpenConnector,
  ConnectorError,
  isRetryable,
} from "@oomol-lab/connector";
import type {
  ClientConfig, CallOptions, ScopeOptions, RawResult,
  ProxyRequest, ProxyResponse, ProxyMethod,
  CatalogApi, ActionMetadata, ProviderMetadata, ProviderQuery,
  AppsApi, ConnectedApp,
  ConnectorErrorCode,
  ProjectConnectorConfig, ProjectCallOptions, ProjectExecuteOptions,
  ConnectionRequest, ConnectedAccount, ProviderSelector,
  ConnectedAccountProfile, ProviderUserProfile, ProviderUserKind,
  OAuthConnectInput, ApiKeyConnectInput, CustomCredentialConnectInput,
  OpenConnectorConfig, OpenConnectorApi, OpenCallOptions, OpenExecuteOptions,
  OpenCatalogApi, OpenAppsApi, OpenHealth,
  OpenActionMetadata, OpenActionFollowUp, OpenActionAsyncLifecycle,
  OpenActionSearchResult, OpenSearchQuery,
} from "@oomol-lab/connector";
```

runnable で type-checked な examples は repository の [`examples/`](https://github.com/oomol-lab/connector-sdk/tree/main/examples) directory にあります。

## ライセンス

MIT。詳しくは [connector-sdk](https://github.com/oomol-lab/connector-sdk) repository を参照してください。
