---
title: "Strands Agents TypeScript SDKの使い方：npm導入からMCP・steering・AgentCoreデプロイまで【1.24対応】"
url: "https://www.issoh.co.jp/tech/details/10146/"
published: 2025-12-05
updated: 2026-11-09
categories: ["AIエージェント・MCP"]
publisher: "株式会社一創"
---

# Strands Agents TypeScript SDKの使い方：npm導入からMCP・steering・AgentCoreデプロイまで【1.24対応】

Strands AgentsのTypeScript SDK（npmパッケージ `@strands-agents/sdk`）は、2025年12月3日にプレビューとして公開され、2026年4月30日に1.0になりました。2026年11月9日時点の最新は1.24.0（11月4日公開）です。この記事では、TypeScriptで使い始める手順、Zodによるツール定義、MCP接続、実行上限、steering、Amazon Bedrock AgentCore Runtimeへのデプロイを、1.24.0で型チェックしたコードで説明します。Strands Agents全体の設計やPython版の使い方は[Strands Agentsとは？読み方・意味とPython SDKの使い方](/tech/details/7199/)にまとめています。

コードは `tsc`（`strict` 有効）で型チェックし、ツール実行・steering・MCP接続・HTTPの応答形式は、モデル呼び出しを台本どおりに応答するテスト用実装へ差し替えて動かしました。Bedrockなど実際のモデルを呼んだ結果ではありません。

## まとめ：TypeScript SDKで押さえる要点

- 導入は `npm install @strands-agents/sdk zod`。Node.js 22以上が必須で（1.17.0でNode.js 20を打ち切り）、ESM（`"type": "module"`）で書きます。
- 1.20.0でMCPの必須peer依存が `@modelcontextprotocol/client` 2.xへ替わりました。import元は `@modelcontextprotocol/client/stdio` です。旧 `@modelcontextprotocol/sdk` は自動では入らなくなっています。
- 本番では `invoke()` に `limits` と `cancelSignal` を渡します。指定しなければターン数にもトークン総量にも上限がありません。
- モデルを指定しないとBedrockの `global.anthropic.claude-sonnet-4-6` が使われ、`maxTokens` も1.23.0からモデルの上限値（Sonnet 4.6は128,000）になります。どちらも明示して固定します。
- strands steeringは、`SteeringHandler` を `interventions` に登録し、ツール実行の直前にエージェントへ指示を返す仕組みです。
- AgentCore Runtimeには、`GET /ping` と `POST /invocations` をポート8080で受けるARM64コンテナか、Node.jsのZIPでデプロイします。
- 双方向音声ストリーミング（`BidiAgent`）、Ollama・LiteLLMなどのプロバイダーはTypeScript版にありません。これらが要件ならPython版を選びます。

## @strands-agents/sdkの現行版と動作要件

[npmレジストリ](https://www.npmjs.com/package/@strands-agents/sdk)と[公式changelog](https://strandsagents.com/changelog/)で確認した、2026年11月9日時点の要件です。

| 項目       | 内容                                           |
| -------- | -------------------------------------------- |
| npmパッケージ | `@strands-agents/sdk`                        |
| 最新版      | 1.24.0（2026-11-04）                           |
| 1.0公開    | 2026-04-30                                   |
| プレビュー公開  | 2025-12-03（0.1.0）                            |
| Node.js  | 22以上（1.17.0から）                               |
| モジュール形式  | ESM（`"type": "module"`）                      |
| ライセンス    | Apache-2.0                                   |
| ソースの場所   | `strands-agents/harness-sdk` の `strands-ts/` |
| 週間ダウンロード | 691,685（2026-11-01〜11-07）                    |

Node.js 20から移れない環境では、`engines` が `>=20.0.0` のままだった1.16.0が上限です。現行のLTSと切り替え時期は[Node.js LTSとは？現行版の確認とlts/\*の固定・移行時期を実装目線で解説](/tech/details/17906/)で確認できます。

### リポジトリ移転とプレビュー期の情報の読み替え

旧リポジトリ `strands-agents/sdk-typescript` は2026年6月3日にアーカイブされ、ソースはPython SDK・ドキュメントと同じ `strands-agents/harness-sdk` へ移りました。GitHubのリリースタグは `typescript/v1.24.0` の形式です。旧リポジトリやNode.js 20前提の解説は現行の手順ではありません。

2025年のプレビュー期の解説で「未対応」とされていたGraph・Swarm、構造化出力、セッション永続化、A2Aは、1.0の候補版までに追加されています。

### 1.x系で破壊的変更が入った9つの版と版の固定

メジャー番号は1のままですが、changelogとGitHubのリリースノートで破壊的変更と示された変更は、1.x系の9つの版に入っています。

| 版      | 公開日        | 破壊的変更                                        |
| ------ | ---------- | -------------------------------------------- |
| 1.6.0  | 2026-06-16 | ミドルウェアのコンテキスト入力をコピーして渡す                      |
| 1.9.0  | 2026-07-10 | `LocalMemoryStore` を `TestMemoryStore` に改名   |
| 1.12.0 | 2026-08-07 | サンドボックス経由のbashツールを `shell` に改名               |
| 1.14.0 | 2026-08-21 | Bedrockのautoモードでシステムプロンプトをキャッシュ              |
| 1.17.0 | 2026-09-08 | Node.js 22以上を必須化                             |
| 1.20.0 | 2026-10-08 | MCPのpeer依存を `@modelcontextprotocol/client` へ |
| 1.21.0 | 2026-10-14 | ContextManagerのstashの保存先の扱いを変更               |
| 1.22.0 | 2026-10-21 | `makeSubagent` の `mcpServers` を廃止            |
| 1.23.0 | 2026-10-30 | subagent・swarmの割り込みを親に永続化                    |

直近で影響が広いのは1.20.0です。1.21.0〜1.23.0の3つは、stash・subagent・swarmを使っている場合だけ確認すれば足ります。`package.json` で `^1.24.0` と書くと、ロックファイルを作り直したときや `npm update` のときに1.xの新しいマイナー版まで解決されます。本番では完全一致か `~1.24.0` で固定し、上げる前にリリースノートを確認してください。

## インストールとTypeScriptプロジェクトの設定（npm）

空のディレクトリから始める手順です。SDK本体は1.24.0に完全一致で固定します。

```
mkdir strands-ts-agent && cd strands-ts-agent
npm init -y
npm pkg set type=module
npm install --save-exact @strands-agents/sdk@1.24.0
npm install zod
npm install -D typescript tsx @types/node
```

`@modelcontextprotocol/client` は必須のpeer依存なので、npm 7以降なら自動で入ります（今回は2.4.0）。`openai`・`@anthropic-ai/sdk`・`@google/genai`・`@ai-sdk/provider`・`express` などは任意のpeer依存で、使うときだけ追加します。

```
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "rootDir": "src",
    "outDir": "dist",
    "skipLibCheck": true,
    "types": ["node"]
  },
  "include": ["src/**/*.ts"]
}
```

`"types": ["node"]` を省くと、TypeScript 7.0.2では `process` や `node:path` が TS2591 で解決できません。`"rootDir": "src"` が無いと `npx tsc` は TS5011 で止まり、出力も `dist/src/` の下になります。実行は `npx tsx src/agent.ts`、ビルドするなら `npx tsc` のあと `node dist/agent.js` です。既定のBedrockには、AWSの認証情報か環境変数 `AWS_BEARER_TOKEN_BEDROCK` のBedrock APIキーが要ります。

## 初回エージェントとZodツールの実装

単語に含まれる文字を数えるツールを持たせた最小構成です。「ツールを呼ぶ→結果を読んで答える」というループを確かめられます。

```
import { Agent, BedrockModel, tool } from '@strands-agents/sdk'
import { z } from 'zod'

// ツールは Zod スキーマで入力を宣言する。callback の引数は型推論される
const letterCounter = tool({
  name: 'letter_counter',
  description: '単語の中に指定した文字が何回出てくるかを数える',
  inputSchema: z.object({
    word: z.string().describe('調べる単語'),
    letter: z.string().length(1).describe('数える1文字'),
  }),
  callback: ({ word, letter }) => {
    const count = [...word.toLowerCase()].filter((c) => c === letter.toLowerCase()).length
    return `「${word}」に「${letter}」は${count}回出てきます`
  },
})

// 既定値に任せず、リージョン・モデルID・出力上限を明示して固定する
const model = new BedrockModel({
  region: 'us-west-2',
  modelId: 'global.anthropic.claude-sonnet-4-6',
  maxTokens: 4096,
})

const agent = new Agent({
  model,
  systemPrompt: 'あなたは文字数を正確に数えるアシスタントです。',
  tools: [letterCounter],
})

const result = await agent.invoke('strawberry に r はいくつありますか？')
console.log(result.stopReason) // endTurn
console.log(result.toString()) // 最終回答のテキスト
```

テスト用モデルに `letter_counter` を呼ばせると、ツール結果「「strawberry」に「r」は3回出てきます」が次のターンの入力に積まれ、`stopReason` が `endTurn` で終わりました。モデルIDや `maxTokens` を省くと「using default modelId, which is subject to change」のような警告が出ます。既定値は版で変わるので、上のように書いておきます。

### モデルプロバイダーの切り替え

BedrockはSDK本体から、他のプロバイダーはサブパスからimportします。既定のモデルIDは1.24.0の `defaults.js` の値です。

| プロバイダー         | import元                                | 既定のモデルID                             |
| -------------- | -------------------------------------- | ------------------------------------ |
| Amazon Bedrock | `@strands-agents/sdk`                  | `global.anthropic.claude-sonnet-4-6` |
| Anthropic      | `@strands-agents/sdk/models/anthropic` | `claude-sonnet-4-6`                  |
| OpenAI         | `@strands-agents/sdk/models/openai`    | `gpt-5.4`                            |
| Google         | `@strands-agents/sdk/models/google`    | `gemini-2.5-flash`                   |
| Vercel AI SDK  | `@strands-agents/sdk/models/vercel`    | ラップ元に従う                              |

```
import { Agent } from '@strands-agents/sdk'
import { AnthropicModel } from '@strands-agents/sdk/models/anthropic'
import { OpenAIModel } from '@strands-agents/sdk/models/openai'

// Anthropic API を直接使う（ANTHROPIC_API_KEY を読む）
const claude = new Agent({ model: new AnthropicModel({ modelId: 'claude-sonnet-4-6', maxTokens: 4096 }) })

// OpenAI（OPENAI_API_KEY を読む）。api は 'chat' か 'responses'
const gpt = new Agent({ model: new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4' }) })

// 文字列を渡すと Bedrock のモデルIDとして扱われる
const bedrock = new Agent({ model: 'global.anthropic.claude-sonnet-4-6' })

void claude; void gpt; void bedrock
```

[公式の対応表](https://strandsagents.com/docs/user-guide/sdk/model-providers/)では、Ollama・LiteLLM・Mistral・Cohere・SageMaker・llama.cpp・Writer・LlamaAPI・Amazon Novaの専用プロバイダーはPython版だけの対応です。BedrockModel経由のNovaモデル利用とは区別してください。足りないプロバイダーは、Vercel AI SDKのプロバイダーを `VercelModel` で包めないかを先に確かめます。

### 構造化出力の型付け

`structuredOutputSchema` にZodスキーマを渡すと、モデルの出力をスキーマで検証し、失敗すれば再試行させます。

```
import { Agent, BedrockModel, StructuredOutputError } from '@strands-agents/sdk'
import { z } from 'zod'

const model = new BedrockModel({
  region: 'us-west-2',
  modelId: 'global.anthropic.claude-sonnet-4-6',
  maxTokens: 4096,
})

const Ticket = z.object({
  title: z.string().describe('問い合わせの要約'),
  priority: z.enum(['low', 'medium', 'high']),
  product: z.string(),
})

const agent = new Agent({ model, structuredOutputSchema: Ticket })

try {
  const result = await agent.invoke('請求画面が500エラーで開けません。月末締めに間に合わないので急ぎです。')
  // structuredOutput は unknown 型。検証済みなので z.infer で型を付ける
  const t = result.structuredOutput as z.infer<typeof Ticket>
  console.log(t.priority, t.title)
} catch (e) {
  if (e instanceof StructuredOutputError) console.error('検証に失敗:', e.message)
  else throw e
}
```

公式READMEには「fully typed」とありますが、1.24.0でも `result.structuredOutput` は実質 `unknown` で、そのまま `.priority` を読むと `tsc` が TS18046 で止まります。公式の構造化出力ガイドと同じく `z.infer` で受けてください。

## limitsとcancelSignalによる実行上限と中断要求

エージェントはモデルが終わると判断するまでループします。上限を指定しないと、ツールを呼び続けるモデルの応答がそのまま課金になるので、[公式のライフサイクル制御](https://strandsagents.com/docs/user-guide/sdk/agents/lifecycle-controls/)にある `limits` を本番では必ず渡します。

```
import { Agent, BedrockModel } from '@strands-agents/sdk'

const agent = new Agent({
  model: new BedrockModel({ region: 'us-west-2', modelId: 'global.anthropic.claude-sonnet-4-6', maxTokens: 4096 }),
})

const result = await agent.invoke('未処理の問い合わせを分類して', {
  limits: { turns: 6, totalTokens: 20_000 },
  cancelSignal: AbortSignal.timeout(30_000), // 30秒後に中断を要求。開始済みツールの停止は協調動作
})

if (result.stopReason !== 'endTurn') console.warn('途中で停止:', result.stopReason)
```

| 指定                                | 到達時の stopReason                 |
| --------------------------------- | ------------------------------- |
| `limits.turns`                    | `limitTurns`                    |
| `limits.totalTokens`              | `limitTotalTokens`              |
| `limits.outputTokens`             | `limitOutputTokens`             |
| `limits.structuredOutputAttempts` | `limitStructuredOutputAttempts` |
| `cancelSignal` ／ `agent.cancel()` | `cancelled`                     |

いずれも例外ではなく `stopReason` で返るので、呼び出し側で分岐します（テスト用モデルで `turns: 1` は `limitTurns`、中断済みのシグナルは `cancelled` になりました）。上限はターンの開始前に判定されるため、最後の1ターンでトークン予算を超えることがあり、超過量が小さいとは限りません。`maxTokens` はモデル呼び出し1回ごと、`limits` はリクエスト全体に効く点が違います。`structuredOutputAttempts` で止まったときの `structuredOutput` は `undefined` なので、値を読む前に `stopReason` を確かめます。

## MCPサーバーの接続（McpClient）

MCPサーバーのツールは、`McpClient` を作って `tools` に渡すだけで読み込まれます。例はAWSのドキュメント検索MCPサーバーをstdioで起動する構成です（`uvx` が必要）。

```
import { Agent, BedrockModel, McpClient } from '@strands-agents/sdk'
import { StdioClientTransport } from '@modelcontextprotocol/client/stdio'

// await using でスコープを抜けるときに子プロセスを止める
await using docs = new McpClient({
  transport: new StdioClientTransport({
    command: 'uvx',
    args: ['awslabs.aws-documentation-mcp-server@latest'],
  }),
  toolFilters: { allowed: ['search_documentation', 'read_documentation'] },
})

const agent = new Agent({
  model: new BedrockModel({ region: 'us-west-2', modelId: 'global.anthropic.claude-sonnet-4-6', maxTokens: 4096 }),
  tools: [docs],
})
const result = await agent.invoke('AgentCore Runtime の最大実行時間を公式ドキュメントで調べて', {
  limits: { turns: 6 },
})
console.log(result.toString())
```

`toolFilters` は読み込むツールの絞り込みです。MCPサーバーは数十のツールを持つことがあります。モデルへ渡す選択候補を減らすため、使うツールだけ許可します。

### 1.20.0の移行：@modelcontextprotocol/sdkからclient 2.xへ

[1.20.0の変更](https://github.com/strands-agents/harness-sdk/pull/4093)で、必須のpeer依存は `@modelcontextprotocol/sdk` から `@modelcontextprotocol/client` へ替わりました。1.19以前のコードで使っていた `@modelcontextprotocol/sdk/client/stdio.js` は、1.24.0を入れただけの環境では TS2307 で解決できません。

移行は、import元を上のコードの形に書き換えるだけで済みます。旧パッケージを手で追加すれば旧トランスポートも `McpClient` に渡せて、1.24.0でツール実行まで動きました。とはいえ依存が二重になるので、書き換えるのが素直です。公式の[MCPの解説](https://strandsagents.com/docs/user-guide/sdk/tools/mcp-tools/)はサーバー側の例で旧パッケージを使っているため、クライアント側と読み分けてください。パッケージ分割の背景は[MCP TypeScript SDK v2とは？パッケージ分割とステートレス化の移行要点](/tech/details/15905/)で説明しています。

自動で入るclientは `^2.0.0` の範囲です。2026年10月に公表された脆弱性の修正版は2.3.0なので、ロックファイルが古い環境では版を確かめます。対象と設定変更は[MCP TypeScript SDKの脆弱性：2026年10月の7件の対象版と更新後に要る設定変更](/tech/details/19021/)を参照してください。

## strands steeringによるツール呼び出しへの介入

steeringは、ツールを呼ぶ直前やモデルが応答した直後に、その場で必要な指示だけを返す仕組みです。禁止事項をすべてシステムプロンプトに書く代わりに、違反しそうな瞬間に指示を差し込みます。TypeScript版では1.4.0（2026年6月1日）から `@strands-agents/sdk/vended-interventions/steering` で提供されており、登録先は `plugins` ではなく `interventions` です。

```
import { Agent, tool, InterventionActions } from '@strands-agents/sdk'
import type { BeforeToolCallEvent } from '@strands-agents/sdk'
import { SteeringHandler } from '@strands-agents/sdk/vended-interventions/steering'
import { z } from 'zod'
import { resolve } from 'node:path'

const deleteFile = tool({
  name: 'delete_file',
  description: 'ファイルを削除する',
  inputSchema: z.object({ path: z.string() }),
  callback: ({ path }) => `${path} を削除しました`, // 説明用の模擬処理（実際には削除しない）
})

// /prod 配下の削除はツールを実行させず、理由をエージェントへ返す
// 文字列判定の例。実運用ではツール側でもリンク解決後のパスと権限を検証する
class ProtectProdSteering extends SteeringHandler {
  readonly name = 'protect-prod'

  override beforeToolCall(event: BeforeToolCallEvent) {
    const input = event.toolUse.input as { path?: string }
    const target = resolve(input.path ?? '') // ../ を含むパスを正規化する
    if (event.toolUse.name === 'delete_file' && (target === '/prod' || target.startsWith('/prod/'))) {
      return InterventionActions.guide('/prod 配下は削除できません。削除せずに理由をユーザーへ説明してください。')
    }
    return InterventionActions.proceed()
  }
}

const agent = new Agent({
  tools: [deleteFile],
  interventions: [new ProtectProdSteering()],
})
await agent.invoke('/prod/app.log を消して')
```

テスト用モデルに `/tmp/../prod/app.log` の削除を要求させると、`delete_file` のcallbackは実行されず、ステータスerrorのツール結果として「GUIDANCE: \[protect-prod\] …」が返りました。モデルはこれを読んで次のターンを続けます。

`beforeToolCall` が返せるのは `proceed`・`guide`・`confirm`（人の承認待ち）、`afterModelCall` は `proceed` と `guide` だけです。理由を伝えずに確実に止めたい操作は、`InterventionHandler` を直接継承して `deny` を返すか、Cedarポリシーのハンドラーを使います。判定をLLMに任せたい場合は `LLMSteeringHandler` があります。

効果については、Strandsチームが[公式ブログ](https://strandsagents.com/blog/steering-accuracy-beats-prompts-workflows/)でPython版の評価を公開しています。6シナリオを構成ごとに各100回実行し、steeringの合格率は100%、指示をプロンプトに書いただけの構成は82.5%でした。手順書（SOP）をプロンプトに入れた構成も99.8%でしたが、平均入力トークンは9,879とsteering（3,346）の約3倍です。1つの題材での結果なので、守られない規則から移して比べるのが手堅い進め方です。

## マルチエージェント（Graph・Swarm）のTypeScript実装

`Graph` と `Swarm` はSDK本体からimportできます。Graphは実行順をエッジで決め、Swarmはエージェント自身が次の担当へ引き継ぐかどうかを決めます。

```
import { Agent, BedrockModel, Graph } from '@strands-agents/sdk'

const model = new BedrockModel({ region: 'us-west-2', modelId: 'global.anthropic.claude-sonnet-4-6', maxTokens: 4096 })
const researcher = new Agent({ model, id: 'researcher', systemPrompt: '要点を箇条書きで調べる。' })
const writer = new Agent({ model, id: 'writer', systemPrompt: '調査結果を300字の説明文にまとめる。' })

// researcher の出力が writer へ渡る。依存が揃ったノードから実行される
const graph = new Graph({
  nodes: [researcher, writer],
  edges: [['researcher', 'writer']],
  maxSteps: 10,
  timeout: 120_000, // ミリ秒
})
const result = await graph.invoke('Strands Agents TypeScript SDK の導入手順')
console.log(result.status)
```

テスト用モデルでは、writerへの入力に元のタスク、`[node: researcher]`、researcherの出力が順に並びました。`maxSteps` と `timeout` の既定は無制限で、省くと「graph has no maxSteps or timeout set; execution is unbounded」の警告が出ます。Python版と違って `timeout` の単位はミリ秒なので、移植するときに注意が要ります。Agents as Toolsを含むパターンの使い分けは[Strands Agentsの解説記事](/tech/details/7199/)で扱っています。

## Amazon Bedrock AgentCore Runtimeへのデプロイ

以下のHTTPサーバー例は `src/server.ts`、Dockerfile例はプロジェクト直下の `Dockerfile` に保存します。

TypeScriptのエージェントをAgentCore Runtimeへ載せる方法は、コンテナイメージと、JavaScriptをZIPで渡す[直接コードデプロイ](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-get-started-code-deploy-node.html)（ランタイム `NODE_22`）の2通りです。どちらも `GET /ping` と `POST /invocations` をポート8080で実装します。ここでは[Strands公式ガイド](https://strandsagents.com/docs/user-guide/sdk/deploy/deploy%5Fto%5Fbedrock%5Fagentcore/typescript/)に沿ったコンテナ方式を説明します。

```
npm install express
npm install -D @types/express
```

```
import express from 'express'
import { Agent, BedrockModel } from '@strands-agents/sdk'

const agent = new Agent({
  model: new BedrockModel({ region: 'us-west-2', modelId: 'global.anthropic.claude-sonnet-4-6', maxTokens: 4096 }),
})
const app = express()

// ヘルスチェック（必須）。time_of_last_update は返さない
app.get('/ping', (_req, res) => {
  res.json({ status: 'Healthy' })
})

// 呼び出し（必須）。本文はバイナリで届くので raw で受けて文字列へ戻す
app.post('/invocations', express.raw({ type: '*/*' }), async (req, res) => {
  try {
    const prompt = new TextDecoder().decode(req.body)
    const result = await agent.invoke(prompt, { limits: { turns: 10 } })
    res.json({ response: result.toString(), stopReason: result.stopReason })
  } catch (err) {
    console.error(err)
    res.status(500).json({ error: 'Internal server error' })
  }
})

app.listen(Number(process.env.PORT ?? 8080))
```

`/ping` に現在時刻の `time_of_last_update` を毎回入れてはいけません。[AWSのHTTPプロトコル契約](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-http-protocol-contract.html)によると、毎回進む時刻は状態の変化と扱われ、アイドルタイムアウトが発火しなくなります。セッションが `MaxLifetime` まで残り、セッション数の上限を使い切る原因になるので、以前の例をコピーしたコードは見直してください。

応答は `result.toString()` と `stopReason` で返し、回答の完了と上限による途中停止を呼び出し側で区別できるようにします。公式ガイドの `res.json({ response })` のように `AgentResult` をそのまま返すと、応答JSONに `type`・`stopReason`・`lastMessage` の構造が丸ごと入ります（テスト用モデルで確認）。

```
FROM --platform=linux/arm64 public.ecr.aws/docker/library/node:22-slim
WORKDIR /app
COPY package*.json tsconfig.json ./
RUN npm ci
COPY src ./src
RUN npx tsc
EXPOSE 8080
CMD ["node", "dist/server.js"]
```

公式ガイドのDockerfileはベースイメージが `node:latest` ですが、Node.jsのメジャー版が勝手に上がらないよう22系に固定しています。ビルドしたイメージはECRへpushし、`bedrock-agentcore.amazonaws.com` を信頼するIAMロールを付けてランタイムを作成します。AgentCore CLIには `agent-typescript-strands` テンプレートがあり、[AWSの手順](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-get-started-cli-typescript.html)ではNode.js 22のCodeZipランタイムが作られます。CLIでのデプロイ手順は[AgentCore APIの使い方：SDK・CLI 1.0・InvokeAgentRuntimeでエージェントを本番に載せる手順](/tech/details/8230/)で扱っています。

## Strands harness・Mastraとの使い分けと採用判断

### Strands harness（createHarness）との関係

`@strands-agents/harness`（2026年11月4日公開の0.3.4）は、SDKの上に組み立て済みのエージェントを載せたパッケージです。`await createHarness()` がモデル・ツール・メモリ・セッションの既定値を組み合わせ、通常の `Agent` を返します。SDKはpeer依存（`>=1.19.0 <2.0.0`）です。

汎用エージェントをすぐ動かすならharness、業務システムに組み込んでツールの範囲・介入・モデルを自分で固定したいならSDKを直接使います。harnessは0.x系で、2026年9月の公開から0.3系まで進んでいるため、既定値に依存した本番運用はまだ勧めません。Python版を含む設定は[Strands Harnessの実装手順](/tech/details/18290/)で解説しています。

### TypeScript版を選ばないほうがよい場面

次のどれかが要件ならPython版を選びます。

- 音声の双方向ストリーミング（`BidiAgent`）。1.24.0のパッケージには含まれていません。
- Ollama・LiteLLM・SageMakerなど、公式対応表でPython版だけのプロバイダーを使う構成。
- コールバックハンドラーでストリームを処理する既存コード。TypeScript版は `agent.stream()` の非同期イテレーターかフックで書き直します。

同梱ツールは差ではなくなってきました。TypeScript版の `vended-tools` には、1.20.0以降に `subagent`・`swarm`・`graph`・`python_repl`・`mcp_router`・`a2a_client`・`read`・`write`・`edit` が入っています。`fileEditor` は1.23.0で非推奨になったので、新規コードは `edit` を使います（公式クイックスタートの例はまだ `fileEditor` です）。

TypeScriptのまま別のフレームワークを選ぶなら、AWS（BedrockやAgentCore）を前提にPython版と設計を共有したい場合はStrands、Next.jsなどのWebアプリにワークフローや記憶ごと組み込みたい場合は[Mastra](/tech/details/6062/)が候補です。LLM呼び出しの部品を細かく組み合わせたいなら[LangChain.js](/tech/details/3590/)も選べます。業務システムへの組み込みをまとめて任せたい場合は、当社の[AIエージェント開発](/service/ai/agent/)でも設計から支援しています。

## よくある質問

### Strands AgentsはTypeScriptで使えますか？

使えます。npmの `@strands-agents/sdk` がTypeScript SDKで、2026年4月30日に1.0になり、2026年11月9日時点の最新は1.24.0です。ただし、双方向音声ストリーミングや一部のモデルプロバイダーなど、Python版にしか無い機能が残っています。概要とPython版は[Strands Agentsの解説記事](/tech/details/7199/)で扱っています。

### @strands-agents/sdkのほかにnpmで入れるものは何ですか？

最低限 `zod` を一緒に入れます。MCP用の `@modelcontextprotocol/client` は必須のpeer依存なのでnpm 7以降なら自動で入ります。OpenAI・Anthropic・Googleのモデルを使う場合はそれぞれの公式SDK（`openai`・`@anthropic-ai/sdk`・`@google/genai`）、AgentCore向けのHTTPサーバーには `express` を追加します。

### Node.js 20でも動きますか？

1.17.0（2026年9月8日）以降はNode.js 22以上が必須で、20はサポート外です。Node.js 20に留まる場合、`engines` が20以上のままだった1.16.0が上限になります。1.16.0にはMCP client 2.xへの切り替えや `limits.structuredOutputAttempts` が入っていないので、Node.js 22へ上げることを勧めます。

### strands steeringとは何ですか？

エージェントがツールを呼ぶ直前やモデルが応答した直後に、その場で必要な指示を返す仕組みです。TypeScript版では `SteeringHandler` を継承し、`interventions` に登録して使います。返せるのは続行・指示・人の承認待ちだけで、拒否が必要な操作は `InterventionHandler` の `deny` で扱います。

### Bedrock以外のモデル（OpenAI・Claude API・Gemini）は使えますか？

使えます。OpenAI（Chat CompletionsとResponses API）、Anthropic、Googleのプロバイダーがサブパスで提供され、Vercel AI SDKのプロバイダーも `VercelModel` で包めます。OllamaやLiteLLMはTypeScript版の公式対応表にありません。使うプロバイダーの公式SDKは任意のpeer依存なので、自分で追加します。

## 関連記事

- [Strands Agentsとは？読み方・意味とPython SDKの使い方【1.62対応・2026年10月】](/tech/details/7199/)
- [Strands Harnessとは？pip導入から本番構成までPythonの実装手順を解説【2026年10月時点】](/tech/details/18290/)
- [AgentCore APIの使い方：SDK・CLI 1.0・InvokeAgentRuntimeでエージェントを本番に載せる手順【2026年10月】](/tech/details/8230/)
- [MCP TypeScript SDK v2とは？パッケージ分割とステートレス化の移行要点【2.4.0対応】](/tech/details/15905/)
- [Mastraとは？Skills・サンドボックス・メモリまで分かるTypeScript製AIエージェントフレームワークの使い方](/tech/details/6062/)

---

出典: [Strands Agents TypeScript SDKの使い方：npm導入からMCP・steering・AgentCoreデプロイまで【1.24対応】](<https://www.issoh.co.jp/tech/details/10146/>)（株式会社一創）
