@aws/agentcore 1.0.0-rc.3 → 1.0.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +175 -0
- package/README.md +92 -1224
- package/dist/assets/agent-inspector/index.js.asset +1 -1
- package/dist/assets/cdk/package.json +1 -1
- package/dist/assets/templates/agent-python-langchain/README.md +1 -1
- package/dist/assets/templates/agui-python-strands/README.md +1 -1
- package/dist/assets/templates/harness/harness.yaml +149 -81
- package/dist/main.js +354 -238
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# AgentCore CLI
|
|
2
2
|
|
|
3
3
|
`agentcore` is a command-line tool and interactive terminal UI (TUI) for managing
|
|
4
|
-
**[AWS Bedrock AgentCore](https://aws.amazon.com/bedrock/agentcore/)
|
|
4
|
+
**[AWS Bedrock AgentCore](https://aws.amazon.com/bedrock/agentcore/)**. AgentCore is Amazon's
|
|
5
5
|
platform for building and running production AI agents.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**[Amazon Bedrock AgentCore documentation](https://docs.aws.amazon.com/bedrock-agentcore/)**
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
It gives you two ways to work, from the same package:
|
|
10
|
+
|
|
11
|
+
- **A scriptable CLI** — composed of flag-driven commands with JSON output (`--json`) for
|
|
12
|
+
coding agents, scripts, CI, and automation.
|
|
13
|
+
- **An interactive TUI** — guided workflows for creating projects, browsing
|
|
14
|
+
resources, and chatting with agents.
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
17
|
agentcore # launch the interactive TUI
|
|
@@ -20,1259 +20,127 @@ agentcore harness list --json # scriptable, machine-readable output
|
|
|
20
20
|
|
|
21
21
|
## What problem does it solve?
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
responses. `agentcore` wraps all of that behind one ergonomic tool.
|
|
27
|
-
|
|
28
|
-
## Command surface
|
|
29
|
-
|
|
30
|
-
Commands with operation flags run headlessly. Bare Harness, Runtime, Memory,
|
|
31
|
-
Identity, and Gateway branches and leaves open their interactive flows, as does
|
|
32
|
-
a bare `project create` in a terminal (any flag, `--json`, or a non-TTY stays
|
|
33
|
-
headless). A bare `project status` opens a Linked Resources view that groups
|
|
34
|
-
the project's resources by agent and forwards to each deployed resource's
|
|
35
|
-
detail page. The harness hub (`harness get`) ends with the same kind of Linked
|
|
36
|
-
Resources tree for the Runtime, Memory, Gateway, Browser, Code Interpreter and
|
|
37
|
-
credential providers wired to that harness, each opening in its own region.
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
agentcore # interactive TUI
|
|
41
|
-
├── harness # manage agentcore harnesses
|
|
42
|
-
│ ├── create # create a harness (auto-provisions a role if none given)
|
|
43
|
-
│ ├── get # fetch a harness by id
|
|
44
|
-
│ ├── list # list harnesses (server-side paginated)
|
|
45
|
-
│ ├── update # update a harness
|
|
46
|
-
│ ├── delete # delete a harness
|
|
47
|
-
│ ├── invoke # chat with / prompt a harness (streams the reply)
|
|
48
|
-
│ ├── exec # run a shell command in a harness runtime
|
|
49
|
-
│ ├── version
|
|
50
|
-
│ │ ├── list # list a harness's versions
|
|
51
|
-
│ │ └── get # get a specific version
|
|
52
|
-
│ └── endpoint
|
|
53
|
-
│ ├── create
|
|
54
|
-
│ ├── get
|
|
55
|
-
│ ├── list
|
|
56
|
-
│ ├── update
|
|
57
|
-
│ └── delete
|
|
58
|
-
├── identity # manage AgentCore Identity resources
|
|
59
|
-
│ ├── api-key-credential-provider
|
|
60
|
-
│ │ ├── create # create an API key credential provider
|
|
61
|
-
│ │ ├── get # get an API key credential provider
|
|
62
|
-
│ │ ├── list # list API key credential providers
|
|
63
|
-
│ │ ├── update # update an API key credential provider
|
|
64
|
-
│ │ └── delete # delete an API key credential provider
|
|
65
|
-
│ ├── oauth2-credential-provider
|
|
66
|
-
│ │ ├── create # create an OAuth2 credential provider
|
|
67
|
-
│ │ ├── get # get an OAuth2 credential provider
|
|
68
|
-
│ │ ├── list # list OAuth2 credential providers
|
|
69
|
-
│ │ ├── update # update an OAuth2 credential provider
|
|
70
|
-
│ │ └── delete # delete an OAuth2 credential provider
|
|
71
|
-
│ └── payment-credential-provider
|
|
72
|
-
│ ├── get # get a payment credential provider
|
|
73
|
-
│ └── list # list payment credential providers
|
|
74
|
-
├── runtime # inspect deployed AgentCore Runtimes
|
|
75
|
-
│ ├── get # fetch a Runtime by id
|
|
76
|
-
│ ├── list # list Runtimes (server-side paginated)
|
|
77
|
-
│ ├── invoke # invoke a Runtime headlessly or in a persistent console
|
|
78
|
-
│ ├── shell # open a persistent interactive terminal in a Runtime
|
|
79
|
-
│ ├── logs # follow a Runtime's logs live, or search a time window
|
|
80
|
-
│ ├── traces
|
|
81
|
-
│ │ ├── list # list a Runtime's recent traces
|
|
82
|
-
│ │ └── get # download a trace's log records to a JSON file
|
|
83
|
-
│ ├── version
|
|
84
|
-
│ │ ├── get # get a specific Runtime version
|
|
85
|
-
│ │ └── list # list a Runtime's versions
|
|
86
|
-
│ └── endpoint
|
|
87
|
-
│ ├── get # get a Runtime endpoint by qualifier
|
|
88
|
-
│ └── list # list a Runtime's endpoints
|
|
89
|
-
├── memory # inspect AgentCore Memories
|
|
90
|
-
│ ├── get # fetch a Memory by id
|
|
91
|
-
│ ├── list # list Memories (server-side paginated)
|
|
92
|
-
│ ├── event
|
|
93
|
-
│ │ ├── get # get an Event from a Memory session
|
|
94
|
-
│ │ └── list # list Events from a Memory session
|
|
95
|
-
│ └── record
|
|
96
|
-
│ ├── get # get a long-term Memory record
|
|
97
|
-
│ └── list # list long-term Memory records
|
|
98
|
-
├── gateway # manage AgentCore Gateways
|
|
99
|
-
│ ├── get # get a Gateway by id
|
|
100
|
-
│ ├── list # list Gateways (server-side paginated)
|
|
101
|
-
│ ├── invoke # invoke a Gateway headlessly or in a persistent console
|
|
102
|
-
│ ├── target
|
|
103
|
-
│ │ ├── get # get a Target under a Gateway
|
|
104
|
-
│ │ └── list # list Targets under a Gateway
|
|
105
|
-
│ ├── connector
|
|
106
|
-
│ │ ├── get # get a connector-backed Target
|
|
107
|
-
│ │ └── list # list connector-backed Targets
|
|
108
|
-
│ ├── rule
|
|
109
|
-
│ │ ├── get # get a Rule under a Gateway
|
|
110
|
-
│ │ └── list # list Rules under a Gateway
|
|
111
|
-
│ └── policy
|
|
112
|
-
│ └── generate # generate Cedar for a Gateway from a prompt (TUI when run bare)
|
|
113
|
-
├── payment # inspect AgentCore Payments (command line only for now)
|
|
114
|
-
│ ├── manager
|
|
115
|
-
│ │ ├── get # get a payment manager by id
|
|
116
|
-
│ │ └── list # list payment managers (server-side paginated)
|
|
117
|
-
│ ├── connector # connectors under a payment manager
|
|
118
|
-
│ │ ├── get # get a connector (shows the Quick Create authorization URL while pending)
|
|
119
|
-
│ │ └── list # list a manager's connectors
|
|
120
|
-
│ ├── session # budget-limited payment contexts (data plane)
|
|
121
|
-
│ │ ├── get
|
|
122
|
-
│ │ └── list
|
|
123
|
-
│ └── instrument # embedded crypto wallets (data plane)
|
|
124
|
-
│ ├── get
|
|
125
|
-
│ ├── list
|
|
126
|
-
│ └── balance # read token balance on an explicit chain (default token: USDC)
|
|
127
|
-
├── eval # evaluate and optimize AgentCore agents
|
|
128
|
-
│ └── evaluator # manage AgentCore evaluators
|
|
129
|
-
│ ├── llm-as-a-judge # LLM-as-a-Judge evaluators
|
|
130
|
-
│ │ ├── create # create (instructions + rating scale + model)
|
|
131
|
-
│ │ └── update # update (merged over the existing config)
|
|
132
|
-
│ ├── code-based # code-based (Lambda-backed) evaluators
|
|
133
|
-
│ │ ├── create # create (Lambda ARN + optional timeout)
|
|
134
|
-
│ │ └── update # update (merged over the existing config)
|
|
135
|
-
│ ├── get # get an evaluator by id (type-agnostic)
|
|
136
|
-
│ ├── list # list evaluators (server-side paginated)
|
|
137
|
-
│ └── delete # delete an evaluator by id
|
|
138
|
-
├── project # manage an AgentCore project (scaffold → deploy)
|
|
139
|
-
│ ├── create # create a project: a managed harness by default,
|
|
140
|
-
│ │ # or scaffolded runtime code via --template;
|
|
141
|
-
│ │ # bare `project create` opens an interactive wizard.
|
|
142
|
-
│ │ # agentcore/cdk/ holds a two-file CDK app on
|
|
143
|
-
│ │ # @aws/agentcore-cdk (bin/cdk.ts, lib/cdk-stack.ts)
|
|
144
|
-
│ ├── add # add a resource to the project (runtime, harness, memory, …)
|
|
145
|
-
│ ├── export
|
|
146
|
-
│ │ └── harness # convert a harness into an editable Strands runtime agent
|
|
147
|
-
│ ├── remove # remove a resource from the project spec (spec-level;
|
|
148
|
-
│ │ # code under app/ is kept). Resource types: harness,
|
|
149
|
-
│ │ # runtime, credential, config-bundle, online-eval,
|
|
150
|
-
│ │ # online-insight, memory, gateway, gateway-target,
|
|
151
|
-
│ │ # gateway-connector, policy-engine, policy,
|
|
152
|
-
│ │ # payment-manager, payment-connector — or `all`, which
|
|
153
|
-
│ │ # empties every resource collection (y/N prompt; --yes
|
|
154
|
-
│ │ # skips it for non-interactive use)
|
|
155
|
-
│ ├── dev # run the project locally
|
|
156
|
-
│ ├── deploy # deploy to AWS (auto-provisions the default target)
|
|
157
|
-
│ ├── invoke # invoke a deployed project resource
|
|
158
|
-
│ │ ├── runtime # use the existing Runtime invoke experience
|
|
159
|
-
│ │ └── harness # use the existing Harness invoke experience
|
|
160
|
-
│ ├── status # inspect deployed project resources (TUI when run bare)
|
|
161
|
-
│ ├── build # synthesize the project's CloudFormation templates
|
|
162
|
-
│ ├── log
|
|
163
|
-
│ │ └── runtime # resolve a project Runtime and inspect its logs
|
|
164
|
-
│ └── traces
|
|
165
|
-
│ └── runtime
|
|
166
|
-
└── config # read/write global config values
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
`project export harness` "ejects" a harness to code you own: it renders a
|
|
170
|
-
Python Strands agent under `app/<target-agent-name>/` mapping the harness spec
|
|
171
|
-
(model, system prompt, tools, skills, memory, execution limits), registers the
|
|
172
|
-
new runtime in `agentcore.json` (the harness entry stays), and writes an
|
|
173
|
-
`EXPORT_NOTES.md` in the agent directory listing anything that could not be
|
|
174
|
-
mapped mechanically. Pass `--name <harness>` for an in-project harness or
|
|
175
|
-
`--arn <harnessArn>` to fetch a deployed one (the fetch uses the region
|
|
176
|
-
embedded in the ARN); `--target-agent-name` overrides the default
|
|
177
|
-
`<harnessName>Agent`. The exported agent is always a `CodeZip` runtime: it
|
|
178
|
-
declares its own dependencies, so it needs no image build. If the harness used a
|
|
179
|
-
pre-built container image or a custom Dockerfile, that is reported in
|
|
180
|
-
`EXPORT_NOTES.md` rather than rebuilt. Path-based skills are not supported,
|
|
181
|
-
since the exported agent has no container filesystem to read them from.
|
|
182
|
-
|
|
183
|
-
### Harness Project Files
|
|
184
|
-
|
|
185
|
-
`project create` (without `--template`) and `project add harness` share the same
|
|
186
|
-
scaffolding flow. Each harness has `app/<name>/harness.yaml` and
|
|
187
|
-
`app/<name>/system-prompt.md`. YAML is the harness configuration format.
|
|
188
|
-
The YAML contains the supplied settings and
|
|
189
|
-
commented optional examples. Tools are opt-in. Newly scaffolded harnesses
|
|
190
|
-
explicitly use `memory: { mode: managed }` unless another memory configuration
|
|
191
|
-
was supplied. Reading an existing file with no `memory` setting still means
|
|
192
|
-
disabled memory; reading never adds the scaffold default.
|
|
193
|
-
|
|
194
|
-
```yaml
|
|
195
|
-
name: assistant
|
|
196
|
-
model:
|
|
197
|
-
provider: bedrock
|
|
198
|
-
modelId: global.anthropic.claude-sonnet-4-6
|
|
199
|
-
# Instructions come from system-prompt.md unless systemPrompt is set inline.
|
|
200
|
-
# systemPrompt: You are a helpful assistant.
|
|
201
|
-
memory:
|
|
202
|
-
mode: managed
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
Both deployment and local export use inline `systemPrompt` text when it is
|
|
206
|
-
provided. Otherwise, instructions come from `system-prompt.md` next to
|
|
207
|
-
`harness.yaml`. Prompt contents are not trimmed, and blank prompts are rejected.
|
|
208
|
-
Prompt settings do not resolve local file references.
|
|
209
|
-
|
|
210
|
-
```yaml
|
|
211
|
-
systemPrompt: |
|
|
212
|
-
You are a concise assistant.
|
|
213
|
-
truncation:
|
|
214
|
-
strategy: summarization
|
|
215
|
-
config:
|
|
216
|
-
summarization:
|
|
217
|
-
summarizationSystemPrompt: Keep decisions and open questions.
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
`project add harness --system-prompt "Your instructions"` writes the supplied
|
|
221
|
-
text to `system-prompt.md`, leaving `systemPrompt` out of the generated YAML.
|
|
222
|
-
Summary instructions in
|
|
223
|
-
`truncation.config.summarization.summarizationSystemPrompt` are inline text.
|
|
224
|
-
|
|
225
|
-
Skills are unchanged: skill paths refer to the **runtime/container filesystem**,
|
|
226
|
-
not local files to package. Other fields do not support local includes.
|
|
227
|
-
Malformed YAML, duplicate keys, and existing schema violations fail the read.
|
|
228
|
-
Unknown fields at the harness root and directly inside `model` are stripped
|
|
229
|
-
from the parsed configuration. Nested configurations keep their existing
|
|
230
|
-
validation contracts. Free-form
|
|
231
|
-
maps such as headers, tags, environment variables, `additionalParams`, and
|
|
232
|
-
`inputSchema` still accept arbitrary keys.
|
|
233
|
-
Build, deploy, and export do not rewrite harness YAML or remove its comments.
|
|
234
|
-
`agentcore.json`, deployment targets, JSON CLI flags/output, and service payloads
|
|
235
|
-
are unchanged.
|
|
236
|
-
|
|
237
|
-
Global flags (declared at the root, available on every command):
|
|
238
|
-
|
|
239
|
-
| Flag | Purpose |
|
|
240
|
-
| ---------------- | -------------------------------------------------------------------- |
|
|
241
|
-
| `--region` | AWS region (falls back to `AWS_REGION`, then the shared AWS config). |
|
|
242
|
-
| `--json` | Emit machine-readable JSON instead of launching the TUI. |
|
|
243
|
-
| `--debug` | Debug logging. |
|
|
244
|
-
| `--endpoint-url` | Override the service endpoint URL (e.g. for testing against a stub). |
|
|
245
|
-
|
|
246
|
-
### Invoke a project resource
|
|
247
|
-
|
|
248
|
-
Run `agentcore project invoke` from inside a project to choose a deployed
|
|
249
|
-
Runtime or Harness interactively. Headless invocation keeps each resource's
|
|
250
|
-
existing input contract:
|
|
251
|
-
|
|
252
|
-
```bash
|
|
253
|
-
agentcore project invoke runtime \
|
|
254
|
-
--name checkout \
|
|
255
|
-
--payload '{"prompt":"Check order 123."}' \
|
|
256
|
-
--content-type application/json
|
|
257
|
-
|
|
258
|
-
agentcore project invoke harness \
|
|
259
|
-
--name support \
|
|
260
|
-
--prompt "Help with my account."
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
Use `--target` to select a deployment target. When a project declares exactly
|
|
264
|
-
one resource of the requested type, `--name` may be omitted.
|
|
265
|
-
|
|
266
|
-
### Inspect project logs
|
|
267
|
-
|
|
268
|
-
Project logging resolves a logical resource name through the selected
|
|
269
|
-
deployment target, so physical IDs and deployment regions do not need to be
|
|
270
|
-
supplied:
|
|
271
|
-
|
|
272
|
-
```bash
|
|
273
|
-
agentcore project log runtime
|
|
274
|
-
agentcore project log runtime --name checkout --target production
|
|
275
|
-
agentcore project log runtime --name checkout --since 1h --level error
|
|
276
|
-
agentcore project log harness
|
|
277
|
-
agentcore project log harness --name support --target production
|
|
278
|
-
agentcore project log harness --name support --since 1h --level error
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
When the project declares exactly one resource of the requested type, `--name`
|
|
282
|
-
may be omitted. For Harnesses, the CLI also resolves the managed Harness to its
|
|
283
|
-
underlying Runtime before reading CloudWatch. Use the imperative
|
|
284
|
-
`agentcore runtime logs` or `agentcore harness logs` commands when addressing a
|
|
285
|
-
physical resource directly or working outside a project.
|
|
286
|
-
|
|
287
|
-
### Inspect project traces
|
|
23
|
+
Using the AgentCore APIs directly means making calls across several services,
|
|
24
|
+
setting up execution roles, and handling streamed responses. `agentcore` handles
|
|
25
|
+
those details so you can create, deploy, and invoke agents from your terminal.
|
|
288
26
|
|
|
289
|
-
|
|
290
|
-
resolution, then lists or downloads traces from the resolved Runtime's
|
|
291
|
-
deployment region:
|
|
27
|
+
## Quick Start
|
|
292
28
|
|
|
293
|
-
|
|
294
|
-
agentcore project traces runtime list
|
|
295
|
-
agentcore project traces runtime list --name checkout --target production --since 30m
|
|
296
|
-
agentcore project traces runtime get <traceId> --name checkout --output trace.json
|
|
297
|
-
agentcore project traces harness list
|
|
298
|
-
agentcore project traces harness list --name support --target production --since 30m
|
|
299
|
-
agentcore project traces harness get <traceId> --name support --output trace.json
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
When the project declares exactly one resource of the requested type, `--name`
|
|
303
|
-
may be omitted. For Harnesses, the CLI resolves the underlying Runtime before
|
|
304
|
-
querying its traces. Use the imperative `agentcore runtime traces` or
|
|
305
|
-
`agentcore harness traces` commands when addressing a physical resource
|
|
306
|
-
directly or working outside a project.
|
|
307
|
-
|
|
308
|
-
### Inspect AgentCore Payments
|
|
309
|
-
|
|
310
|
-
The `payment` commands call the Payments control and data planes directly, with
|
|
311
|
-
no project involved. This command family currently provides read-only inspection
|
|
312
|
-
of existing managers, connectors, sessions, instruments, and payment credential
|
|
313
|
-
providers. It does not create IAM roles or change provider credentials.
|
|
314
|
-
|
|
315
|
-
Choose a manager from `manager list` and use its `paymentManagerId` below:
|
|
29
|
+
Create a managed Harness project, deploy it, and send a prompt:
|
|
316
30
|
|
|
317
31
|
```bash
|
|
318
|
-
agentcore
|
|
319
|
-
|
|
320
|
-
agentcore
|
|
321
|
-
agentcore
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
`--user-id` is the application user ID used when the session or instrument was
|
|
325
|
-
created, not an IAM username or AWS profile. Session and instrument reads require
|
|
326
|
-
it with IAM authentication; their lists return that user's resources, not every
|
|
327
|
-
user's resources under the manager.
|
|
328
|
-
|
|
329
|
-
```bash
|
|
330
|
-
USER_ID='alice' # Use the application user ID associated with the resources.
|
|
331
|
-
agentcore payment session list --manager-id "$MANAGER_ID" --user-id "$USER_ID"
|
|
332
|
-
agentcore payment instrument list --manager-id "$MANAGER_ID" --user-id "$USER_ID"
|
|
333
|
-
|
|
334
|
-
# Use paymentInstrumentId and paymentConnectorId from the same instrument list item.
|
|
335
|
-
INSTRUMENT_ID='<paymentInstrumentId>'
|
|
336
|
-
CONNECTOR_ID='<paymentConnectorId>'
|
|
337
|
-
agentcore payment instrument get --manager-id "$MANAGER_ID" \
|
|
338
|
-
--instrument-id "$INSTRUMENT_ID" --user-id "$USER_ID"
|
|
339
|
-
agentcore payment instrument balance --manager-id "$MANAGER_ID" \
|
|
340
|
-
--connector-id "$CONNECTOR_ID" --instrument-id "$INSTRUMENT_ID" \
|
|
341
|
-
--user-id "$USER_ID" --chain BASE_SEPOLIA
|
|
32
|
+
agentcore project create --name MyAssistant
|
|
33
|
+
cd MyAssistant
|
|
34
|
+
agentcore project deploy
|
|
35
|
+
agentcore project invoke harness --prompt "Hey, what can you do for me?"
|
|
342
36
|
```
|
|
343
37
|
|
|
344
|
-
To
|
|
38
|
+
To start with code you own instead, create a Runtime project from a template.
|
|
39
|
+
Run this alternative from outside an existing project:
|
|
345
40
|
|
|
346
41
|
```bash
|
|
347
|
-
agentcore
|
|
348
|
-
agentcore identity payment-credential-provider list --json
|
|
349
|
-
agentcore identity payment-credential-provider get --name '<provider name>'
|
|
42
|
+
agentcore project create --name MyAgent --template agent-python-strands
|
|
350
43
|
```
|
|
351
44
|
|
|
352
|
-
|
|
353
|
-
observability. It does not select an AgentCore agent or filter the results.
|
|
45
|
+
## Command Surface
|
|
354
46
|
|
|
355
|
-
`
|
|
356
|
-
|
|
357
|
-
such as ETHEREUM do not identify whether to query mainnet or a testnet. The JSON
|
|
358
|
-
response retains the raw atomic amount string and decimals. A service error is
|
|
359
|
-
reported as an error, never converted to a zero balance.
|
|
47
|
+
`project` commands manage local project specifications and their deployments.
|
|
48
|
+
Resource commands operate on deployed resources without requiring a local project.
|
|
360
49
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
`
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
50
|
+
| Command | Purpose |
|
|
51
|
+
| ---------- | ----------------------------------------------------------------------------- |
|
|
52
|
+
| `project` | Create, develop, build, deploy, invoke, and inspect a project |
|
|
53
|
+
| `harness` | Manage Harnesses, versions, and endpoints; invoke and inspect them |
|
|
54
|
+
| `identity` | Manage credential providers |
|
|
55
|
+
| `runtime` | Inspect, invoke, and open a shell in deployed Runtimes |
|
|
56
|
+
| `memory` | Inspect Memories, actors, sessions, events, and records |
|
|
57
|
+
| `gateway` | Inspect and invoke Gateways, inspect targets and rules, and generate policies |
|
|
58
|
+
| `payment` | Inspect payment managers, connectors, sessions, instruments, and balances |
|
|
59
|
+
| `eval` | Evaluate agents, manage datasets and configurations, and run experiments |
|
|
60
|
+
| `feedback` | Submit feedback |
|
|
61
|
+
| `config` | Read and write global CLI settings |
|
|
62
|
+
| `update` | Check for and install CLI updates |
|
|
370
63
|
|
|
371
|
-
|
|
64
|
+
Use `--help` for subcommands and flags, or browse the [command reference](command.md):
|
|
372
65
|
|
|
373
66
|
```bash
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
agentcore project create --name MyAssistant
|
|
378
|
-
cd MyAssistant && agentcore project deploy
|
|
379
|
-
# … or run `agentcore project create` bare in a terminal for the guided
|
|
380
|
-
# wizard (name → harness or template → confirm), which drives the same
|
|
381
|
-
# creation path.
|
|
382
|
-
agentcore harness invoke --id <id from the deploy outputs> --prompt "hello"
|
|
383
|
-
|
|
384
|
-
# Scaffold runtime code instead by selecting a template. Templates that support
|
|
385
|
-
# a model provider (agent-python-strands) accept --model-provider/--api-key;
|
|
386
|
-
# add the -container suffix for a container build, or use `empty` for a project
|
|
387
|
-
# with no runtime.
|
|
388
|
-
agentcore project create --name MyAgent --template agent-python-strands
|
|
389
|
-
# The same Strands agent built as a container image, with a Dockerfile.
|
|
390
|
-
agentcore project create --name MyAgent --template agent-python-strands-container
|
|
391
|
-
# A LangChain agent on Bedrock, built with create_agent.
|
|
392
|
-
agentcore project create --name MyAgent --template agent-python-langchain
|
|
393
|
-
|
|
394
|
-
# Translate an existing Amazon Bedrock Agent version into editable runtime code
|
|
395
|
-
# with `project add runtime --type import` from inside a project. The selected
|
|
396
|
-
# alias identifies the immutable source version; generated code invokes models
|
|
397
|
-
# and translated tools directly rather than proxying the alias. Use --framework
|
|
398
|
-
# strands (default) or langgraph. The alias must point at a prepared version,
|
|
399
|
-
# not the mutable DRAFT that the built-in test alias (TSTALIASID) routes to.
|
|
400
|
-
# Anything that could not be translated is listed in the generated IMPORT_NOTES.md.
|
|
401
|
-
agentcore project add runtime --name MyImportedAgent --type import \
|
|
402
|
-
--agent-id A1B2C3D4E5 --agent-alias-id XYZ123ABC4 --region us-east-1 \
|
|
403
|
-
--framework strands
|
|
67
|
+
agentcore --help
|
|
68
|
+
agentcore project --help
|
|
69
|
+
agentcore runtime invoke --help
|
|
404
70
|
```
|
|
405
71
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
--model '{"bedrockModelConfig":{"modelId":"us.anthropic.claude-sonnet-4-5-20250929-v1:0"}}' \
|
|
412
|
-
--json
|
|
413
|
-
|
|
414
|
-
# List and inspect
|
|
415
|
-
agentcore harness list --json
|
|
416
|
-
agentcore harness get --id <harnessId> --json
|
|
417
|
-
|
|
418
|
-
# One-shot prompt (streams, then prints the full transcript as JSON)
|
|
419
|
-
agentcore harness invoke --id <harnessId> --prompt "Summarize this repo." --json
|
|
420
|
-
|
|
421
|
-
# Interactive chat (no --prompt): opens the TUI chat at that harness/session
|
|
422
|
-
agentcore harness invoke --id <harnessId>
|
|
423
|
-
agentcore harness invoke --id <harnessId> --session-id <session> --qualifier PROD
|
|
424
|
-
|
|
425
|
-
# Run a shell command inside the agent runtime
|
|
426
|
-
agentcore harness exec --id <harnessId> --command "ls -la" --json
|
|
427
|
-
|
|
428
|
-
# Inspect deployed Runtimes without project configuration or deployment
|
|
429
|
-
agentcore runtime get --id <runtimeId>
|
|
430
|
-
agentcore runtime list --max-results 20
|
|
431
|
-
agentcore runtime version get --id <runtimeId> --version <version>
|
|
432
|
-
agentcore runtime version list --id <runtimeId> --max-results 20
|
|
433
|
-
agentcore runtime endpoint get --id <runtimeId> --qualifier DEFAULT
|
|
434
|
-
agentcore runtime endpoint list --id <runtimeId> --max-results 20
|
|
435
|
-
|
|
436
|
-
# Follow a Runtime's logs live by resource ID (Ctrl+C to stop)
|
|
437
|
-
agentcore runtime logs --id <runtimeId>
|
|
438
|
-
agentcore runtime logs --id <runtimeId> --level error --query "database"
|
|
439
|
-
|
|
440
|
-
# Search a past window instead (--since/--until switch to search mode)
|
|
441
|
-
agentcore runtime logs --id <runtimeId> --since 1h --limit 100
|
|
442
|
-
agentcore runtime logs --id <runtimeId> --since 2026-08-30T12:00:00Z --until now --json
|
|
443
|
-
|
|
444
|
-
# List recent traces (they take 2-3 minutes to appear), then download one
|
|
445
|
-
agentcore runtime traces list --id <runtimeId> --since 30m
|
|
446
|
-
agentcore runtime traces get <traceId> --id <runtimeId> --output trace.json
|
|
447
|
-
|
|
448
|
-
# Resolve project resources by logical name and deployment target
|
|
449
|
-
agentcore project log harness --name support --target production --since 1h
|
|
450
|
-
agentcore project traces runtime list --name checkout --target production --since 30m
|
|
451
|
-
agentcore project traces runtime get <traceId> --name checkout --output trace.json
|
|
452
|
-
agentcore project traces harness list --name support --target production --since 30m
|
|
453
|
-
agentcore project traces harness get <traceId> --name support --output trace.json
|
|
454
|
-
|
|
455
|
-
# Inspect AgentCore Memories without project configuration or deployment
|
|
456
|
-
agentcore memory get --id <memoryId>
|
|
457
|
-
agentcore memory get --id <memoryId> --view without_decryption
|
|
458
|
-
agentcore memory list --max-results 20
|
|
459
|
-
agentcore memory event get --id <memoryId> --actor-id <actorId> --session-id <sessionId> --event-id <eventId>
|
|
460
|
-
agentcore memory event list --id <memoryId> --actor-id <actorId> --session-id <sessionId> --max-results 20
|
|
461
|
-
agentcore memory record get --id <memoryId> --record-id <recordId>
|
|
462
|
-
agentcore memory record list --id <memoryId> --namespace <namespace> --max-results 20
|
|
463
|
-
|
|
464
|
-
# Inspect Gateway resources without project configuration or deployment
|
|
465
|
-
agentcore gateway get --id <gatewayId>
|
|
466
|
-
agentcore gateway list --max-results 20
|
|
467
|
-
agentcore gateway invoke --id <gatewayId> --payload file://request.json
|
|
468
|
-
agentcore gateway invoke --id <gatewayId> # open the persistent JSON console
|
|
469
|
-
agentcore gateway target get --gateway-id <gatewayId> --target-id <targetId>
|
|
470
|
-
agentcore gateway target list --gateway-id <gatewayId> --max-results 20
|
|
471
|
-
agentcore gateway connector get --gateway-id <gatewayId> --id <targetId>
|
|
472
|
-
agentcore gateway connector list --gateway-id <gatewayId> --max-results 20
|
|
473
|
-
agentcore gateway rule get --gateway-id <gatewayId> --rule-id <ruleId>
|
|
474
|
-
agentcore gateway rule list --gateway-id <gatewayId> --max-results 20
|
|
475
|
-
agentcore gateway policy generate --gateway-id <gatewayId> --prompt "forbid IAM callers from every tool"
|
|
476
|
-
agentcore gateway policy generate --gateway-id <gatewayArn> --prompt file://policy.txt --json
|
|
477
|
-
# Pipe the generated Cedar into a project (run inside the project)
|
|
478
|
-
agentcore gateway policy generate --gateway-id <gatewayId> --prompt "..." \
|
|
479
|
-
| agentcore project add policy --engine Guardrails --name Generated --statement -
|
|
480
|
-
|
|
481
|
-
# Manage API key credential providers
|
|
482
|
-
agentcore identity api-key-credential-provider create --name my-provider --api-key <key>
|
|
483
|
-
agentcore identity api-key-credential-provider get --name my-provider
|
|
484
|
-
agentcore identity api-key-credential-provider list --max-results 10
|
|
485
|
-
agentcore identity api-key-credential-provider update --name my-provider --api-key <new-key>
|
|
486
|
-
agentcore identity api-key-credential-provider delete --name my-provider
|
|
487
|
-
|
|
488
|
-
# Manage OAuth2 credential providers (guided Custom OAuth2, or --provider-configuration for other vendors)
|
|
489
|
-
agentcore identity oauth2-credential-provider create \
|
|
490
|
-
--name my-oauth-provider \
|
|
491
|
-
--vendor CustomOauth2 \
|
|
492
|
-
--client-id <client-id> \
|
|
493
|
-
--discovery-url https://issuer.example.com/.well-known/openid-configuration \
|
|
494
|
-
--client-secret -
|
|
495
|
-
agentcore identity oauth2-credential-provider get --name my-oauth-provider
|
|
496
|
-
agentcore identity oauth2-credential-provider list --max-results 10
|
|
497
|
-
agentcore identity oauth2-credential-provider delete --name my-oauth-provider
|
|
498
|
-
|
|
499
|
-
# Manage evaluators
|
|
500
|
-
# Create an LLM-as-a-Judge evaluator with a rating-scale preset.
|
|
501
|
-
agentcore eval evaluator llm-as-a-judge create \
|
|
502
|
-
--name order-support-quality \
|
|
503
|
-
--level SESSION \
|
|
504
|
-
--model us.anthropic.claude-sonnet-4-5-20250929-v1:0 \
|
|
505
|
-
--instructions "Judge from {context} whether the order-support agent answered correctly." \
|
|
506
|
-
--rating-scale 1-5-quality \
|
|
507
|
-
--json
|
|
508
|
-
|
|
509
|
-
# Create a code-based (Lambda-backed) evaluator; timeout defaults to the service value.
|
|
510
|
-
agentcore eval evaluator code-based create \
|
|
511
|
-
--name refund-policy-compliance \
|
|
512
|
-
--level SESSION \
|
|
513
|
-
--lambda-arn arn:aws:lambda:us-west-2:123456789012:function:refund-policy \
|
|
514
|
-
--json
|
|
72
|
+
Supported bare commands open their interactive flows in a terminal. Operation
|
|
73
|
+
flags select headless behavior for most commands, but invoke commands can use
|
|
74
|
+
selectors such as `--id` and `--session-id` to seed an interactive console.
|
|
75
|
+
Run `agentcore project create` for guided setup. To create a default project
|
|
76
|
+
without the wizard, run `agentcore project create --name MyAssistant`.
|
|
515
77
|
|
|
516
|
-
|
|
517
|
-
agentcore eval evaluator get --id <evaluatorId> --json
|
|
518
|
-
agentcore eval evaluator list --max-results 20 --json
|
|
519
|
-
agentcore eval evaluator delete --id <evaluatorId> --json
|
|
520
|
-
|
|
521
|
-
# Remove resources from a project's spec (run inside the project)
|
|
522
|
-
agentcore project remove memory --name recall
|
|
523
|
-
agentcore project remove credential --name svc-key # also deletes its .env.local entries
|
|
524
|
-
agentcore project remove gateway-target --gateway tools --name search
|
|
525
|
-
agentcore project remove all # y/N prompt; empties every collection
|
|
526
|
-
agentcore project remove all --yes # non-interactive
|
|
527
|
-
```
|
|
78
|
+
Global flags (declared at the root, available on every command):
|
|
528
79
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
`
|
|
532
|
-
`--
|
|
80
|
+
| Flag | Purpose |
|
|
81
|
+
| ---------- | ------------------------------------------------------------------------------------------- |
|
|
82
|
+
| `--region` | AWS region: flag, `AWS_REGION`, `AWS_DEFAULT_REGION`, active AWS profile, then `us-east-1`. |
|
|
83
|
+
| `--json` | Emit machine-readable JSON instead of launching the TUI. |
|
|
84
|
+
| `--debug` | Debug logging. |
|
|
533
85
|
|
|
534
|
-
|
|
535
|
-
spec name and keeps its secret in `agentcore/.env.local` under
|
|
536
|
-
`AGENTCORE_CREDENTIAL_<NAME>` (with a field suffix for OAuth2 and payment
|
|
537
|
-
values). `project deploy` provisions the Identity credential provider before
|
|
538
|
-
synth under the name `<project>_<target>_<credential>`, so two targets in one
|
|
539
|
-
account and region get separate providers, and records its ARN in
|
|
540
|
-
`deployed-state.json` under the spec name. A credential removed from the spec
|
|
541
|
-
has its provider deleted on the next deploy of each target, after the stack
|
|
542
|
-
update. Tearing a target down (deploying a spec with nothing left to deploy,
|
|
543
|
-
which is where `project remove all` leads) deletes every provider the target
|
|
544
|
-
owns: API key, OAuth2 and payment. CLI versions before this change named providers by the bare credential name. Those
|
|
545
|
-
providers stay in the account after an upgrade, untouched by deploys and
|
|
546
|
-
teardowns. Delete them with `agentcore identity api-key-credential-provider
|
|
547
|
-
delete --name <credential>`, the `oauth2-credential-provider` equivalent, or
|
|
548
|
-
`aws bedrock-agentcore-control delete-payment-credential-provider` once nothing
|
|
549
|
-
else uses them.
|
|
86
|
+
Run `agentcore --version` to check the installed CLI version.
|
|
550
87
|
|
|
551
|
-
|
|
88
|
+
## Extending the CDK app
|
|
552
89
|
|
|
553
|
-
`agentcore/cdk/`
|
|
90
|
+
`agentcore/cdk/` has two source files. `bin/cdk.ts` reads the project once
|
|
554
91
|
(`readAgentCoreProject`), makes one stack per deployment target
|
|
555
92
|
(`resolveTargetStacks`) and turns `agentcore.json` into the application's props
|
|
556
|
-
(`transformAgentCoreJson`)
|
|
557
|
-
|
|
558
|
-
on your disk. `lib/cdk-stack.ts` instantiates one `AgentCoreApplication`; it is
|
|
559
|
-
the file you edit. Add your own resources after the application and wire them to
|
|
560
|
-
a runtime or harness through the application's accessors: runtimes and harnesses
|
|
561
|
-
implement `iam.IGrantable`, so any AWS L2 grant accepts them, and they expose
|
|
562
|
-
`grantRead` / `grantWrite` / `grantReadWrite` (DynamoDB tables, S3 buckets,
|
|
563
|
-
Secrets Manager secrets) and `addEnvironmentVariable`:
|
|
564
|
-
|
|
565
|
-
```ts
|
|
566
|
-
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
|
|
567
|
-
|
|
568
|
-
const orders = new dynamodb.Table(this, "Orders", {
|
|
569
|
-
partitionKey: { name: "pk", type: dynamodb.AttributeType.STRING },
|
|
570
|
-
});
|
|
571
|
-
const checkout = this.application.runtime("checkout"); // or this.application.harness('support')
|
|
572
|
-
checkout.grantReadWrite(orders);
|
|
573
|
-
checkout.addEnvironmentVariable("ORDERS_TABLE", orders.tableName);
|
|
574
|
-
orders.grantReadData(this.application.harness("support")); // any AWS L2 grant works too
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
Redeploy with `agentcore project deploy`. An unknown name fails at synth and lists
|
|
578
|
-
the names that exist; a runtime or harness configured with an `executionRoleArn`
|
|
579
|
-
warns at synth about every grant CDK could not attach to the imported role. Note
|
|
580
|
-
that `agentcore project status` reports only the resources `agentcore.json`
|
|
581
|
-
declares, not the ones you add in the stack.
|
|
582
|
-
|
|
583
|
-
### Invoke a Gateway
|
|
584
|
-
|
|
585
|
-
Gateway Invoke is a project-independent HTTP request command with headless and
|
|
586
|
-
interactive modes. It gets the Gateway by ID, uses the returned HTTPS origin,
|
|
587
|
-
selects authentication from the Gateway's authorizer, and preserves the request
|
|
588
|
-
and response bodies.
|
|
589
|
-
|
|
590
|
-
```bash
|
|
591
|
-
# MCP Gateway: use the exact gatewayUrl returned by GetGateway.
|
|
592
|
-
agentcore gateway invoke \
|
|
593
|
-
--id <gatewayId> \
|
|
594
|
-
--payload '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"agentcore-cli","version":"1"}}}' \
|
|
595
|
-
--accept 'application/json, text/event-stream' \
|
|
596
|
-
--mcp-protocol-version 2025-03-26
|
|
597
|
-
|
|
598
|
-
# HTTP target: --path is relative to the Gateway origin.
|
|
599
|
-
agentcore gateway invoke \
|
|
600
|
-
--id <gatewayId> \
|
|
601
|
-
--path support-agent/invocations \
|
|
602
|
-
--payload file://request.json \
|
|
603
|
-
--session-id <runtimeSessionId>
|
|
604
|
-
|
|
605
|
-
# Inference target.
|
|
606
|
-
agentcore gateway invoke \
|
|
607
|
-
--id <gatewayId> \
|
|
608
|
-
--path inference/v1/messages \
|
|
609
|
-
--payload file://message.json \
|
|
610
|
-
--json
|
|
611
|
-
|
|
612
|
-
# GET requests do not accept a payload.
|
|
613
|
-
agentcore gateway invoke \
|
|
614
|
-
--id <gatewayId> \
|
|
615
|
-
--method GET \
|
|
616
|
-
--path inference/v1/models
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
`--path` replaces the path in the returned Gateway URL while retaining its
|
|
620
|
-
origin. It must remain relative to the selected Gateway and may include a query
|
|
621
|
-
string. Omitting it uses the returned `gatewayUrl` exactly. Supported methods
|
|
622
|
-
are `GET`, `POST` (the default), and `DELETE`. POST requires `--payload`; DELETE
|
|
623
|
-
may include one. Payloads accept inline bytes, `file://<path>`, or `-` for stdin.
|
|
624
|
-
|
|
625
|
-
Authentication follows `GetGateway.authorizerType`: `AWS_IAM` and
|
|
626
|
-
`AUTHENTICATE_ONLY` requests use SigV4, `CUSTOM_JWT` requires `--bearer-token`,
|
|
627
|
-
and `NONE` uses unsigned HTTPS. Bearer tokens accept inline, `file://`, or stdin
|
|
628
|
-
sources; payload and token cannot both read stdin.
|
|
629
|
-
|
|
630
|
-
Raw responses stream exact bytes to stdout. `--output-file` streams those bytes
|
|
631
|
-
to disk, while `--json` buffers one envelope containing status, selected session
|
|
632
|
-
and request metadata, body encoding, and body. Binary or unknown output requires
|
|
633
|
-
`--output-file` or `--json` when stdout is a terminal. Response metadata goes to
|
|
634
|
-
stderr in raw and file modes. Redirects are returned without being followed.
|
|
635
|
-
Non-2xx response bodies use the selected output mode before the command exits
|
|
636
|
-
with a failure status.
|
|
637
|
-
|
|
638
|
-
Without `--payload`, Gateway Invoke opens a persistent POST JSON console. Bare
|
|
639
|
-
invoke opens the Gateway picker, while `--id` opens the selected Gateway
|
|
640
|
-
directly. `--path`, `--session-id`, MCP session flags, `--header`, and
|
|
641
|
-
`--bearer-token` seed the console. Interactive bearer tokens may be inline or
|
|
642
|
-
`file://` sources, but not stdin. Explicit headless-only flags such as
|
|
643
|
-
`--method`, `--accept`, `--content-type`, `--output-file`, or `--json` keep the
|
|
644
|
-
command headless.
|
|
645
|
-
|
|
646
|
-
The console generates and displays a Runtime session ID, adopts returned Runtime
|
|
647
|
-
and MCP sessions, and streams textual responses as they arrive. An empty path
|
|
648
|
-
uses the exact `gatewayUrl`; `Ctrl+P` edits the raw Gateway-relative path and
|
|
649
|
-
`Ctrl+T` switches Gateways. Switching Gateways clears request context, while
|
|
650
|
-
changing paths preserves the draft and Gateway authentication but starts fresh
|
|
651
|
-
sessions.
|
|
652
|
-
|
|
653
|
-
| Shortcut | Action |
|
|
654
|
-
| ------------- | -------------------------------------------- |
|
|
655
|
-
| `Enter` | Send the JSON request |
|
|
656
|
-
| `Shift+Enter` | Insert a newline |
|
|
657
|
-
| `Ctrl+P` | Edit the Gateway-relative path |
|
|
658
|
-
| `Ctrl+T` | Change Gateway |
|
|
659
|
-
| `Ctrl+V` | Toggle raw and pretty completed JSON |
|
|
660
|
-
| `Esc` | Interrupt an active request or navigate back |
|
|
661
|
-
| `↑`/`↓` | Scroll response history |
|
|
662
|
-
|
|
663
|
-
Gateway Invoke V1 has no request-type selector, target/path discovery,
|
|
664
|
-
tool/model discovery command, authentication editor, or protocol-specific
|
|
665
|
-
payload builder. Callers provide the Gateway-relative route and protocol payload
|
|
666
|
-
directly. GET and DELETE remain available through headless invoke.
|
|
667
|
-
|
|
668
|
-
### Invoke a Runtime
|
|
669
|
-
|
|
670
|
-
Headless invocation accepts inline, file, or stdin payload bytes:
|
|
671
|
-
|
|
672
|
-
```bash
|
|
673
|
-
# Inline
|
|
674
|
-
agentcore runtime invoke \
|
|
675
|
-
--id <runtimeId> \
|
|
676
|
-
--payload '{"action":"status"}' \
|
|
677
|
-
--content-type application/json \
|
|
678
|
-
--accept text/event-stream
|
|
679
|
-
|
|
680
|
-
# File
|
|
681
|
-
agentcore runtime invoke --id <runtimeId> --payload file://request.json
|
|
682
|
-
|
|
683
|
-
# stdin
|
|
684
|
-
cat request.json | agentcore runtime invoke --id <runtimeId> --payload -
|
|
685
|
-
```
|
|
686
|
-
|
|
687
|
-
CUSTOM_JWT Runtimes require `--bearer-token`. The token accepts the same inline,
|
|
688
|
-
`file://`, or stdin sources as the payload; payload and token cannot both read
|
|
689
|
-
stdin.
|
|
93
|
+
(`transformAgentCoreJson`). All three come from `@aws/agentcore-cdk`, so that
|
|
94
|
+
logic is updated through the library rather than changes to your CDK app.
|
|
690
95
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
--bearer-token file://$HOME/.config/agentcore/runtime-token
|
|
696
|
-
```
|
|
697
|
-
|
|
698
|
-
For MCP Runtimes, initialize first, then pass the returned Runtime and MCP
|
|
699
|
-
session IDs to later methods. MCP requests accept both JSON and SSE responses.
|
|
700
|
-
|
|
701
|
-
```bash
|
|
702
|
-
agentcore runtime invoke \
|
|
703
|
-
--id <runtimeId> \
|
|
704
|
-
--payload '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"agentcore-cli","version":"1"}}}' \
|
|
705
|
-
--accept 'application/json, text/event-stream' \
|
|
706
|
-
--mcp-protocol-version 2025-03-26 \
|
|
707
|
-
--mcp-method initialize
|
|
708
|
-
|
|
709
|
-
agentcore runtime invoke \
|
|
710
|
-
--id <runtimeId> \
|
|
711
|
-
--payload '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
|
|
712
|
-
--accept 'application/json, text/event-stream' \
|
|
713
|
-
--session-id <returnedRuntimeSessionId> \
|
|
714
|
-
--mcp-session-id <returnedMcpSessionId> \
|
|
715
|
-
--mcp-protocol-version 2025-03-26 \
|
|
716
|
-
--mcp-method tools/list
|
|
717
|
-
```
|
|
718
|
-
|
|
719
|
-
Raw stdout always streams exact response bytes as they arrive, regardless of
|
|
720
|
-
content type. `--output-file` streams the same bytes directly to disk. Binary or
|
|
721
|
-
unknown responses require `--output-file` or `--json` when stdout is a terminal.
|
|
722
|
-
Response metadata is written to stderr.
|
|
723
|
-
|
|
724
|
-
`--json` buffers the complete response, including streaming representations, and
|
|
725
|
-
emits one metadata envelope without interpreting the customer body. If a raw or
|
|
726
|
-
file response fails, bytes already written remain available and the stderr
|
|
727
|
-
summary reports `complete=false`. A failed JSON response emits no partial
|
|
728
|
-
envelope.
|
|
729
|
-
|
|
730
|
-
```bash
|
|
731
|
-
agentcore runtime invoke \
|
|
732
|
-
--id <runtimeId> \
|
|
733
|
-
--payload file://request.bin \
|
|
734
|
-
--content-type application/octet-stream \
|
|
735
|
-
--accept application/octet-stream \
|
|
736
|
-
--output-file response.bin
|
|
737
|
-
|
|
738
|
-
agentcore runtime invoke --id <runtimeId> --payload '{"action":"status"}' --json
|
|
739
|
-
# {"statusCode":200,"contentType":"application/json","bodyEncoding":"utf8","body":"{\"ok\":true}","complete":true}
|
|
740
|
-
```
|
|
741
|
-
|
|
742
|
-
Without `--payload`, Runtime Invoke opens a persistent JSON console for repeated
|
|
743
|
-
requests. The console sends inline `application/json` payloads and renders each
|
|
744
|
-
response according to its returned content type. Bare invoke opens the Runtime
|
|
745
|
-
and endpoint pickers; `--id` skips the Runtime picker, and `--id` plus
|
|
746
|
-
`--qualifier` opens the console directly. `--session-id` resumes that Runtime
|
|
747
|
-
session in the console. `--user-id`, `--header`, and `--bearer-token` seed
|
|
748
|
-
request context that persists across sends and endpoint changes within that
|
|
749
|
-
Runtime. The console never displays their values, and switching Runtimes clears
|
|
750
|
-
them. Interactive bearer tokens may be inline or `file://` sources, but not
|
|
751
|
-
stdin.
|
|
752
|
-
|
|
753
|
-
| Shortcut | Action |
|
|
754
|
-
| ------------- | -------------------------------------------- |
|
|
755
|
-
| `Enter` | Send the JSON request |
|
|
756
|
-
| `Shift+Enter` | Insert a newline |
|
|
757
|
-
| `Ctrl+T` | Change Runtime or endpoint |
|
|
758
|
-
| `Ctrl+V` | Toggle raw and pretty completed JSON |
|
|
759
|
-
| `Esc` | Interrupt an active request or navigate back |
|
|
760
|
-
| `↑`/`↓` | Scroll response history |
|
|
761
|
-
|
|
762
|
-
Runtime Invoke accepts Runtime IDs from the current account only. It does not
|
|
763
|
-
accept ARNs, `--version`, `--interactive`, cross-account targets, or custom
|
|
764
|
-
request paths. All requests use the Runtime `/invocations` route, including MCP
|
|
765
|
-
Runtimes.
|
|
766
|
-
|
|
767
|
-
### Open a Runtime shell
|
|
96
|
+
`lib/cdk-stack.ts` instantiates one `AgentCoreApplication`. This is the file you
|
|
97
|
+
edit to add your own resources. Runtimes and harnesses implement `iam.IGrantable`,
|
|
98
|
+
so you can pass them to a resource's CDK grant methods to give your agents access.
|
|
99
|
+
Use `addEnvironmentVariable` to pass resource names, ARNs, or endpoints to your agent.
|
|
768
100
|
|
|
769
|
-
|
|
770
|
-
Bare shell opens the Runtime and endpoint pickers. `--id` skips the Runtime
|
|
771
|
-
picker, and `--id` plus `--qualifier` connects directly.
|
|
772
|
-
|
|
773
|
-
```bash
|
|
774
|
-
agentcore runtime shell
|
|
775
|
-
agentcore runtime shell --id <runtimeId>
|
|
776
|
-
agentcore runtime shell --id <runtimeId> --qualifier DEFAULT
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
Use `--session-id` to open the shell in a specific Runtime session/VM:
|
|
780
|
-
|
|
781
|
-
```bash
|
|
782
|
-
agentcore runtime shell \
|
|
783
|
-
--id <runtimeId> \
|
|
784
|
-
--qualifier DEFAULT \
|
|
785
|
-
--session-id <runtimeSessionId>
|
|
786
|
-
```
|
|
787
|
-
|
|
788
|
-
CUSTOM_JWT Runtimes require `--bearer-token`. Interactive bearer tokens may be
|
|
789
|
-
inline or `file://` sources, but not stdin.
|
|
790
|
-
|
|
791
|
-
The shell forwards terminal input byte-for-byte, including `Ctrl+C`, `Ctrl+D`,
|
|
792
|
-
escape sequences, and full-screen terminal applications. Terminal resize events
|
|
793
|
-
update the remote PTY. Running `exit` or sending `Ctrl+D` terminates the remote
|
|
794
|
-
shell.
|
|
795
|
-
|
|
796
|
-
Runtime Shell requires TTY stdin and stdout and does not support `--json` or
|
|
797
|
-
`--endpoint-url`.
|
|
798
|
-
|
|
799
|
-
Bare Runtime branches and leaves, plus `memory`, `memory get`, and `memory list`,
|
|
800
|
-
require a TTY on stdin and stdout.
|
|
801
|
-
For Runtime Invoke, supplying a payload or headless-only request or output flags
|
|
802
|
-
runs headlessly; `--session-id` can instead seed the persistent console.
|
|
803
|
-
Supplying Memory operation flags runs those commands headlessly, and `--json`
|
|
804
|
-
always suppresses TUI rendering. The `memory event` and `memory record` groups
|
|
805
|
-
are headless: invoking a group without a leaf prints help, and their leaves
|
|
806
|
-
require resource selectors.
|
|
807
|
-
|
|
808
|
-
```bash
|
|
809
|
-
agentcore runtime
|
|
810
|
-
agentcore runtime list
|
|
811
|
-
agentcore runtime get
|
|
812
|
-
agentcore runtime version list
|
|
813
|
-
agentcore runtime endpoint list
|
|
814
|
-
agentcore memory
|
|
815
|
-
agentcore memory list
|
|
816
|
-
agentcore memory get
|
|
817
|
-
agentcore memory event
|
|
818
|
-
agentcore memory record
|
|
819
|
-
```
|
|
820
|
-
|
|
821
|
-
The Identity TUI is read-only: bare `identity` branches and the `get`/`list`
|
|
822
|
-
leaves open interactive menus and detail views. Mutations (`create`, `update`,
|
|
823
|
-
`delete`) remain available through the CLI and are omitted from the TUI menus.
|
|
824
|
-
|
|
825
|
-
```bash
|
|
826
|
-
agentcore identity
|
|
827
|
-
agentcore identity api-key-credential-provider list
|
|
828
|
-
agentcore identity api-key-credential-provider get
|
|
829
|
-
agentcore identity oauth2-credential-provider list
|
|
830
|
-
agentcore identity oauth2-credential-provider get
|
|
831
|
-
```
|
|
832
|
-
|
|
833
|
-
The Gateway TUI is read-only: bare Gateway, Target, Connector, and Rule
|
|
834
|
-
branches and their `get`/`list` leaves open command menus and scoped selection
|
|
835
|
-
flows. Connector is presented as a separate resource experience while using
|
|
836
|
-
Gateway Target operations internally.
|
|
837
|
-
|
|
838
|
-
```bash
|
|
839
|
-
agentcore gateway
|
|
840
|
-
agentcore gateway list
|
|
841
|
-
agentcore gateway get
|
|
842
|
-
agentcore gateway target list
|
|
843
|
-
agentcore gateway target get
|
|
844
|
-
agentcore gateway connector list
|
|
845
|
-
agentcore gateway connector get
|
|
846
|
-
agentcore gateway rule list
|
|
847
|
-
agentcore gateway rule get
|
|
848
|
-
```
|
|
849
|
-
|
|
850
|
-
---
|
|
851
|
-
|
|
852
|
-
# Architecture & patterns
|
|
853
|
-
|
|
854
|
-
This section documents the architectural conventions the codebase is built
|
|
855
|
-
around. They exist to keep the app modular, testable, and predictable as it
|
|
856
|
-
grows.
|
|
857
|
-
|
|
858
|
-
## The big picture
|
|
859
|
-
|
|
860
|
-
```
|
|
861
|
-
┌───────────────────────────┐
|
|
862
|
-
argv ─────────────▶ │ Router / Handler tree │ src/router, src/handlers
|
|
863
|
-
│ (flags, args, middleware)│
|
|
864
|
-
└────────────┬──────────────┘
|
|
865
|
-
│
|
|
866
|
-
flags/args ? │ bare command ?
|
|
867
|
-
│ │ │
|
|
868
|
-
▼ ▼
|
|
869
|
-
┌─────────────────┐ ┌───────────────────┐
|
|
870
|
-
│ headless handler│ │ Ink/React TUI │ src/tui, src/components
|
|
871
|
-
│ → JSON output │ │ (same handlers) │
|
|
872
|
-
└────────┬────────┘ └────────┬──────────┘
|
|
873
|
-
│ │
|
|
874
|
-
└──────────┬─────────────┘
|
|
875
|
-
▼
|
|
876
|
-
┌───────────────────────┐
|
|
877
|
-
│ Core (CoreClient) │ src/core
|
|
878
|
-
│ feature sub-clients │
|
|
879
|
-
└──────────┬────────────┘
|
|
880
|
-
▼
|
|
881
|
-
AWS SDK: Bedrock AgentCore (control + data) + IAM
|
|
882
|
-
```
|
|
883
|
-
|
|
884
|
-
The CLI and the TUI are two front-ends over the **same** handler tree and the
|
|
885
|
-
**same** `Core` clients. Dependencies are injected at the edge in the main entrypoint (`src/index.ts`),
|
|
886
|
-
which is what makes the whole thing testable end-to-end.
|
|
887
|
-
|
|
888
|
-
## The Router / Handler framework
|
|
889
|
-
|
|
890
|
-
The whole CLI is expressed as a tree of **`Handler`** nodes wired together by a
|
|
891
|
-
**`Router`** (`src/router/`). A `Router` is itself a mountable branch node, so
|
|
892
|
-
routers nest to form the command tree (`agentcore` → `harness` → `get`). Every
|
|
893
|
-
command — branch or leaf — is a `Handler`:
|
|
894
|
-
|
|
895
|
-
- **Branch nodes** (routers) host subcommands and may declare group-level
|
|
896
|
-
("global") flags and middleware that apply to everything beneath them. A
|
|
897
|
-
branch can also register a **default handler** (`router.default(...)`) that
|
|
898
|
-
runs when the branch is invoked with no subcommand (e.g. bare `agentcore` or
|
|
899
|
-
`agentcore harness` — this is how the TUI launches).
|
|
900
|
-
- **Leaf nodes** (built with `createHandler(...)`) do the work. They declare
|
|
901
|
-
their own flags/arguments (validated and coerced via zod schemas) and receive
|
|
902
|
-
a typed object in `handle(ctx, flags, args)`.
|
|
903
|
-
|
|
904
|
-
Every node — branch or leaf — satisfies the `Handler` interface:
|
|
101
|
+
This example gives the generated runtime named `agent` access to a table:
|
|
905
102
|
|
|
906
103
|
```ts
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
arguments(): Argument[];
|
|
912
|
-
// At runtime `handle` receives the validated, coerced flags object. The precise
|
|
913
|
-
// shape is supplied to authors via createHandler's generic; the interface keeps
|
|
914
|
-
// it erased so middleware can forward it uniformly.
|
|
915
|
-
handle: (ctx: Context, flags: any, args: any) => Promise<void>;
|
|
916
|
-
children(): Handler[];
|
|
917
|
-
}
|
|
918
|
-
```
|
|
919
|
-
|
|
920
|
-
Under the hood the tree is compiled into a [Commander](https://github.com/tj/commander.js)
|
|
921
|
-
command tree (`src/router/router.tsx`), so `--help`, argument parsing, and error
|
|
922
|
-
handling come from a battle-tested parser while the authoring API stays small.
|
|
923
|
-
|
|
924
|
-
Cross-cutting values flow through a typed **`Context`**. Group-level flags
|
|
925
|
-
(`globalFlag(...)`) double as context keys, so a flag declared high in the tree
|
|
926
|
-
is read type-safely by any descendant via `ctx.value(key)` / `ctx.require(key)`.
|
|
104
|
+
import { AgentCoreApplication, type AgentCoreApplicationProps } from "@aws/agentcore-cdk";
|
|
105
|
+
import { Stack, type StackProps } from "aws-cdk-lib";
|
|
106
|
+
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
|
|
107
|
+
import { Construct } from "constructs";
|
|
927
108
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
// value returns the value previously stored under `key`, or undefined if absent.
|
|
931
|
-
value<V>(key: ContextKey<V>): V | undefined;
|
|
932
|
-
// require returns the value stored under `key`, throwing if it is absent.
|
|
933
|
-
require<V>(key: ContextKey<V>): V;
|
|
934
|
-
// withValue returns a new Context that carries `key`/`value` on top of this one.
|
|
935
|
-
withValue<V>(key: ContextKey<V>, value: V): Context;
|
|
109
|
+
export interface AgentCoreStackProps extends StackProps {
|
|
110
|
+
application: AgentCoreApplicationProps;
|
|
936
111
|
}
|
|
937
|
-
```
|
|
938
|
-
|
|
939
|
-
**Middleware** (`router.use(...)`) wraps handlers down the subtree in
|
|
940
|
-
ancestor-first order — for example `withRegion` resolves the effective AWS
|
|
941
|
-
region once at the root and pins it on the context for every command below. A
|
|
942
|
-
middleware is just a function that wraps one `Handler` in another:
|
|
943
|
-
|
|
944
|
-
```ts
|
|
945
|
-
export type Middleware = (handler: Handler) => Handler;
|
|
946
|
-
```
|
|
947
|
-
|
|
948
|
-
### Putting it all together
|
|
949
|
-
|
|
950
|
-
A minimal, self-contained example — a router with one piece of middleware and a
|
|
951
|
-
`greet` leaf handler:
|
|
952
|
-
|
|
953
|
-
```ts
|
|
954
|
-
import z from "zod";
|
|
955
|
-
import { Router, createHandler, flag, globalFlag, type Middleware } from "./router";
|
|
956
112
|
|
|
957
|
-
|
|
958
|
-
|
|
113
|
+
export class AgentCoreStack extends Stack {
|
|
114
|
+
public readonly application: AgentCoreApplication;
|
|
959
115
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
description: () => h.description(),
|
|
964
|
-
flags: () => h.flags(),
|
|
965
|
-
arguments: () => h.arguments(),
|
|
966
|
-
children: () => h.children(),
|
|
967
|
-
handle: async (ctx, flags, args) => {
|
|
968
|
-
console.error(`> running ${h.name()}`);
|
|
969
|
-
await h.handle(ctx, flags, args);
|
|
970
|
-
},
|
|
971
|
-
});
|
|
972
|
-
|
|
973
|
-
// A leaf handler. `flags` is precisely typed from the zod schemas, and the
|
|
974
|
-
// group-level LoudKey is read back off the context.
|
|
975
|
-
const greet = createHandler({
|
|
976
|
-
name: "greet",
|
|
977
|
-
description: "greet someone",
|
|
978
|
-
flags: [flag("name", "who to greet", z.string().default("world"))] as const,
|
|
979
|
-
handle: async (ctx, flags) => {
|
|
980
|
-
const message = `hello, ${flags.name}!`;
|
|
981
|
-
console.log(ctx.value(LoudKey) ? message.toUpperCase() : message);
|
|
982
|
-
},
|
|
983
|
-
});
|
|
984
|
-
|
|
985
|
-
// Wire it together: flags + middleware live on the router, handlers mount under it.
|
|
986
|
-
const app = new Router("demo", "a tiny demo CLI")
|
|
987
|
-
.groupFlags(LoudKey)
|
|
988
|
-
.use(withLogging())
|
|
989
|
-
.handler(greet);
|
|
990
|
-
|
|
991
|
-
await app.route(process.argv);
|
|
992
|
-
```
|
|
993
|
-
|
|
994
|
-
```bash
|
|
995
|
-
demo greet --name Ada # hello, Ada!
|
|
996
|
-
demo greet --name Ada --loud # HELLO, ADA!
|
|
997
|
-
```
|
|
998
|
-
|
|
999
|
-
## Adding a new handler
|
|
1000
|
-
|
|
1001
|
-
Each command lives in its own directory with a consistent file layout. Using
|
|
1002
|
-
`harness` as the model:
|
|
1003
|
-
|
|
1004
|
-
```
|
|
1005
|
-
src/handlers/harness/
|
|
1006
|
-
├── index.tsx # createHarnessHandler(core): builds the Router/Handler, wires
|
|
1007
|
-
│ # subcommands, middleware, flags, and the default handler
|
|
1008
|
-
├── screen.tsx # the Ink/React screen(s) rendered for this command in the TUI
|
|
1009
|
-
├── types.tsx # the interface(s) this command consumes from Core (see below)
|
|
1010
|
-
├── get/ # a subcommand, same layout recursively
|
|
1011
|
-
│ ├── index.tsx
|
|
1012
|
-
│ └── screen.tsx
|
|
1013
|
-
└── list/
|
|
1014
|
-
├── index.tsx
|
|
1015
|
-
└── screen.tsx
|
|
1016
|
-
```
|
|
1017
|
-
|
|
1018
|
-
Conventions:
|
|
1019
|
-
|
|
1020
|
-
- **`index.tsx`** exports a `create<Name>Handler(core)` factory returning a
|
|
1021
|
-
`Handler`/`Router`. Dependencies (the `Core` client) are passed in, never
|
|
1022
|
-
imported as singletons. Re-export the command's `screen.tsx` from here.
|
|
1023
|
-
- **`screen.tsx`** exports the React component(s) for the TUI. Screens receive
|
|
1024
|
-
`ScreenProps` (`{ ctx, core }`) threaded down from `Root`, and drive data
|
|
1025
|
-
fetching with react-query against `core`.
|
|
1026
|
-
- **`types.tsx`** defines the interface(s) this command needs from Core.
|
|
1027
|
-
- Shared helpers live in a sibling `utils.tsx` (e.g. `coreOptsFromCtx(ctx)`
|
|
1028
|
-
builds the standard `CoreOptions` from context values).
|
|
1029
|
-
- Shared components live in `src/components/`: anything rendered by more than
|
|
1030
|
-
one screen belongs there (e.g. `Layout`, `RouterScreen`, `HarnessPicker`),
|
|
1031
|
-
with the vendored InkUI primitives under `src/components/ui/`. A handler
|
|
1032
|
-
directory contains only the screens for its own command.
|
|
1033
|
-
|
|
1034
|
-
Mount the new handler by adding `root.handler(create<Name>Handler(core))` in
|
|
1035
|
-
`src/handlers/index.tsx` (or on the appropriate parent router).
|
|
1036
|
-
|
|
1037
|
-
## Core and dependency inversion
|
|
1038
|
-
|
|
1039
|
-
Business logic and all I/O (AWS SDK calls, etc.) live in **`src/core/`**, behind
|
|
1040
|
-
a `CoreClient` that exposes feature-scoped sub-clients (e.g. `core.harness`).
|
|
1041
|
-
`CoreClient` owns the underlying AWS clients — the Bedrock AgentCore
|
|
1042
|
-
**control** plane (CRUD, versions, endpoints), the **data** plane (invoke, exec
|
|
1043
|
-
streaming), **IAM** (default execution roles) — caching one per config.
|
|
1044
|
-
|
|
1045
|
-
The important rule: **interfaces are defined by their consumers, not by Core.**
|
|
1046
|
-
The `CoreHarnessClient` interface lives in `src/handlers/harness/types.tsx` —
|
|
1047
|
-
next to the handler that uses it — and `src/core/harness.tsx` provides the
|
|
1048
|
-
implementation. Handlers depend on the interface they declare; Core depends on
|
|
1049
|
-
nothing about the handlers. This is **dependency inversion**: the
|
|
1050
|
-
high-level policy (handlers) owns the abstraction, and the low-level detail
|
|
1051
|
-
(Core/SDK) conforms to it.
|
|
1052
|
-
|
|
1053
|
-
Construction is also inverted. `CoreClient` doesn't build SDK clients directly;
|
|
1054
|
-
it takes **factory functions** (`(config) => new BedrockAgentCore...Client(...)`)
|
|
1055
|
-
injected at the app edge in `src/index.ts`. That keeps the SDK swappable —
|
|
1056
|
-
crucial for the testing strategy below.
|
|
1057
|
-
|
|
1058
|
-
## The TUI
|
|
1059
|
-
|
|
1060
|
-
The interactive UI is built with [Ink](https://github.com/vadimdemedes/ink)
|
|
1061
|
-
(React for the terminal). `renderTui` mounts the `Root` component
|
|
1062
|
-
(`src/components/Root.tsx`) — a MemoryRouter over the app's route table plus a
|
|
1063
|
-
react-query client — seeded at the command's path. Because routes map to the
|
|
1064
|
-
same handler paths as the CLI, deep-linking works: `harness invoke --id X` opens
|
|
1065
|
-
the chat screen at that harness. Ink reads and writes through the injected IO
|
|
1066
|
-
streams, so the TUI is fully testable without a real terminal.
|
|
1067
|
-
|
|
1068
|
-
## Testing
|
|
1069
|
-
|
|
1070
|
-
Tests sit next to the code they cover as `<file>.test.tsx` (e.g.
|
|
1071
|
-
`src/router/router.test.ts`), run with `bun test`. Shared test infrastructure
|
|
1072
|
-
lives in `src/testing/`.
|
|
1073
|
-
|
|
1074
|
-
The guiding principle is **test behavior, not implementation**: a good test lets
|
|
1075
|
-
a maintainer refactor freely and only fails when observable behavior changes.
|
|
1076
|
-
This is possible because the app injects every dependency at its edges, so a
|
|
1077
|
-
test can build the whole CLI with test doubles at the boundary and drive a real
|
|
1078
|
-
command flow — argument parsing, middleware, handler, Core, and (for the TUI)
|
|
1079
|
-
rendering — as a single unit, asserting on the output a user would see.
|
|
1080
|
-
|
|
1081
|
-
We aim for **90% line coverage** (`bun test --coverage`).
|
|
1082
|
-
|
|
1083
|
-
### Injected IO
|
|
1084
|
-
|
|
1085
|
-
Nothing in the app reaches for `process.stdout`/`console.*` directly. An `AppIO`
|
|
1086
|
-
(`{ stdin, stdout, stderr }`, defined in `src/handlers/types.tsx`) is passed to
|
|
1087
|
-
`createRootHandler(core, io)` at the edge (`src/index.ts` passes the real process
|
|
1088
|
-
streams) and threaded down to the TUI renderer and handlers. JSON output flows
|
|
1089
|
-
through the context: a `withJsonRenderer` middleware pins a `JsonRenderer` wired
|
|
1090
|
-
to the configured stdout, and leaf handlers emit via
|
|
1091
|
-
`ctx.require(JsonRendererKey).renderJson(...)`. In tests, `testIO()` supplies an
|
|
1092
|
-
in-memory `AppIO` with `stdout()`/`stderr()` accessors, so a command's output is
|
|
1093
|
-
captured with no global patching.
|
|
1094
|
-
|
|
1095
|
-
### Golden files and record mode
|
|
1096
|
-
|
|
1097
|
-
Handler tests run the real `CoreClient` over fixture-backed SDK clients and
|
|
1098
|
-
compare rendered output against committed **golden files**. The record/replay
|
|
1099
|
-
seam sits at the SDK `.send()` boundary (the same seam `src/index.ts` wires the
|
|
1100
|
-
real clients into), so replayed tests still exercise the real `CoreClient`,
|
|
1101
|
-
`HarnessClient`, and option translation — only the network call is swapped out.
|
|
1102
|
-
|
|
1103
|
-
Two modes, selected by the `RECORD` env var:
|
|
1104
|
-
|
|
1105
|
-
```bash
|
|
1106
|
-
RECORD=1 bun test # hit the live AWS APIs and (re)write fixtures + golden files
|
|
1107
|
-
bun test # replay the saved fixtures; never touch the network
|
|
1108
|
-
```
|
|
116
|
+
constructor(scope: Construct, id: string, props: AgentCoreStackProps) {
|
|
117
|
+
super(scope, id, props);
|
|
118
|
+
this.application = new AgentCoreApplication(this, "Application", props.application);
|
|
1109
119
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
on the pattern.
|
|
1119
|
-
|
|
1120
|
-
### TUI tests
|
|
1121
|
-
|
|
1122
|
-
Screens are tested with
|
|
1123
|
-
[`ink-testing-library`](https://github.com/vadimdemedes/ink-testing-library) via
|
|
1124
|
-
the `renderScreen(path, { core })` helper (`src/testing/renderScreen.tsx`). It
|
|
1125
|
-
mounts the real `Root` (MemoryRouter + the app's route table + react-query)
|
|
1126
|
-
seeded at a command path — exactly how the CLI mounts a screen — so routing,
|
|
1127
|
-
route params, data fetching, key input, and rendering are all exercised
|
|
1128
|
-
together. Data comes from a `TestCoreClient` (a hand-controllable `Core` that
|
|
1129
|
-
returns canned responses, forces errors, and records calls). Assertions read the
|
|
1130
|
-
rendered frame (`waitForText`, `lastFrame`) and key presses drive navigation
|
|
1131
|
-
between screens (`press`, `write`).
|
|
1132
|
-
|
|
1133
|
-
## Repository layout
|
|
1134
|
-
|
|
1135
|
-
```
|
|
1136
|
-
src/
|
|
1137
|
-
index.ts # app entry: wires real SDK factories + process IO into the root handler
|
|
1138
|
-
router/ # the Router/Handler framework (compiles to Commander)
|
|
1139
|
-
handlers/ # the command tree; one directory per command (index/screen/types)
|
|
1140
|
-
core/ # CoreClient + feature sub-clients; all AWS SDK I/O lives here
|
|
1141
|
-
middleware/ # cross-cutting middleware (withRegion, withJsonRenderer, ...)
|
|
1142
|
-
tui/ # Ink renderer entry (renderTui / renderTuiAt) + JSON renderer
|
|
1143
|
-
components/ # shared TUI components; ui/ holds vendored InkUI primitives
|
|
1144
|
-
testing/ # test doubles + helpers (testIO, renderScreen, fixtures, golden IO)
|
|
1145
|
-
runnable/ # top-level run/exit-code wrapper
|
|
1146
|
-
```
|
|
1147
|
-
|
|
1148
|
-
---
|
|
1149
|
-
|
|
1150
|
-
# Development
|
|
1151
|
-
|
|
1152
|
-
Install [Bun](https://bun.com).
|
|
1153
|
-
|
|
1154
|
-
```bash
|
|
1155
|
-
brew install oven-sh/bun/bun
|
|
1156
|
-
```
|
|
1157
|
-
|
|
1158
|
-
Install dependencies:
|
|
1159
|
-
|
|
1160
|
-
```bash
|
|
1161
|
-
bun install
|
|
1162
|
-
```
|
|
1163
|
-
|
|
1164
|
-
Run from source:
|
|
1165
|
-
|
|
1166
|
-
```bash
|
|
1167
|
-
bun run start
|
|
1168
|
-
```
|
|
1169
|
-
|
|
1170
|
-
Run tests:
|
|
1171
|
-
|
|
1172
|
-
```bash
|
|
1173
|
-
bun test
|
|
1174
|
-
```
|
|
1175
|
-
|
|
1176
|
-
## Run Locally
|
|
1177
|
-
|
|
1178
|
-
Build, then symlink the `agentcore` command globally so it works from any directory:
|
|
1179
|
-
|
|
1180
|
-
```bash
|
|
1181
|
-
bun run build
|
|
1182
|
-
npm link
|
|
1183
|
-
```
|
|
1184
|
-
|
|
1185
|
-
Re-run `bun run build` after changes; the linked command picks it up. Remove with:
|
|
1186
|
-
|
|
1187
|
-
```bash
|
|
1188
|
-
npm unlink -g @aws/agentcore
|
|
1189
|
-
```
|
|
1190
|
-
|
|
1191
|
-
To test the exact published artifact instead:
|
|
1192
|
-
|
|
1193
|
-
```bash
|
|
1194
|
-
npm pack # builds via prepublishOnly, creates the .tgz
|
|
1195
|
-
npm i -g ./aws-agentcore-0.28.1.tgz
|
|
1196
|
-
```
|
|
1197
|
-
|
|
1198
|
-
## Windows notes
|
|
1199
|
-
|
|
1200
|
-
- **`agentcore.ps1 cannot be loaded because running scripts is disabled`**: the
|
|
1201
|
-
npm shim is a PowerShell script and Windows Server defaults to a `Restricted`
|
|
1202
|
-
execution policy. Run `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned`
|
|
1203
|
-
once, or call `agentcore.cmd`. The compiled `.exe` has no shim.
|
|
1204
|
-
- **The CLI looks frozen in a PowerShell window**: legacy conhost pauses all
|
|
1205
|
-
output while text is selected (the title bar shows `Select`). Press `Esc`.
|
|
1206
|
-
Windows Terminal does not do this.
|
|
1207
|
-
- **`project create` refuses a long path**: Windows caps paths at 260 characters
|
|
1208
|
-
unless `LongPathsEnabled` is set, and the CDK app's `node_modules` puts its
|
|
1209
|
-
deepest file 155 characters below the project root (aws-cdk-lib's own shipped
|
|
1210
|
-
fixtures), so the project root must be at most 104 characters. Create the
|
|
1211
|
-
project higher in the tree or enable long paths.
|
|
1212
|
-
|
|
1213
|
-
# Build
|
|
1214
|
-
|
|
1215
|
-
Run `make` to verify bun is installed, build the Node bundle, and compile all native binaries:
|
|
1216
|
-
|
|
1217
|
-
```bash
|
|
1218
|
-
make # check-bun -> build -> compile (all platforms)
|
|
1219
|
-
make bundle # node bundle only (dist/index.js)
|
|
1220
|
-
make compile # native binaries only (dist/bin/)
|
|
1221
|
-
make clean # remove dist/
|
|
1222
|
-
```
|
|
1223
|
-
|
|
1224
|
-
`make` errors out early if bun is not installed.
|
|
1225
|
-
|
|
1226
|
-
Bundle the CLI into `dist/` for distribution. The bundle targets Node.js and is the artifact published to npm (via the `bin` entry):
|
|
1227
|
-
|
|
1228
|
-
```bash
|
|
1229
|
-
make bundle
|
|
1230
|
-
```
|
|
1231
|
-
|
|
1232
|
-
The output (`dist/index.js`) can be run directly with Node:
|
|
1233
|
-
|
|
1234
|
-
```bash
|
|
1235
|
-
node dist/index.js
|
|
1236
|
-
```
|
|
1237
|
-
|
|
1238
|
-
## Native binaries
|
|
1239
|
-
|
|
1240
|
-
Compile standalone executables (Bun runtime embedded; no Node/Bun required to run) for all platforms into `dist/bin/`:
|
|
1241
|
-
|
|
1242
|
-
```bash
|
|
1243
|
-
make compile
|
|
120
|
+
const orders = new dynamodb.Table(this, "Orders", {
|
|
121
|
+
partitionKey: { name: "pk", type: dynamodb.AttributeType.STRING },
|
|
122
|
+
});
|
|
123
|
+
const agent = this.application.runtime("agent");
|
|
124
|
+
orders.grantReadWriteData(agent);
|
|
125
|
+
agent.addEnvironmentVariable("ORDERS_TABLE", orders.tableName);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
1244
128
|
```
|
|
1245
129
|
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
| Script | Output |
|
|
1249
|
-
| ----------------------- | ----------------------------- |
|
|
1250
|
-
| `compile:darwin-x64` | `agentcore-darwin-x64` |
|
|
1251
|
-
| `compile:darwin-arm64` | `agentcore-darwin-arm64` |
|
|
1252
|
-
| `compile:linux-x64` | `agentcore-linux-x64` |
|
|
1253
|
-
| `compile:linux-arm64` | `agentcore-linux-arm64` |
|
|
1254
|
-
| `compile:windows-x64` | `agentcore-windows-x64.exe` |
|
|
1255
|
-
| `compile:windows-arm64` | `agentcore-windows-arm64.exe` |
|
|
1256
|
-
|
|
1257
|
-
Each binary is ~60–95MB (embedded runtime).
|
|
130
|
+
For a Harness, use `this.application.harness("<name>")` instead.
|
|
1258
131
|
|
|
1259
|
-
|
|
132
|
+
Run `agentcore project deploy` to apply your changes. The names passed to
|
|
133
|
+
`runtime()` or `harness()` must match the names in your project.
|
|
1260
134
|
|
|
1261
|
-
|
|
135
|
+
If you use an existing execution role through `executionRoleArn`, CDK cannot
|
|
136
|
+
change its permissions. You'll need to add the required permissions to that role
|
|
137
|
+
yourself.
|
|
1262
138
|
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
bun run format:check # check only
|
|
1266
|
-
```
|
|
1267
|
-
|
|
1268
|
-
A Husky pre-commit hook runs Prettier (via lint-staged) on staged files automatically. It installs on `bun install`.
|
|
139
|
+
Note that `agentcore project status` reports only the resources `agentcore.json`
|
|
140
|
+
declares, not the ones you add in the stack.
|
|
1269
141
|
|
|
1270
|
-
|
|
142
|
+
## Documentation
|
|
1271
143
|
|
|
1272
|
-
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
data-plane operations, browser profiles, and the other AgentCore resources.
|
|
1276
|
-
- **Implement `config`.** The `config` command is currently a stub — it should
|
|
1277
|
-
read/write real global settings (telemetry, log level, ...) through an
|
|
1278
|
-
injected config accessor.
|
|
144
|
+
- [Amazon Bedrock AgentCore documentation](https://docs.aws.amazon.com/bedrock-agentcore/): service guides and API references.
|
|
145
|
+
- [Harness project configuration](docs/harness-project-configuration.md): Harness YAML, prompts, tools, skills, and environment settings.
|
|
146
|
+
- [Contributing](CONTRIBUTING.md): development, builds, architecture, and testing.
|