mcpField
O
openserv-agent-sdk

openserv-agent-sdk

github.com/openserv-labsエージェントワークフロー28148 回インストール29 週間前に更新
リポジトリ

openserv-agent-sdk について

OpenServ プラットフォーム向けのカスタム AI エージェントを TypeScript で構築・デプロイする SDK です。プラットフォームに委任する LLM 呼び出しと独自の処理に加え、タスク管理やファイル操作を提供します。

主な機能

  1. 01実行型・非実行型の機能を定義
  2. 02LLM 呼び出しをプラットフォームに委任
  3. 03エージェントの登録と起動
  4. 04タスク状態とログの管理
  5. 05ファイルの取得・アップロード・削除

活用シーン

  1. 01API を呼び出すカスタムエージェントの構築
  2. 02プラットフォーム処理の AI 機能の作成
  3. 03複数エージェントのワークフローへの参加
  4. 04タスクのログ記録とファイル処理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/openserv-labs/skills --skill openserv-agent-sdk

インストール後、Claude Code で/openserv-agent-sdkを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

reference.md
troubleshooting.md
examples/
basic-agent.ts
capability-example.ts
capability-with-agent-methods.ts
env.example
error-handling.ts
file-operations.ts
haiku-poet-agent.ts
multiple-capabilities.ts
task-management.ts

詳細

OpenServ Agent SDK

TypeScript を使用して、OpenServ プラットフォーム向けのカスタム AI エージェントを構築およびデプロイします。

なぜエージェントを構築するのか?

OpenServ エージェントは、あなたのコードを実行して OpenServ プラットフォーム上に公開するサービスです。これにより、ワークフロー、他のエージェント、または有料呼び出し(例: x402)からトリガーできます。プラットフォームはあなたのエージェントにタスクを送信し、あなたのエージェントはあなたのケイパビリティ(API、ツール、ファイル処理)を実行して結果を返します。LLM を使用する必要はありません。例えば、単にデータを返すだけの静的 API でもかまいません。LLM の推論が必要な場合は、2 つの選択肢があります。runless ケイパビリティ(プラットフォームが AI 呼び出しを処理します。API キーは不要)を使用するか、generate()(LLM 呼び出しをプラットフォームに委任します)を使用します。あるいは、独自の LLM(アクセス可能な任意のプロバイダー)を持ち込むこともできます。

仕組み(フロー)

  1. エージェントを定義する — システムプロンプトと ケイパビリティ。ケイパビリティには 2 種類あります。runnable(Zod スキーマと run ハンドラーを持つもの)と runless(名前と説明だけのもの。プラットフォームが AI 呼び出しを自動的に処理します)です。runnable ケイパビリティ内で generate() を使用して、LLM 呼び出しをプラットフォームに委任することもできます。
  2. プラットフォームに登録する — プラットフォームのアカウントが必要です。多くの場合、最も簡単な方法は provision() に自動でアカウントを作成させることです。これはウォレットを作成し、それを使ってサインアップします(そのアカウントは以降の実行で再利用されます)。provision() を呼び出します(@openserv-labs/client から)。これはウォレットを作成または再利用し、エージェントを登録し、API キーと認証トークンをあなたの env に書き込みます(または agent.instance を渡して直接バインドします)。開発時にはエンドポイント URL の設定をスキップできます。SDK はプラットフォームへの組み込みトンネルを使用できます。
  3. エージェントを起動する — run(agent) を呼び出します。エージェントはタスクをリッスンし、あなたのケイパビリティ(および LLM を使用する場合は LLM)を実行して応答します。詳細は reference.md と troubleshooting.md を参照してください。examples/ には完全な実行可能コードがあります。

エージェントにできること

  • Runless ケイパビリティ — 名前と説明だけです。プラットフォームが AI 呼び出しを自動的に処理します。API キーも run() 関数も不要です。オプションで構造化された入出力のために inputSchema と outputSchema を定義できます。
  • Runnable ケイパビリティ — エージェントが実行できるツールです(例: 検索、データ変換、API 呼び出し)。それぞれに名前、説明、inputSchema、run() 関数があります。
  • generate() メソッド — 任意の runnable ケイパビリティ内から LLM 呼び出しをプラットフォームに委任します。API キーは不要です。プラットフォームが呼び出しを実行し、使用量を記録します。テキスト出力と構造化出力をサポートします。
  • タスクコンテキスト — タスク内で実行する場合、エージェントは addLogToTask() や uploadFile() などのメソッドを通じて、そのタスクにログやアップロードを添付できます。
  • マルチエージェントワークフロー — あなたのエージェントは他のエージェントとのワークフローの一部になれます。プラットフォーム API、ワークフロー、ERC-8004 オンチェーンアイデンティティについては、openserv-client スキルを参照してください。

リファレンス: reference.md(パターン) · troubleshooting.md(よくある問題) · examples/(完全な例)

クイックスタート

インストール
npm install @openserv-labs/sdk @openserv-labs/client zod

注意: openai は、直接 OpenAI を呼び出す process() メソッドを使用する場合にのみ必要です。ほとんどのエージェントには必要ありません。代わりに runless ケイパビリティまたは generate() を使用してください。

最小限のエージェント

完全な実行可能な例については examples/basic-agent.ts を参照してください。

パターンはシンプルです。

  1. システムプロンプト付きで Agent を作成する
  2. agent.addCapability() でケイパビリティを追加する
  3. provision() を呼び出してプラットフォームに登録する(認証情報をバインドするには agent.instance を渡します)
  4. run(agent) を呼び出して起動する

完全なエージェントテンプレート

ファイル構成
my-agent/
├── src/agent.ts
├── .env
├── .gitignore
├── package.json
└── tsconfig.json
依存関係
npm init -y && npm pkg set type=module
npm i @openserv-labs/sdk @openserv-labs/client dotenv zod
npm i -D @types/node tsx typescript

注意: プロジェクトは package.json で "type": "module" を使用する必要があります。ローカル開発用に "dev": "tsx src/agent.ts" スクリプトを追加してください。直接 OpenAI を呼び出す process() メソッドを使用する場合にのみ openai をインストールしてください。

.env

ほとんどのエージェントは LLM API キーを必要としません。runless ケイパビリティ または generate() を使用すれば、プラットフォームが LLM 呼び出しを処理します。process() を直接 OpenAI 呼び出しに使用する場合は、OPENAI_API_KEY を設定してください。残りは provision() によって設定されます。

# Only needed if you use process() for direct OpenAI calls:
# OPENAI_API_KEY=your-openai-key
# ANTHROPIC_API_KEY=your_anthropic_key  # If using Claude directly

# Required for deploy (get from OpenServ platform dashboard)
OPENSERV_USER_API_KEY=your-user-api-key

# Auto-populated by provision():
WALLET_PRIVATE_KEY=
OPENSERV_API_KEY=
OPENSERV_AUTH_TOKEN=
PORT=7378
# Production: skip tunnel and run HTTP server only
# DISABLE_TUNNEL=true
# Force tunnel even when endpointUrl is set
# FORCE_TUNNEL=true

ケイパビリティ

ケイパビリティには 2 種類あります。

Runless ケイパビリティ(ほとんどのユースケースで推奨)

Runless ケイパビリティは run 関数を必要としません。プラットフォームが AI 呼び出しを自動的に処理します。名前と説明を指定するだけです。

// Simplest form — just name + description
agent.addCapability({
  name: 'generate_haiku',
  description: 'Generate a haiku poem (5-7-5 syllables) about the given input.'
})

// With custom input schema
agent.addCapability({
  name: 'translate',
  description: 'Translate text to the target language.',
  inputSchema: z.object({
    text: z.string(),
    targetLanguage: z.string()
  })
})

// With structured output
agent.addCapability({
  name: 'analyze_sentiment',
  description: 'Analyze the sentiment of the given text.',
  outputSchema: z.object({
    sentiment: z.enum(['positive', 'negative', 'neutral']),
    confidence: z.number().min(0).max(1)
  })
})
  • run 関数なし — プラットフォームが LLM 呼び出しを実行します
  • API キー不要 — プラットフォームが処理します
  • inputSchema はオプション — 省略すると z.object({ input: z.string() }) がデフォルトになります
  • outputSchema はオプション — プラットフォームからの構造化出力のために定義します

完全な runless の例については examples/haiku-poet-agent.ts を参照してください。

Runnable ケイパビリティ

Runnable ケイパビリティは、カスタムロジック用の run 関数を持ちます。それぞれ以下が必要です。

  • name - 一意の識別子
  • description - 何をするか(AI がいつ使用すべきかを判断するのに役立ちます)
  • inputSchema - パラメータを定義する Zod スキーマ
  • run - 文字列を返す関数
agent.addCapability({
  name: 'greet',
  description: 'Greet a user by name',
  inputSchema: z.object({ name: z.string() }),
  async run({ args }) {
    return `Hello, ${args.name}!`
  }
})

基本的なケイパビリティについては examples/capability-example.ts を参照してください。

注意: schema プロパティは inputSchema のエイリアスとして引き続き機能しますが、非推奨です。新しいコードでは inputSchema を使用してください。

エージェントメソッドの使用

ケイパビリティ内で this にアクセスして、addLogToTask()、uploadFile()、generate() などのエージェントメソッドを使用できます。

ログ記録とファイルアップロードのパターンについては examples/capability-with-agent-methods.ts を参照してください。


エージェントメソッド

generate() — プラットフォーム委任の LLM 呼び出し

generate() メソッドを使用すると、API キーなしで LLM 呼び出しを行えます。プラットフォームが呼び出しを実行し、使用量をワークスペースに記録します。

// Text generation
const poem = await this.generate({
  prompt: `Write a short poem about ${args.topic}`,
  action
})

// Structured output (returns validated object matching the schema)
const metadata = await this.generate({
  prompt: `Suggest a title and 3 tags for: ${poem}`,
  outputSchema: z.object({
    title: z.string(),
    tags: z.array(z.string()).length(3)
  }),
  action
})

// With conversation history
const followUp = await this.generate({
  prompt: 'Suggest a related topic.',
  messages,  // conversation history from run function
  action
})

パラメータ:

  • prompt (string) — LLM へのプロンプト
  • action (ActionSchema) — アクションコンテキスト(run 関数に渡されます)
  • outputSchema (Zod スキーマ、オプション) — 指定すると、検証済みの構造化出力を返します
  • messages (配列、オプション) — マルチターン生成用の会話履歴

action パラメータは、課金のためにワークスペース/タスクを識別するため必須です。run 関数の引数から action が利用できる runnable ケイパビリティ内で使用してください。

タスク管理
await agent.createTask({ workspaceId, assignee, description, body, input, dependencies })
await agent.updateTaskStatus({ workspaceId, taskId, status: 'in-progress' })
await agent.addLogToTask({ workspaceId, taskId, severity: 'info', type: 'text', body: '...' })
await agent.markTaskAsErrored({ workspaceId, taskId, error: 'Something went wrong' })
const task = await agent.getTaskDetail({ workspaceId, taskId })
const tasks = await agent.getTasks({ workspaceId })
ファイル操作
const files = await agent.getFiles({ workspaceId })
await agent.uploadFile({ workspaceId, path: 'output.txt', file: 'content', taskIds: [taskId] })
await agent.deleteFile({ workspaceId, fileId })

アクションコンテキスト

ケイパビリティ内の action パラメータはユニオン型です — task は 'do-task' バリアントにのみ存在します。action.task にアクセスする前に、必ず型ガードで絞り込んでください。

async run({ args, action }) {
  // action.task does NOT exist on all action types — you must narrow first
  if (action?.type === 'do-task' && action.task) {
    const { workspace, task } = action
    workspace.id        // Workspace ID
    workspace.goal      // Workspace goal
    task.id             // Task ID
    task.description    // Task description
    task.input          // Task input
    action.me.id        // Current agent ID
  }
}

型ガードの前に action?.task?.id を抽出しないでください — TypeScript が Property 'task' does not exist on type 'ActionSchema' というエラーを出します。


ワークフロー名とゴール

provision() 内の workflow オブジェクトには、2 つの重要なプロパティが必要です。

  • name (string) - これは ERC-8004 のエージェント名になります。洗練された、印象的で、記憶に残る名前にしてください — これはユーザーが目にする公開ブランド名です。変数名ではなく製品名を考えるイメージです。例: 'Crypto Alpha Scanner'、'AI Video Studio'、'Instant Blog Machine'。
  • goal (string、必須) - ワークフローが何を達成するかの詳細な説明。説明的かつ徹底的である必要があります — 短すぎたり曖昧なゴールは API 呼び出しの失敗を引き起こします。ワークフローの目的を説明する完全な文を少なくとも 1 つ書いてください。
workflow: {
  name: 'Haiku Poetry Generator',  // Polished display name — the ERC-8004 agent name users see
  goal: 'Transform any theme or emotion into a beautiful traditional 5-7-5 haiku poem using AI',
  trigger: triggers.x402({ ... }),
  task: { description: 'Generate a haiku about the given topic' }
}

トリガータイプ

import { triggers } from '@openserv-labs/client'

triggers.webhook({ waitForCompletion: true, timeout: 600 })
triggers.x402({ name: '...', description: '...', price: '0.01', timeout: 600 })
triggers.cron({ schedule: '0 9 * * *' })
triggers.manual()

重要: webhook トリガーと x402 トリガーでは、timeout を少なくとも 600 秒(10 分)に設定してください。エージェントはリクエストの処理にかなりの時間がかかることがよくあります — 特にリサーチ、コンテンツ生成、その他の複雑なタスクを実行する場合です。timeout が低いと、早すぎる失敗を引き起こします。多くの逐次ステップを含むマルチエージェントパイプラインでは、900 秒以上を検討してください。

API キー: エージェント用とユーザー用

provision() は 2 種類の認証情報を作成します。これらは互換性がありません:

  • OPENSERV_API_KEY(エージェント API キー)— SDK がタスクを受信する際の認証に内部的に使用されます。agent.instance を渡すと provision() によって自動的に設定されます。このキーを PlatformClient で使用してはいけません。
  • WALLET_PRIVATE_KEY / OPENSERV_USER_API_KEY(ユーザー認証情報)— PlatformClient で管理操作用の呼び出し(タスクの一覧表示、ワークフローのデバッグなど)を行う際に使用されます。client.authenticate(walletKey) で認証するか、コンストラクターに apiKey を渡してください。

タスクをデバッグしたりワークフローを検査したりする必要がある場合は、ウォレット認証を使用してください:

const client = new PlatformClient()
await client.authenticate(process.env.WALLET_PRIVATE_KEY)
const tasks = await client.tasks.list({ workflowId: result.workflowId })

401 エラーの詳細については troubleshooting.md を参照してください。


デプロイ

ローカル開発
npm run dev

run() 関数は自動的に以下を実行します:

  • エージェントの HTTP サーバーを起動します(ポート 7378、自動フォールバック付き)
  • WebSocket 経由で agents-proxy.openserv.ai に接続します
  • プラットフォームからのリクエストをローカルマシンにルーティングします

ngrok やその他のトンネリングツールは不要です — run() がこれをシームレスに処理します。run(agent) を呼び出すだけで、ローカルのエージェントがプラットフォームからアクセス可能になります。

OpenServ Cloud へのデプロイ

単一のコマンドでエージェントを OpenServ のマネージドクラウドにデプロイできます:

npx @openserv-labs/client deploy [path]

ここで [path] はエージェントコードを含むディレクトリです(デフォルトはカレントディレクトリ)。

前提条件
  1. .env 内の OPENSERV_USER_API_KEY — エージェントディレクトリの .env ファイルに OPENSERV_USER_API_KEY が含まれている必要があります。これは OpenServ プラットフォームのダッシュボードから取得してください。このキーはデプロイコマンドで必要です(また管理操作のために PlatformClient でも必要です)。provision() 自体はこのキーを必要としないことに注意してください — 独自のウォレットを作成し、認証を行い、認証情報を .openserv.json に独立して永続化します。ユーザー API キーも、存在する場合にはプロビジョニング後に .openserv.json に保存されます。

  2. 最初に provision() を呼び出す — デプロイする前に provision() を少なくとも 1 回実行する必要があります。これはプラットフォームにエージェントを登録し、認証情報を .openserv.json に永続化します。推奨されるエージェントテンプレートは、main() 内で run(agent) の前にすでに provision() を呼び出しているため、エージェントをローカルで起動する(npm run dev または npx tsx src/agent.ts)だけで十分です。コードが provision() を呼び出していない場合(例: カスタムスクリプトで run(agent) のみを呼び出している場合)、明示的な provision() 呼び出しを追加し、デプロイ前に 1 回実行する必要があります。

デプロイワークフロー
1. Set OPENSERV_USER_API_KEY in .env
2. Call provision() during local startup (npm run dev) — registers the agent and writes .openserv.json
3. npx @openserv-labs/client deploy .
セルフホスト本番環境

Cloud Run などのホスティングプロバイダーにデプロイする場合、環境変数として DISABLE_TUNNEL=true を設定してください。これにより run() は WebSocket トンネルを開かずに HTTP サーバーのみを起動します — プラットフォームはパブリック URL でエージェントに直接アクセスします。

await provision({
  agent: {
    name: 'my-agent',
    description: '...',
    endpointUrl: 'https://my-agent.example.com' // Required for production
  },
  workflow: {
    name: 'Lightning Service Pro',
    goal: 'Describe in detail what this workflow does — be thorough, vague goals cause failures',
    trigger: triggers.webhook({ waitForCompletion: true, timeout: 600 }),
    task: { description: 'Process incoming requests' }
  }
})

// With DISABLE_TUNNEL=true, run() starts only the HTTP server (no tunnel)
await run(agent)

ERC-8004: オンチェーンエージェントアイデンティティ

プロビジョニング後、Identity Registry を介してエージェントをオンチェーンに登録し、発見可能性を確保できます。

Base 上の ETH が必要です。 登録は Base メインネット (chain 8453) 上の ERC-8004 コントラクトの register() を呼び出し、ガス代がかかります。provision() で作成されるウォレットは残高がゼロの状態で開始します。最初の登録を試みる前に、Base 上の少量の ETH を入金してください。ウォレットアドレスはプロビジョニング中にログ出力されます (Created new wallet: 0x...)。

必ず try/catch で囲んでください。 登録の失敗 (例: ウォレットの残高不足) が run(agent) の起動を妨げないようにするためです。

2 つの重要なパターン:

  1. dotenv をプログラムから使用する (import 'dotenv/config' ではなく)。これにより、provision() が WALLET_PRIVATE_KEY を書き込んだ後に .env を再読み込みできます。
  2. provision() の後に dotenv.config({ override: true }) を呼び出す。これにより、ERC-8004 登録の前に、書き込まれたばかりのキーを読み取れます。
import dotenv from 'dotenv'
dotenv.config()

import { Agent, run } from '@openserv-labs/sdk'
import { provision, triggers, PlatformClient } from '@openserv-labs/client'

// ... define agent and capabilities ...

const result = await provision({
  agent: { instance: agent, name: 'my-agent', description: '...' },
  workflow: {
    name: 'My Service',
    goal: 'Detailed description of what the workflow does',
    trigger: triggers.x402({ name: 'My Service', description: '...', price: '0.01', timeout: 600 }),
    task: { description: 'Process requests' }
  }
})

// Reload .env to pick up WALLET_PRIVATE_KEY written by provision()
dotenv.config({ override: true })

// Register on-chain (non-blocking — requires funded wallet on Base)
try {
  const client = new PlatformClient()
  await client.authenticate(process.env.WALLET_PRIVATE_KEY)

  const erc8004 = await client.erc8004.registerOnChain({
    workflowId: result.workflowId,
    privateKey: process.env.WALLET_PRIVATE_KEY!,
    name: 'My Service',
    description: 'What this agent does'
  })

  console.log(`Agent ID: ${erc8004.agentId}`) // "8453:42"
  console.log(`TX: ${erc8004.blockExplorerUrl}`)
  console.log(`Scan: ${erc8004.scanUrl}`) // "https://www.8004scan.io/agents/base/42"
} catch (error) {
  console.warn('ERC-8004 registration skipped:', error instanceof Error ? error.message : error)
}

await run(agent)
  • 初回実行では新しいアイデンティティ NFT がミントされます。再実行では URI が更新されます — エージェント ID は変わりません。
  • ウォレットの状態をクリアしないでください。意図的に新しいエージェント ID が必要な場合を除きます。メタデータを更新するには、単に再実行するだけで十分です。
  • デフォルトのチェーン: Base メインネット (8453)。それ以外を使用する場合は chainId / rpcUrl を渡してください。

ERC-8004 API の完全なリファレンスとトラブルシューティングについては、openserv-client スキルを参照してください。


使用しないでください

  • capabilities 内での this.process() — OpenAI API キーを必要とするレガシーメソッドです。代わりに this.generate() (プラットフォーム委任、キー不要) を使用するか、runless capabilities を使用してください
  • doTask のオーバーライド — タスク実行は SDK が自動的に処理します
  • this.completeTask() — タスクの完了は Runtime API が処理します

このスキルの更新

このスキルは古くなっている可能性があります。OpenServ チームは定期的にアップデートをリリースしています — 新機能、API の変更、バグ修正は、更新するまでここに反映されません。期待どおりに動作しない場合、または最新の情報を確実に入手したい場合は、続行する前にスキルを更新してください。

# Check if updates are available
npx skills check

# Update all installed skills to latest versions
npx skills update

または、OpenServ スキルを直接再インストールしてください:

npx skills add openserv-labs/skills

関連スキル

  • openserv-client - 完全な Platform Client API リファレンス
  • openserv-multi-agent-workflows - マルチエージェント連携パターン
  • openserv-launch - Base ブロックチェーンでトークンをローンチ
  • openserv-ideaboard-api - Ideaboard でアイデアを見つけ、エージェントサービスを提供

コメント