push-inventory-collector
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePush inventory collector
推送清单采集器
Generate one collector script for one self-managed scanner configuration. Do not assume a cloud vendor, a programming language, or a credential shape until the customer provides them. The script is the pull-scanner connection form on their machine, in the language they name. It reads their APIs, builds one payload per asset, uploads each payload, and then commits the scan. The scanner reconciles and publishes. The script does not publish by itself.
There is no universal provider credential set. There is no schedule on this scanner. Do not add a schedule, a last-run time, or a "run discovery" step.
为一个自托管 scanner 配置生成一个采集脚本。在客户提供信息前,不要假定云厂商、编程语言或凭据结构。脚本应采用客户指定的语言,作为其机器上的 pull-scanner 连接表单。它读取客户的 API,为每个资产生成一个 payload,上传每个 payload,然后提交扫描。由 scanner 执行核对和发布;脚本本身不负责发布。
不存在通用的 provider 凭据集合。此 scanner 也没有调度机制。不要添加调度、上次运行时间或“运行发现”步骤。
When to Use This Skill
何时使用此 Skill
Use this skill when the user asks to:
- Generate a collector script for a self-managed scanner
- How to Push, download the collector skill, or push inventory
- Write a script that calls POST /push then POST /commit
Trigger keywords: push inventory, push script, How to Push, self-managed scanner, collector skill, POST /push, POST /commit.
Do NOT use this skill when: creating a pull scanner that discovers from a connected cloud platform — use skill setup-service-scanner. Running a hosted scan and reviewing staging assets — use skill run-service-scan-and-view-results.
当用户要求以下事项时使用此 Skill:
- 为自托管 scanner 生成采集脚本
- How to Push、下载 collector skill,或推送 inventory
- 编写先调用 POST /push、再调用 POST /commit 的脚本
触发关键词: push inventory、push script、How to Push、self-managed scanner、collector skill、POST /push、POST /commit。
不要在以下场景使用此 Skill: 创建用于从已连接云平台发现资产的 pull scanner——请使用 skill setup-service-scanner;运行托管扫描并检查暂存资产——请使用 skill run-service-scan-and-view-results。
Prerequisites
前置条件
- Organization id and scanner configuration id copied from the self-managed scanner page
- A Connected App with client-credentials grant and on that organization
manage:exchange - The provider API specification they can paste or attach (OpenAPI, Postman, or a redacted request and response)
- Authentication documentation for those APIs, without secret values
- A language they can run on their machine
- 从自托管 scanner 页面复制的 Organization id 和 scanner configuration id
- 一个使用 client-credentials grant、并且在该组织上拥有 权限的 Connected App
manage:exchange - 客户可粘贴或附加的 provider API 规范(OpenAPI、Postman,或已脱敏的请求与响应)
- 这些 API 的认证文档,但不得包含 secret 值
- 客户机器上能够运行的编程语言
Reference files
参考文件
- — ZIP layout, POST /push multipart, POST /commit body. Read it before writing the upload and commit functions.
references/scanner-contract.md - — runtime inputs, stderr stages, JSON stdout, mapping fingerprint. Read it when writing the script.
references/generated-script-standard.md - — one question per turn, managed-only auth, new-provider contract. Read it when choosing operations and credential fields.
references/provider-auth-resolution.md
- ——ZIP 布局、POST /push multipart、POST /commit 请求体。编写上传和提交函数前必须阅读。
references/scanner-contract.md - ——运行时输入、stderr 阶段、JSON stdout、mapping fingerprint。编写脚本时必须阅读。
references/generated-script-standard.md - ——每轮只问一个问题、仅托管端可执行的认证方式、新 provider 契约。选择操作和凭据字段时必须阅读。
references/provider-auth-resolution.md
Workflow
工作流
Rules that always apply
始终适用的规则
- Customer-facing words — use the table below in every question, in , in the FAILED block, and in Ways to run the script. A wrong verb here is a generation failure.
--help - One question per response — never combine asset type, inventory, auth, or language.
- Never ask for a provider name — infer the provider from a usable spec. On an unreadable or incomplete spec, ask only the missing list, fetch, handshake, export, or auth piece.
- Never reorder — skip a step only when this chat already answered it with usable data. Ask a step again when the previous answer was unreadable, the wrong kind of file, or missing a required piece.
- Do not create a scanner during generation — do not log in, do not call Anypoint CLI, do not mint a token to discover an organization. Organization id and configuration id are values copied from the scanner page into the inputs file or the parameters.
Use these words. Do not hard-code a vendor, a non-production host, or a loopback address into a question or an example host. The example host is .
https://anypoint.mulesoft.com| Say | Do not say |
|---|---|
| script | adapter, collector, product command |
| input file, parameters, or prompts | three CLIs, CLI mode |
| self-managed scanner | self-serve, self-service, build your own |
| commit the scan | seal, seal the zip, complete and publish, publish to Exchange |
The upload call is . The finish call is . The question is exactly: "Commit this scan? [y/N]". A generated script that calls , , or is a generation failure. The JSON body still has a boolean field named . That field is not the customer sentence.
POST .../pushPOST .../commitPOST .../sealPOST .../completePOST .../push-assetscompleteExamples of an inventory (OpenAPI, a Postman collection, a redacted request and response) show the shape. They are not a menu and not a default. Language examples are not a fixed list. Do not default to one language.
A script that creates a configuration, calls , or calls in order to invent an organization id is a generation failure. That auto-fill is later work. It is not this script.
anypoint-cliGET /accounts/api/meThe only customer questions in this chat are the quoted sentences in Steps 1–5, the missing-piece follow-ups, "Does this look fine?", and the generated script's "Commit this scan? [y/N]". Do not ask which provider.
- 面向客户的措辞——在每个问题、、FAILED 块和脚本运行方式中使用下表。这里使用错误动词即视为生成失败。
--help - 每次响应只问一个问题——绝不能把资产类型、清单、认证或语言合并询问。
- 绝不询问 provider 名称——从可用的规范中推断 provider。如果规范无法读取或不完整,只询问缺少的列表、获取、握手、导出或认证部分。
- 绝不调整顺序——只有当前对话已经提供了可用数据时,才能跳过某一步。如果之前的回答无法读取、文件类型错误或缺少必要内容,则必须重新询问该步骤。
- 生成期间不要创建 scanner——不要登录,不要调用 Anypoint CLI,也不要签发 token 来发现 organization。Organization id 和 configuration id 应从 scanner 页面复制到输入文件或参数中。
请使用以下词语。不要在问题或示例 host 中硬编码厂商、非生产环境 host 或 loopback 地址。示例 host 为 。
https://anypoint.mulesoft.com| 使用 | 不要使用 |
|---|---|
| script | adapter, collector, product command |
| input file, parameters, or prompts | three CLIs, CLI mode |
| self-managed scanner | self-serve, self-service, build your own |
| commit the scan | seal, seal the zip, complete and publish, publish to Exchange |
上传调用为 ,结束调用为 。问题必须逐字为:。生成调用 、 或 的脚本即视为生成失败。JSON 请求体仍有一个名为 的 boolean 字段,但该字段不是面向客户的问题。
POST .../pushPOST .../commit"Commit this scan? [y/N]"POST .../sealPOST .../completePOST .../push-assetscompleteInventory 示例(OpenAPI、Postman collection、已脱敏的请求与响应)仅用于展示结构,并不是选项菜单或默认值。语言示例也不是固定列表。不要默认使用某一种语言。
创建配置、调用 ,或为了自行推断 organization id 而调用 的脚本均视为生成失败。这种自动填充属于后续工作,不属于本脚本。
anypoint-cliGET /accounts/api/me本对话中唯一允许面向客户提出的问题,是步骤 1–5 中加引号的句子、缺失信息的追问、,以及生成脚本中的 。不要询问 provider 名称。
"Does this look fine?""Commit this scan? [y/N]"Step 1: Ask asset type
步骤 1:询问资产类型
When the asset type is not already explicit, the whole message is:
"What asset type does this scanner configuration accept? Reply with one of: agent, mcp, or rest-api.
agent is one agent card. mcp is one MCP server card. rest-api is one API description. One script commits one of these, to one configuration."
Then stop.
Explicit means they wrote , , or , or a harmless alias ( → , / / → , / → ). A provider name, a file name, or an operation name is not an asset type. Do not infer the asset type from a single-type contract. Inferring the type so generation can jump ahead is a generation failure.
agentmcprest-apiagentsagentapiREST APIsAPIsrest-apiMCPMCP serversmcp如果尚未明确资产类型,整条消息必须为:
`"What asset type does this scanner configuration accept? Reply with one of: agent, mcp, or rest-api.
agent is one agent card. mcp is one MCP server card. rest-api is one API description. One script commits one of these, to one configuration."`
然后停止。
明确意味着用户写入了 、 或 ,或者写入了无害别名( → , / / → , / → )。Provider 名称、文件名或 operation 名称不属于资产类型。不要根据单类型契约推断资产类型。为了直接进入生成阶段而推断类型即视为生成失败。
agentmcprest-apiagentsagentapiREST APIsAPIsrest-apiMCPMCP serversmcpStep 2: Collect inventory
步骤 2:收集清单
Once the type is known, the whole next message is:
"Please provide the API specification or documentation for the provider APIs that list and fetch these assets. OpenAPI or Swagger, a Postman or Insomnia collection, RAML, an API Blueprint, a GraphQL schema, an SDK reference, or a redacted request and response are examples, not required formats."
Then stop. Do not ask which provider. Infer the provider from a usable spec. Do not invent calls. Do not fetch a spec they did not provide. The catalog later in this file is a shape reminder for a matching paste, not a substitute.
Read what they attached. Then stop if it is not yet usable. Ask only the missing piece. One question per response.
- Unreadable, empty, unrelated, or not a spec or redacted request and response. Whole message: "This attachment is not a usable specification for listing and fetching these assets. Please attach or paste a valid API spec or a redacted request and response that includes those APIs."
- No list API for the type they named. Whole message: "This specification does not include an API that lists {agent|mcp|rest-api} assets. Please attach or paste that list API."
- Agent list with no fetch or card API. Whole message: "This specification lists assets but does not include the fetch or card API needed to build the agent zip. Please attach or paste that call."
- MCP list with no /
initialize(or the equivalent handshake). Whole message: "This specification does not include initialize and tools/list (or the equivalent handshake) needed to build an MCP card. Please attach or paste those calls."tools/list - REST list with no export or OpenAPI download. Whole message: "This specification does not include the export or OpenAPI download needed to build a REST zip. Please attach or paste that call."
A usable inventory has the list call plus the fetch, card, handshake, or export that type needs. Only then ask authentication. Vertex MCP, Gemini MCP, Gemini agents, Azure AI Foundry MCP, and Microsoft 365 Copilot with no customer list docs are enum-only: ask for a customer list call, or stop. If they ask which file to use, they only have this skill and the files they attach; do not name a path from this package.
类型明确后,下一条消息必须完整写为:
"Please provide the API specification or documentation for the provider APIs that list and fetch these assets. OpenAPI or Swagger, a Postman or Insomnia collection, RAML, an API Blueprint, a GraphQL schema, an SDK reference, or a redacted request and response are examples, not required formats."然后停止。不要询问 provider 名称。要从可用规范中推断 provider。不要自行创造调用。不要获取用户未提供的规范。本文件中后续的 catalog 只是用于匹配粘贴内容的结构提示,不能替代用户提供的规范。
阅读用户附加的内容。如果尚不可用,则停止并只询问缺失部分。每次响应只问一个问题。
- 内容无法读取、为空、不相关,或者既不是规范也不是已脱敏的请求与响应。整条消息必须为:
"This attachment is not a usable specification for listing and fetching these assets. Please attach or paste a valid API spec or a redacted request and response that includes those APIs." - 用户指定类型的清单中没有 list API。整条消息必须为:
"This specification does not include an API that lists {agent|mcp|rest-api} assets. Please attach or paste that list API." - Agent 清单中没有 fetch 或 card API。整条消息必须为:
"This specification lists assets but does not include the fetch or card API needed to build the agent zip. Please attach or paste that call." - MCP 清单中没有 /
initialize或等效握手。整条消息必须为:tools/list"This specification does not include initialize and tools/list (or the equivalent handshake) needed to build an MCP card. Please attach or paste those calls." - REST 清单中没有 export 或 OpenAPI download。整条消息必须为:
"This specification does not include the export or OpenAPI download needed to build a REST zip. Please attach or paste that call."
可用清单必须包含 list 调用,以及该资产类型所需的 fetch、card、握手或 export。只有满足这些条件后,才能询问认证方式。Vertex MCP、Gemini MCP、Gemini agents、Azure AI Foundry MCP 和 Microsoft 365 Copilot 如果没有客户自己的 list 文档,则属于仅枚举支持:要求客户提供 list 调用,或者停止。如果用户询问应使用哪个文件,说明其只有当前 Skill 和自己附加的文件;不要指出本软件包中的路径。
Step 3: Collect authentication
步骤 3:收集认证信息
Once the inventory is usable, the whole next message is:
"Please provide the authentication documentation needed to call those APIs. Include the token or signing request, the response, which field is a secret, and how a call is proven to be the right account. Do not paste secret values."
Then stop. A long-lived secret, a session token, and a private key are never typed into this chat. They belong in the inputs file or in the environment when the script runs.
If that document is missing a piece, ask only that piece. Whole message, fill one gap: "The authentication documentation is missing {the token or signing request|the response|which field is a secret|how a call is proven to be the right account}. Please add that piece. Do not paste secret values." Do not proceed to language until those four are present.
Use the authentication document they pasted. Do not open a catalog file from this skill. When they describe Salesforce connected-org (C2C) login or a MuleSoft-managed authorization-code flow, that is not customer-executable: ask for a request and response they can run from their machine. Until they provide one, do not write files. A pasted SigV4 access-key flow still uses the request and response they pasted. Do not copy pull-scanner-only fields such as Hub Role ARN, Spoke Role Name, External ID, Account IDs, or Target Regions into the script.
清单可用后,下一条消息必须完整写为:
"Please provide the authentication documentation needed to call those APIs. Include the token or signing request, the response, which field is a secret, and how a call is proven to be the right account. Do not paste secret values."然后停止。长期有效的 secret、session token 和 private key 绝不能输入到对话中。它们应放在输入文件里,或者在脚本运行时通过环境变量提供。
如果认证文档缺少某一部分,只询问该部分。整条消息必须为: 在这四项全部具备前,不要进入语言选择步骤。
"The authentication documentation is missing {the token or signing request|the response|which field is a secret|how a call is proven to be the right account}. Please add that piece. Do not paste secret values."使用用户粘贴的认证文档。不要打开此 Skill 中的 catalog 文件。当用户描述 Salesforce connected-org(C2C)登录或 MuleSoft 托管的 authorization-code 流程时,这种方式无法由客户直接执行:要求客户提供可从其机器运行的请求和响应。在用户提供之前,不要编写文件。粘贴的 SigV4 access-key 流程仍需使用用户提供的请求和响应。不要把 Hub Role ARN、Spoke Role Name、External ID、Account IDs 或 Target Regions 等仅供 pull scanner 使用的字段复制到脚本中。
Step 4: Ask script language
步骤 4:询问脚本语言
Once auth is known, the whole next message is:
"Which script language should I use? Project conventions are optional. Any language you can run is acceptable. Named languages are examples, not a fixed list."
Then stop. Do not default to a language. Writing a file before they answer is a failure. If they name a language and omit conventions, write a plain script in that language.
Default script stderr the customer sees: the numbered step banner only when that step runs; after a successful list ; then one line per matching asset (, external id, display name); when M is 0; FAILED for real failures. Do not print skip ids, , or unless .
listed N, matching M, skipped KtypeNo matching {ASSET_TYPE} assets found.skipping MCPnot MCP--verbose认证方式明确后,下一条消息必须完整写为:
"Which script language should I use? Project conventions are optional. Any language you can run is acceptable. Named languages are examples, not a fixed list."然后停止。不要默认使用某种语言。在用户回答前写文件即视为失败。如果用户指定语言但没有说明项目约定,则使用该语言编写普通脚本。
客户看到的默认 stderr:仅在对应步骤实际执行时打印编号步骤横幅;成功 list 后打印 ;随后每个匹配资产打印一行(、external id、display name);当 M 为 0 时打印 ;真实失败时打印 FAILED。除非使用 ,不要打印被跳过的 id、 或 。
listed N, matching M, skipped KtypeNo matching {ASSET_TYPE} assets found.--verboseskipping MCPnot MCPStep 5: Show the mapping
步骤 5:展示映射
[GATE] WAIT for an explicit yes to "Does this look fine?" before writing files.
When type, inventory, auth, and language are known, do not write files in that turn. Show the mapping in this order, then stop. Do not treat dumping the script as having shown the mapping.
- What was collected, in plain English: the list and detail calls, the auth field names (not values), the language, and the one asset type.
- One row per inventory call. Columns: Call, Request, Response field, Zip path.
- One row per field the zip will contain. Columns: Source, Sent as, Required. Source is the operation and response path, or . If a required Source cannot be pointed at, leave the row blank and ask only for that API or field. Do not guess. If any required Source is blank, stop here. Do not show items 4–8 and do not ask "Does this look fine?" until every required Source is filled.
constant - One Representative generated JSON object for a single asset, using values from their inventory when they gave an example, otherwise empty strings. For , every required A2A v0.3 field has a row (
agent,name,description,protocolVersion,url,version,capabilities,defaultInputModes,defaultOutputModes). A v1 card usesskillsorsupportedInterfacesand has no top-levelsupported_interfaces. The artifact isurlora2a-card.json. Fora2a-v1-card.json,mcpwithspecification/mcp-metadata.jsonrequired; if capabilities are included, include all four booleanstransport,tools,resources, andprompts; do not addlogging. ForserverInfo,rest-apiwithspecification/oas.jsonandinfo;pathsis the provider id, and one stage is one asset.externalId - How the zip is uploaded after they run the script: is the zip as multipart part
POST {ANYPOINT_BASE}/agent-scanner/api/v1/organizations/{org}/scanner-configurations/{config}/push, filenamefile. Not JSON. Finish is a separate{externalId}.zip. The customer question is "Commit this scan? [y/N]". Do not namePOST .../commit,/push-assets, or/complete./seal - Script architecture: the function names to write (provider login, list, shape zip, token, upload, optional commit, print status) and the numbered stderr steps below.
- Flags, environment variables, prompts, and which of those are secret. Same names as The script. three columns: Prompt label, Parameter flag, Input file key.
--help - Ask exactly: "Does this look fine?"
Do not show Prerequisites or Ways to run the script in this turn. Those come after the files exist. Showing them before they say yes is a generation failure.
If they say no, ask which row is wrong, fix the table, and ask again. Still do not write files. If they say yes, write the two files. After the files exist, show Prerequisites, then Ways to run the script in this order: interactive, parameters, input file, and the full as a fenced block named so they can download it. Do not ask "Does this look fine?" after writing.
inputs.envinputs.envThat yes is the only approval. The script is not written until they say yes, so a run does not ask them to approve the mapping again and does not refuse live because a fingerprint is pending. Record the approved rows as : canonical JSON, UTF-8, keys sorted, , rows in the order shown, SHA-256 hex. That value is a record of the chat yes. It is not a second question.
MAPPING_FINGERPRINT{"assetType":"...","rows":[{"source":"...","sentAs":"...","required":true}]}Classify with the check described in their inventory. Do not classify by display name. A list that returns more than one kind of asset still yields only the type they named. The other kinds are skipped. A shared AgentCore is not permission to zip both agents and MCP. Agent script: skip , then or the documented synthesized card. MCP script: SigV4 JSON-RPC , then ; null = skip. Name is never classification. REST script lists API Gateway (or their REST inventory), not AgentCore runtimes. A skip is a count, not a default log line: increment and continue. Do not print , , or on stderr unless is set. may print . FAILED still prints (list/page errors, HTTP 401/403, missing required zip fields, upload refusals).
ListAgentRuntimesprotocolConfiguration.serverProtocol=MCPGetAgentCardinitializetools/listinitializeskippedskipped {id}skipping MCPnot MCP--verbose--verboseskipped {id} <reason>AgentCore MCP handshake URL is not the Exchange card field (). The invoke URL is . comes from / the list item. Encode it with (every , , and extra character). is , usually . No endpoint name means skip that runtime. is . Parse JSON or SSE lines. params are , , . HTTP 401/403 on initialize is FAILED. HTTP 400/404/405/415/422 or a missing object is skip. A generated script that POSTs , uses the unencoded runtime id in the path, or omits is a generation failure. A default run that prints for every non-matching runtime is a generation failure.
transport.path/mcphttps://bedrock-agentcore.{region}.amazonaws.com/runtimes/{urlencoded agentRuntimeArn}/invocations?qualifier={endpointName}agentRuntimeArnget-agent-runtimeurllib.parse.quote(arn, safe=""):/endpointNamelist-agent-runtime-endpointsruntimeEndpoints[0].nameDEFAULTAcceptapplication/json, text/event-streamdata:initializeprotocolVersion2025-03-26capabilities{}clientInforesult/runtimes/{agentRuntimeId}/invocations/mcp?qualifier=skipped {id}[GATE] 在写入文件前,必须等待用户明确回答 "Does this look fine?"。
当类型、清单、认证方式和语言均已明确时,不要在当前轮次写文件。按以下顺序展示映射,然后停止。不要把输出脚本本身视为已经展示映射。
- 用通俗语言说明收集到的信息:list 和 detail 调用、认证字段名称(不显示值)、语言,以及唯一的资产类型。
- 每个清单调用一行。列:Call、Request、Response field、Zip path。
- ZIP 将包含的每个字段一行。列:Source、Sent as、Required。Source 是 operation 和 response path,或 。如果某个必填 Source 无法定位,则该行留空,并且只询问对应的 API 或字段。不要猜测。如果任何必填 Source 为空,在这里停止;不要展示第 4–8 项,也不要在所有必填 Source 填写完毕前询问
constant。"Does this look fine?" - 展示单个资产的代表性 JSON 对象。用户提供示例时使用其清单中的值,否则使用空字符串。对于 ,每个必填 A2A v0.3 字段都要有一行(
agent、name、description、protocolVersion、url、version、capabilities、defaultInputModes、defaultOutputModes)。v1 card 使用skills或supportedInterfaces,且没有顶层supported_interfaces。产物为url或a2a-card.json。对于a2a-v1-card.json,产物为mcp,其中specification/mcp-metadata.json必填;如果包含 capabilities,则必须包含全部四个 boolean:transport、tools、resources、prompts;不要添加logging。对于serverInfo,产物为rest-api,其中包含specification/oas.json和info;paths是 provider id,一个 stage 对应一个资产。externalId - 说明用户运行脚本后如何上传 ZIP:,请求体为 multipart part
POST {ANYPOINT_BASE}/agent-scanner/api/v1/organizations/{org}/scanner-configurations/{config}/push,文件名为file。不是 JSON。结束操作是单独的{externalId}.zip。面向客户的问题必须是POST .../commit。不要使用"Commit this scan? [y/N]"、/push-assets或/complete。/seal - 说明脚本架构:需要编写的函数名称(provider login、list、shape zip、token、upload、可选 commit、print status),以及下方编号 stderr 步骤。
- 说明 flags、环境变量、prompts,以及其中哪些是 secret。名称必须与脚本部分一致。使用三列:Prompt label、Parameter flag、Input file key。
--help - 逐字询问:
"Does this look fine?"
本轮不要展示 Prerequisites 或 Ways to run the script;这些内容应在文件创建后展示。如果用户回答 no,询问哪一行有误,修正表格后再次询问,仍然不要写文件。如果用户回答 yes,则写入两个文件。文件存在后,先展示 Prerequisites,再按以下顺序展示 Ways to run the script:interactive、parameters、input file,以及完整的 fenced block,代码块名称为 ,以便用户下载。写完文件后不要再询问 。
inputs.envinputs.env"Does this look fine?"该 yes 是唯一批准信号。脚本在用户回答 yes 前不得编写,因此运行时不应再次要求批准映射,也不能因为 fingerprint 尚未生成而拒绝实时运行。将用户批准的各行记录为 :canonical JSON、UTF-8、键排序、,各行保持展示时的顺序,使用 SHA-256 hex。该值只是对话中 yes 的记录,不是第二个问题。
MAPPING_FINGERPRINT{"assetType":"...","rows":[{"source":"...","sentAs":"...","required":true}]}按照清单中描述的检查方式进行分类。不要按 display name 分类。一个 list 返回多种资产时,仍只产出用户指定的类型,其他类型应跳过。共享的 AgentCore 不表示可以同时打包 agent 和 MCP。Agent 脚本:跳过 ,然后调用 或文档规定的合成 card。MCP 脚本:执行 SigV4 JSON-RPC ,然后执行 ; 返回 null 时跳过。名称绝不能作为分类依据。REST 脚本列出 API Gateway(或用户的 REST 清单),而不是 AgentCore runtimes。跳过只应计入数量,不能作为默认日志行:增加 后继续。除非设置了 ,不要在 stderr 打印 、 或 。 可以打印 。FAILED 仍须打印,包括 list/page 错误、HTTP 401/403、缺少必填 ZIP 字段以及上传被拒绝。
ListAgentRuntimesprotocolConfiguration.serverProtocol=MCPGetAgentCardinitializetools/listinitializeskipped--verboseskipped {id}skipping MCPnot MCP--verboseskipped {id} <reason>AgentCore MCP 握手 URL 不是 Exchange card 字段 ()。调用 URL 是 。 来自 或 list item。使用 对其编码,包括每一个 、 和其他额外字符。 来自 的 ,通常为 。没有 endpoint name 时跳过该 runtime。 为 。解析 JSON 或 SSE 行。 的 params 包含 、 和 。initialize 返回 HTTP 401/403 时为 FAILED。HTTP 400/404/405/415/422 或缺少 对象时跳过。生成 POST 到 、在路径中使用未编码 runtime id,或省略 的脚本均视为生成失败。默认运行中为每个不匹配的 runtime 打印 的脚本也视为生成失败。
transport.path/mcphttps://bedrock-agentcore.{region}.amazonaws.com/runtimes/{urlencoded agentRuntimeArn}/invocations?qualifier={endpointName}agentRuntimeArnget-agent-runtimeurllib.parse.quote(arn, safe=""):/endpointNamelist-agent-runtime-endpointsruntimeEndpoints[0].nameDEFAULTAcceptapplication/json, text/event-streamdata:initializeprotocolVersion2025-03-26capabilities{}clientInforesult/runtimes/{agentRuntimeId}/invocations/mcp?qualifier=skipped {id}Step 6: Write the two files
步骤 6:编写两个文件
Two files, in the language they named. No markdown guide. The chat already showed the mapping. Prerequisites and Ways to run come after these files exist.
- The script. One run lists the assets, checks each matching object, uploads each matching one, and then either commits the scan or stops. Zero matching assets stop after list/shape: no MuleSoft login. The asset type is a source constant (). The script does not accept
ASSET_TYPE,--asset-type, or an environment variable that switches type.SCANNER_ASSET_TYPE - An inputs file, , written to disk beside the script and shown again as a fenced block named
inputs.envso the customer can download it. The block contains the whole file. A chat that only prints the commandinputs.envis a generation failure. Every secret value is empty. Non-secret placeholders are obvious fakes, never a real id from this chat. Mark each line--input-file inputs.envor(required)in a comment.(optional)
Do not write a pipeline, a container, a schedule, or a second library.
inputs.envundefined使用用户指定的语言编写两个文件。不要提供 Markdown 指南。映射已经在对话中展示;Prerequisites 和 Ways to run 应在文件存在后展示。
- 脚本。一次运行应列出资产、检查每个匹配对象、上传每个匹配资产,然后提交扫描或停止。零匹配资产时,在 list/shape 后停止:不进行 MuleSoft 登录。资产类型是源常量 。脚本不接受
ASSET_TYPE、--asset-type,也没有用于切换类型的环境变量。SCANNER_ASSET_TYPE - 输入文件 ,写在脚本旁边,并再次以名为
inputs.env的 fenced block 展示完整内容,以便用户下载。代码块包含整个文件。所有 secret 值均为空。非 secret 占位值必须是明显伪造的值,绝不能使用对话中的真实 id。每一行都要在注释中标明inputs.env或(required)。(optional)
不要编写 pipeline、container、schedule 或第二个 library。
inputs.envundefined(required) Anypoint host. Example: https://anypoint.mulesoft.com
(required) Anypoint host. Example: https://anypoint.mulesoft.com
ANYPOINT_BASE=
ANYPOINT_BASE=
(required) Organization id, copied from the scanner page
(required) Organization id, copied from the scanner page
ANYPOINT_ORG_ID=
ANYPOINT_ORG_ID=
(required) Scanner configuration id, copied from the scanner page
(required) Scanner configuration id, copied from the scanner page
SCANNER_CONFIGURATION_ID=
SCANNER_CONFIGURATION_ID=
(required) Connected App client id
(required) Connected App client id
ANYPOINT_CLIENT_ID=
ANYPOINT_CLIENT_ID=
(required) Connected App client secret. Leave empty in chat. Fill this on the machine that runs the script.
(required) Connected App client secret. Leave empty in chat. Fill this on the machine that runs the script.
ANYPOINT_CLIENT_SECRET=
ANYPOINT_CLIENT_SECRET=
(optional) Commit the scan without a prompt. yes or no. Default no.
(optional) Commit the scan without a prompt. yes or no. Default no.
PUSH_COMMIT=
Append one line per provider credential the script will actually ask for, with `(required)` or `(optional)`. Do not copy a credential set from a different provider. A session token, a private key, or any other long secret is `(required)` only when their auth document says the call fails without it.
When that document offers more than one credential source, ask which one before the mapping. The script uses only that source. It does not fall back to another. An attached role or a named profile is allowed when they select it. Do not demand an access key for that choice. An unattended run names the source in the inputs file. It does not guess from leftover environment variables. For AWS that line is `AWS_AUTH_MODE` with one of `profile`, `default-chain`, or `access-keys`.
The rest of this file is the script contract. Read **The script**, **One input mode**, **ZIP and push**, and `references/scanner-contract.md` before writing. Read `references/generated-script-standard.md` for stderr, JSON stdout, and the mapping fingerprint. Read `references/provider-auth-resolution.md` for managed-only auth.PUSH_COMMIT=
为脚本实际会请求的每一个 provider credential 追加一行,并标注 `(required)` 或 `(optional)`。不要从其他 provider 复制 credential 集合。只有在认证文档说明缺少该凭据会导致调用失败时,session token、private key 或其他长期 secret 才是 `(required)`。
当认证文档提供多个 credential source 时,在展示映射前询问用户选择哪一个。脚本只能使用选定的 source,不能回退到另一个。允许使用用户选择的 role 或命名 profile。不要强制该选择必须使用 access key。无人值守运行时,应在输入文件中明确写出 source,不能从遗留环境变量中猜测。对于 AWS,该行是 `AWS_AUTH_MODE`,值为 `profile`、`default-chain` 或 `access-keys` 之一。
本文件的其余部分是脚本契约。编写前必须阅读 **The script**、**One input mode**、**ZIP and push** 和 `references/scanner-contract.md`。阅读 `references/generated-script-standard.md`,以了解 stderr、JSON stdout 和 mapping fingerprint。阅读 `references/provider-auth-resolution.md`,以了解仅托管端可执行的认证方式。Step 7: Verify generation and show how to run
步骤 7:验证生成结果并展示运行方式
After the two files exist, show Prerequisites, then Ways to run the script in this order: interactive, parameters, input file, and the full as a fenced block named so they can download it. Do not ask "Does this look fine?" after writing.
inputs.envinputs.envRun the language checker in Same job, any language on the generated file. Search for forbidden patterns ( or on , , , , ). If the checker cannot run here, search the file for those patterns. Do not declare completion until the file parses in the named language and those searches are clean.
json="Content-Type": "application/json"/pushPOST .../sealPOST .../complete--client-secretargs.[a-z]+-两个文件创建后,先展示 Prerequisites,再按以下顺序展示 Ways to run the script:interactive、parameters、input file,以及完整的 fenced block,名称为 ,以便下载。写完文件后不要再询问 。
inputs.envinputs.env"Does this look fine?"在生成的文件上运行 Same job, any language 中的语言检查器。搜索禁止模式( 上使用 或 、、、、)。如果当前环境无法运行检查器,则在文件中搜索这些模式。在文件能够按指定语言解析且搜索结果干净之前,不要声明完成。
/pushjson="Content-Type": "application/json"POST .../sealPOST .../complete--client-secretargs.[a-z]+-Connected App
Connected App
The script logs in to Anypoint with one Connected App: client id and client secret, grant . It never asks for an Anypoint username or password.
client_credentialsAn Organization Administrator creates the app once, in Access Management, before they run the script. The script cannot create it.
- Access Management → Connected Apps → Create App.
- Type: App acts on its own behalf (client credentials).
- Add scope and apply it to this organization. A token without that scope is rejected.
manage:exchange - Save. Copy the client id. Store the client secret as . Do not paste it into this chat.
ANYPOINT_CLIENT_SECRET
The self-managed types are offered only when is on and the entitlement matches: for agents, for MCP and REST. If upload returns that the type is absent, stop and say so. Do not invent an id.
push-scanner-enabledagentapiScannersToken request, in every language: with and body . Never JSON.
POST {ANYPOINT_BASE}/accounts/api/v2/oauth2/tokenContent-Type: application/x-www-form-urlencodedgrant_type=client_credentials&client_id=...&client_secret=...脚本使用一个 Connected App 登录 Anypoint:client id、client secret,以及 grant。绝不要求用户提供 Anypoint username 或 password。
client_credentialsOrganization Administrator 在运行脚本前,需要先在 Access Management 中创建一次该 App。脚本无法自行创建。
- Access Management → Connected Apps → Create App。
- Type:App acts on its own behalf (client credentials)。
- 添加 scope 并应用到该组织。缺少此 scope 的 token 会被拒绝。
manage:exchange - 保存。复制 client id。将 client secret 存为 。不要粘贴到对话中。
ANYPOINT_CLIENT_SECRET
仅当 已开启且 entitlement 匹配时,才提供自托管类型:agent 对应 agents, 对应 MCP 和 REST。如果上传返回该类型不可用,停止并说明情况。不要编造 id。
push-scanner-enabledapiScanners每种语言中的 token 请求均为:,使用 ,请求体为 。绝不能使用 JSON。
POST {ANYPOINT_BASE}/accounts/api/v2/oauth2/tokenContent-Type: application/x-www-form-urlencodedgrant_type=client_credentials&client_id=...&client_secret=...What the script does
脚本执行过程
Inside that one run the script prints a numbered step banner on stderr only when that step runs, then stops. Do not split them across programs. Do not print a later banner after the run has stopped.
── Step 1: provider login
── Step 2: list assets
── Step 3: shape zips
── Step 4: MuleSoft login
── Step 5: publish
── Step 6: commit--dry-runAfter step 3, if zero assets matched :
ASSET_TYPE- Print on stderr (
No matching {ASSET_TYPE} assets found.,agent, ormcp).rest-api - Print the JSON object on stdout (true, that type's count
ok,0for classified-away and handshake skips, empty publish ids).skipped - Exit 0.
- Do not print Step 4, 5, or 6. Do not prompt for the Connected App secret. Do not call or
/push./commit - uses this same stop.
--dry-run - Live exception only: continues to
PUSH_ALLOW_EMPTY=yesand the empty-commit path in step 5.GET .../workspace
- Read inputs. See One input mode.
- Call their list and detail APIs with their auth. Follow pages until the list ends or a page cap is hit. If the list call itself fails, exit 2 and do not commit. After a successful list, print one summary line: . Do not print one line per skipped id unless
listed N, matching M, skipped K.--verbose - For each matching asset, build the object from the mapping they accepted. If a required field is missing, print FAILED and do not upload that object. An invalid object is the script's fault. Print each matching asset on its own line: type, external id, display name. Print the zip path plus the artifact. A zip that uses
{id}/specification/config.json(no{id}/config.json) is a generation failure.specification/ - Upload each valid ZIP with . The body is the zip bytes, not JSON.
POST {ANYPOINT_BASE}/agent-scanner/api/v1/organizations/{org}/scanner-configurations/{config}/pushisContent-Typewith exactly one part namedmultipart/form-data, filenamefile, part{externalId}.zip. HTTP 202 JSON isContent-Type: application/zip. Keep that{assetId, action, workspaceRunId}. Every later upload in this run must return the same id. The server checks the zip again. A refusal is FAILED, with the response body. The same provider id replaces the staged object. It does not create a second row, and Exchange is not called. An id uploaded earlier and absent from this list stays staged untilworkspaceRunId. Omission is not deletion. HTTP 415 means this POST was not a zip part namedDELETE .../push/{externalId}(JSON body,file,application/x-www-form-urlencodedwith no boundary, or a boundary that starts withContent-Type: multipart/form-data). A generated script that posts JSON to=, uses/push, setsjson=onContent-Type: application/json, or names the part anything other than/pushis a generation failure.file - Close the workspace and declare completeness separately. comes only from a 202
workspaceRunId(or/pushwhenGET .../workspaceand nothing was uploaded). InventingPUSH_ALLOW_EMPTY=yesor postingrun-…without that id is a generation failure. Zero accepted uploads: do not call/commit./commit- The list stopped at a page cap, or any upload failed, and at least one upload was accepted: with
POST .../commit. Do not ask.{"workspaceRunId":"<id from 202>","complete":false}is upsert only. It must not becomplete:false.true - The list finished and every upload succeeded: ask on a TTY, "Commit this scan? [y/N]". The default is no. or
--commitis the yes when there is no TTY. Yes sendsPUSH_COMMIT=yeswithPOST .../commit. No uploads and does not commit."complete":true - An empty successful list does not commit unless they also set .
PUSH_ALLOW_EMPTY=yes
- The list stopped at a page cap, or any upload failed, and at least one upload was accepted:
- Print one JSON object on stdout: counts, ,
truncated,workspaceRunId, and whether the scan was committed. Exit 0 when nothing failed. Exit 2 when a list, an upload, or a requested commit failed.scanRunId
complete: truecomplete: falseThe upload is one ZIP per asset because that is the API. The customer confirms the mapping and the sample JSON. Do not spend the chat on archive layout. The script still produces a valid ZIP: one directory whose name is the provider's stable id, with and , and the artifact next to it ( or , , or ).
specification/config.jsonnametypea2a-card.jsona2a-v1-card.jsonmcp-metadata.jsonoas.jsonLive stderr after MuleSoft values resolve (non-secrets in full; secret presence only):
Anypoint host: https://anypoint.mulesoft.com
Anypoint Organization ID: …
Scanner Configuration ID: …
Connected App Client ID: …
Connected App Client Secret: setAsk only the missing ones. must not prompt for those Anypoint rows.
--dry-run在一次运行中,脚本仅在步骤实际执行时向 stderr 打印编号步骤横幅,然后停止。不要把步骤拆成多个程序。运行停止后,不要打印后续步骤的横幅。
── Step 1: provider login
── Step 2: list assets
── Step 3: shape zips
── Step 4: MuleSoft login
── Step 5: publish
── Step 6: commit--dry-run步骤 3 后,如果匹配 的资产数为零:
ASSET_TYPE- 在 stderr 打印 (
No matching {ASSET_TYPE} assets found.、agent或mcp)。rest-api - 在 stdout 打印 JSON 对象(为 true,该类型计数为
ok,0包含分类排除和握手跳过项,publish ids 为空)。skipped - 退出码为 0。
- 不打印步骤 4、5、6。不提示 Connected App secret。不调用 或
/push。/commit - 使用相同的停止逻辑。
--dry-run - 唯一的实时例外是:时继续执行
PUSH_ALLOW_EMPTY=yes,并进入步骤 5 的空提交路径。GET .../workspace
- 读取输入。参见 One input mode。
- 使用认证方式调用客户的 list 和 detail API。持续翻页,直到 list 结束或达到 page cap。如果 list 调用本身失败,退出码为 2,并且不要提交。成功 list 后,打印一行摘要:。除非使用
listed N, matching M, skipped K,不要为每个被跳过的 id 打印一行。--verbose - 对每个匹配资产,使用客户批准的 mapping 构建对象。如果缺少必填字段,打印 FAILED,并且不上传该对象。无效对象属于脚本错误。每个匹配资产单独打印一行:type、external id、display name。打印 ZIP 路径 以及产物。使用
{id}/specification/config.json(没有{id}/config.json)的 ZIP 属于生成失败。specification/ - 使用 上传每个有效 ZIP。请求体是 ZIP 字节,不是 JSON。
POST {ANYPOINT_BASE}/agent-scanner/api/v1/organizations/{org}/scanner-configurations/{config}/push为Content-Type,且只能有一个名为multipart/form-data的 part,文件名为file,part 的{externalId}.zip为Content-Type。HTTP 202 JSON 为application/zip。保留该{assetId, action, workspaceRunId}。本次运行中的每次后续上传都必须返回同一个 id。服务器会再次检查 ZIP。上传被拒绝时打印 FAILED,并附上响应体。相同 provider id 会替换暂存对象,不会创建第二行,也不会调用 Exchange。本次 list 中未包含的早期上传 id 会保持暂存,直到调用workspaceRunId。遗漏并不表示删除。HTTP 415 表示该 POST 没有收到名为DELETE .../push/{externalId}的 ZIP part,例如使用了 JSON body、file、application/x-www-form-urlencoded但没有 boundary,或者 boundary 以Content-Type: multipart/form-data开头。生成向=POST JSON、使用/push、在json=上设置/push,或使用Content-Type: application/json以外 part 名称的脚本均视为生成失败。file - 分别关闭 workspace 并声明完整性。只能来自 HTTP 202 的
workspaceRunId响应;当/push且没有上传任何内容时,可以来自PUSH_ALLOW_EMPTY=yes。编造GET .../workspace,或在缺少该 id 的情况下 POSTrun-…,均视为生成失败。没有成功接受任何上传时,不要调用/commit。/commit- list 在 page cap 处停止,或任一上传失败,但至少有一个上传成功被接受:POST ,请求体为
.../commit。不要询问。{"workspaceRunId":"<id from 202>","complete":false}表示只执行 upsert,绝不能为complete:false。true - list 完整结束且所有上传都成功:在 TTY 上询问 。默认值为 no。没有 TTY 时,
"Commit this scan? [y/N]"或--commit表示 yes。Yes 发送 POSTPUSH_COMMIT=yes,其中.../commit。No 不上传,也不提交。"complete":true - 成功得到空 list 时,除非同时设置 ,否则不要提交。
PUSH_ALLOW_EMPTY=yes
- list 在 page cap 处停止,或任一上传失败,但至少有一个上传成功被接受:POST
- 在 stdout 打印一个 JSON 对象:包含计数、、
truncated、workspaceRunId,以及扫描是否已提交。没有失败时退出码为 0。list、上传或用户请求的提交失败时,退出码为 2。scanRunId
complete: truecomplete: falseAPI 要求每个资产上传一个 ZIP。客户需要确认 mapping 和示例 JSON。不要在对话中花费大量时间讨论 archive 布局。脚本仍必须生成有效 ZIP:一个以 provider 稳定 id 命名的目录、(包含 和 ),以及与其同级的产物( 或 、 或 )。
specification/config.jsonnametypea2a-card.jsona2a-v1-card.jsonmcp-metadata.jsonoas.jsonMuleSoft 值解析完成后,实时 stderr 应显示如下内容(非 secret 显示完整值,secret 只显示是否存在):
Anypoint host: https://anypoint.mulesoft.com
Anypoint Organization ID: …
Scanner Configuration ID: …
Connected App Client ID: …
Connected App Client Secret: set只询问缺少的值。 不得提示任何 Anypoint 配置项。
--dry-runOne input mode
One input mode
One run uses one value source. Control flags do not pick a source and do not block prompts. Control flags are , , , and . Provider fields come from the authentication document they pasted, minus pull-scanner-only hub/spoke fields. AWS, Azure, GCP, Databricks, Snowflake, Kong, and a provider that is not in the catalog use that same rule. Do not copy an AWS field onto another provider.
--help--dry-run--verbose--commitInside the chosen source, every field uses this fill order. A variable already in the shell fills the value. It does not switch the source, and a blank prompt must not erase it.
- Command flag already set → use it. Do not prompt.
- Else the environment variable.
- Else the /
--input-filekey, when that source is the input file.PUSH_INPUT_FILE - Else a TTY prompt in this same process. Hide a secret. An empty answer keeps step 2.
- Else, not a TTY → naming the missing input.
FAILED
Three ways to supply values. They are OR.
- Input file. or
--input-fileis set. Every required value, including secrets, is in that file. A missing required key is FAILED.PUSH_INPUT_FILEand--dry-runmay be added. They do not switch the run to parameters mode.--commit - Parameters. A value flag is on the command line, and no input file is set. Value flags are ,
--anypoint-base,--org,--config, then only that provider's flags. AWS adds--client-idand--profile/--region. Azure and GCP do not get--aws-region. Secrets are environment variables, never flags. A missing required value is FAILED. No prompt.--profile - Prompts. No input file and no value flag, and stdin is a TTY. alone is this mode. Ask only for a label that is still empty after the environment. A secret already in the environment is not asked again.
--dry-run
--dry-runNo file, no value flag, and no TTY → FAILED naming the missing input.
一次运行只使用一个 value source。Control flags 不会选择 source,也不会阻止 prompts。Control flags 为 、、 和 。Provider 字段来自用户粘贴的认证文档,并排除仅供 pull scanner 使用的 hub/spoke 字段。AWS、Azure、GCP、Databricks、Snowflake、Kong 以及不在 catalog 中的 provider 均遵循同一规则。不要把 AWS 字段复制到其他 provider。
--help--dry-run--verbose--commit在选定的 source 内,每个字段都按以下顺序填充。Shell 中已存在的变量会提供值,但它不会切换 source;空白 prompt 也不能清除它。
- 命令行 flag 已设置 → 使用该值。不要提示。
- 否则使用环境变量。
- 否则,当 source 为 input file 时,使用 /
--input-file中对应的键。PUSH_INPUT_FILE - 否则,在同一进程中通过 TTY 提示输入。Secret 必须隐藏。空回答保留步骤 2 的值。
- 否则,若不是 TTY → 打印 ,并指明缺少的输入。
FAILED
提供值有三种方式,三者互斥。
- Input file。 设置了 或
--input-file。所有必填值,包括 secret,都放在该文件中。缺少必填键时为 FAILED。可附加PUSH_INPUT_FILE和--dry-run,它们不会让运行切换到 parameters 模式。--commit - Parameters。 命令行中存在 value flag,且未设置 input file。Value flags 依次为 、
--anypoint-base、--org、--config,然后仅追加该 provider 的 flags。AWS 增加--client-id和--profile/--region。Azure 和 GCP 不使用--aws-region。Secret 只能通过环境变量提供,不能作为 flag。缺少必填值时为 FAILED,不进行提示。--profile - Prompts。 没有 input file,也没有 value flag,并且 stdin 是 TTY。单独的 也属于此模式。只询问在检查环境变量后仍为空的 label。环境中已经存在的 secret 不再询问。
--dry-run
--dry-run没有文件、没有 value flag,并且不是 TTY → 打印 FAILED,并指明缺少的输入。
Pull-form provider login
Pull-form provider login
Step 1 looks like the Exchange connection form for that provider, not a cloud-CLI tutorial. Derive prompts from the authentication document they pasted. If a current pull form matches that provider, use that credential class's for the fields the script actually asks. Do not copy an AWS, Azure, or Kong field set onto a different provider. Do not send any of these values to MuleSoft. The push configuration is with no .
@Field(label=...)authScheme=customer-uploadauthParameters| Pull scanner form (UI label) | Script prompt | Secret? |
|---|---|---|
| AWS Access Key ID | | no |
| AWS Secret Access Key | | yes |
| AWS Session Token | hidden, only when the access key is | yes |
| AWS Region | | no |
| Tenant ID / Client ID / Client Secret (Azure) | same labels | secret last |
| Subscription ID (Azure APIM) | same label | no |
| Personal Access Token (Kong) | same label | yes |
| GCP Project ID / Service Account Email / Private Key | same labels | private key yes |
| Workspace URL + client id/secret (Databricks) | same labels | secret yes |
Do not prompt Hub Role ARN, Spoke Role Name, External ID, Account IDs, or Target Regions. Those names exist on the pull scanner form. This script does not assume a role. A row labeled Hub Role ARN, Spoke Role Name, External ID, Account IDs, or Target Regions is a generation failure.
--help步骤 1 应类似于该 provider 的 Exchange connection form,而不是云 CLI 教程。根据用户粘贴的认证文档推导 prompts。如果当前 pull form 与该 provider 匹配,应对脚本实际询问的字段使用该 credential class 的 。不要把 AWS、Azure 或 Kong 的字段集合复制给其他 provider。不要将这些值发送给 MuleSoft。Push 配置为 ,且没有 。
@Field(label=...)authScheme=customer-uploadauthParameters| Pull scanner form(UI label) | Script prompt | Secret? |
|---|---|---|
| AWS Access Key ID | | 否 |
| AWS Secret Access Key | | 是 |
| AWS Session Token | 隐藏;仅当去除引号后的 access key 以 | 是 |
| AWS Region | | 否 |
| Tenant ID / Client ID / Client Secret (Azure) | 相同 label | 最后一项为 secret |
| Subscription ID (Azure APIM) | 相同 label | 否 |
| Personal Access Token (Kong) | 相同 label | 是 |
| GCP Project ID / Service Account Email / Private Key | 相同 label | private key 为 secret |
| Workspace URL + client id/secret (Databricks) | 相同 label | secret 为是 |
不要提示 Hub Role ARN、Spoke Role Name、External ID、Account IDs 或 Target Regions。这些名称存在于 pull scanner form 中,但本脚本不假定 role。带有这些名称的 行属于生成失败。
--helpAlready logged in
已登录状态
The laptop CLI/SDK session is the default. Access keys, client secrets, and private keys are the other branch.
- AWS. /
~/.aws/configalready work.~/.aws/credentialsmust have the row--help.AWS Profile | --profile | AWS_PROFILEuses that profile and does not ask for Access Key, Secret, or Session Token.--profile NAME/--profilewins over leftoverAWS_PROFILE/AWS_ACCESS_KEY_IDin the environment. Do not tell them toAWS_SECRET_ACCESS_KEY. On a TTY, AWS Access Key ID first. Blank, andexport AWS_PROFILE/--profilealready set: do not ask Secret. Blank, and no profile yet: prompt AWS Profile (empty = default chain already on this machine), then AWS Region only. Non-TTY:AWS_PROFILE,--profile, or access keys. Blank Access Key with none of those is FAILED; do not silently call STS on leftover environment credentials or a default chain they did not choose. An AWSAWS_AUTH_MODE=default-chainthat lists Access Key and Region but never--help/--profileis a generation failure.AWS_PROFILE - Azure. is already logged in. Use that session (DefaultAzureCredential /
az). Do not addaz account. Do not prompt Tenant ID, Client ID, or Client Secret unless they pasted those as the auth document they will actually use.--profile - GCP. is already logged in (ADC). Use that session. Do not add
gcloud. Do not prompt Service Account Email or Private Key unless they pasted the service-account JSON as the auth they will actually use.--profile - Kong, Databricks, Snowflake, Claude, LangSmith. No analog of . Use that provider's token fields. Do not invent
aws/config.--profile
--profile--help--profile默认使用笔记本上的 CLI/SDK session。Access keys、client secrets 和 private keys 属于另一种认证分支。
- AWS。 /
~/.aws/config已经可用。~/.aws/credentials必须包含--help这一行。使用AWS Profile | --profile | AWS_PROFILE时采用该 profile,不询问 Access Key、Secret 或 Session Token。--profile NAME/--profile的优先级高于环境中遗留的AWS_PROFILE/AWS_ACCESS_KEY_ID。不要要求用户执行AWS_SECRET_ACCESS_KEY。在 TTY 上,首先询问 AWS Access Key ID。输入为空且已设置export AWS_PROFILE/--profile时,不要询问 Secret。输入为空且尚无 profile 时,提示 AWS Profile(留空表示使用本机已有的 default chain),然后仅提示 AWS Region。非 TTY:必须使用AWS_PROFILE、--profile或 access keys。Access Key 为空且以上选项均未设置时为 FAILED;不能静默使用遗留的环境凭据或用户未选择的 default chain 调用 STS。AWS 的AWS_AUTH_MODE=default-chain如果列出 Access Key 和 Region,却从未列出--help/--profile,则属于生成失败。AWS_PROFILE - Azure。 已经登录。使用该 session(DefaultAzureCredential /
az)。不要添加az account。除非用户粘贴了实际使用的认证文档,否则不要提示 Tenant ID、Client ID 或 Client Secret。--profile - GCP。 已经登录(ADC)。使用该 session。不要添加
gcloud。除非用户粘贴了 service-account JSON 作为实际使用的认证方式,否则不要提示 Service Account Email 或 Private Key。--profile - Kong、Databricks、Snowflake、Claude、LangSmith。 没有类似 的机制。使用对应 provider 的 token 字段。不要自行创建
aws/config。--profile
--profile--help--profileAWS login
AWS 登录
AWS asks for one login, then the region. Nothing else. Order on a TTY: AWS Access Key ID, then either the already-logged-in profile path above, or AWS Secret Access Key (hidden) when the key is non-empty, then AWS Session Token (hidden) only when the unquoted key starts with and the token is not already set, then AWS Region. Skipping Access Key ID and jumping to Secret is a generation failure.
ASIA- Access keys: and
AWS_ACCESS_KEY_IDfrom the flag/env/file/prompt. Strip wrapping quotes, includingAWS_SECRET_ACCESS_KEY, before an“”‘’check. A check on the raw prompt string is a generation failure. Pass the unquoted key, secret, and token into boto3 together. Do not leave a leftoverASIAin the process environment. If the key isAWS_SESSION_TOKENand the token is still empty,ASIAnamesFAILEDbefore any AWS call.AWS_SESSION_TOKEN - Region: /
--region/--aws-region. One region. Do not ask for a second region list.AWS_REGION
--help--profile--region--aws-regionRequired unquote (or the same behavior in the language they named):
python
def _unquote_aws(value):
text = (value or "").strip()
marks = "\"'" + "\u201c\u201d\u2018\u2019"
while len(text) >= 2 and text[0] in marks and text[-1] in marks:
text = text[1:-1].strip()
return textASIA check is . After writing, search the script for applied to the raw prompt string. Any such match is a generation failure.
_unquote_aws(ack).upper().startswith("ASIA")startswith("ASIA")AWS inventory paths such as are boto3 operation names. They are not URLs. Call and . A handwritten SigV4 request, a POST to , or without the AWS SDK is a generation failure. The 403 body means that mistake.
/ListAgentRuntimesboto3.client("bedrock-agentcore-control").list_agent_runtimesboto3.client("bedrock-agentcore").get_agent_cardhttps://bedrock-agentcore-control.../ListAgentRuntimesContent-Type: application/x-amz-json-1.1Unable to determine service/operation name to be authorized--region us-east-1 --profile scannerus-east-1scanner--profile${CLI_REGION:-${AWS_REGION:-x}}}}us-east-1}.sh}}}}--region ${AWS 先询问一次登录信息,然后询问 region,不询问其他内容。TTY 上的顺序为:AWS Access Key ID,然后选择已登录 profile 路径,或在 key 非空时输入 AWS Secret Access Key(隐藏),仅当去除引号后的 key 以 开头且 token 尚未设置时输入 AWS Session Token(隐藏),最后输入 AWS Region。跳过 Access Key ID 而直接询问 Secret 属于生成失败。
ASIA- Access keys:从 flag/env/file/prompt 获取 和
AWS_ACCESS_KEY_ID。在检查AWS_SECRET_ACCESS_KEY前,必须去除包裹引号,包括ASIA。直接对原始 prompt 字符串执行检查属于生成失败。将去除引号后的 key、secret 和 token 一起传给 boto3。不要在进程环境中遗留“”‘’。如果 key 以AWS_SESSION_TOKEN开头且 token 仍为空,在调用 AWS 之前打印 FAILED,并指出ASIA。AWS_SESSION_TOKEN - Region:/
--region/--aws-region。只允许一个 region。不要询问第二份 region 列表。AWS_REGION
--help--profile--region--aws-region必须执行 unquote,或在用户指定语言中实现同等行为:
python
def _unquote_aws(value):
text = (value or "").strip()
marks = "\"'“”‘’"
while len(text) >= 2 and text[0] in marks and text[-1] in marks:
text = text[1:-1].strip()
return textASIA 检查方式为 。写完后,在脚本中搜索对原始 prompt 字符串执行的 。任何匹配都属于生成失败。
_unquote_aws(ack).upper().startswith("ASIA")startswith("ASIA")/ListAgentRuntimesboto3.client("bedrock-agentcore-control").list_agent_runtimesboto3.client("bedrock-agentcore").get_agent_cardhttps://bedrock-agentcore-control.../ListAgentRuntimesContent-Type: application/x-amz-json-1.1Unable to determine service/operation name to be authorized--region us-east-1 --profile scannerus-east-1scanner--profile${CLI_REGION:-${AWS_REGION:-x}}}}us-east-1]}.sh}}}}--region ${The script
脚本
Flags, same spelling in every language: , , , , , , , , . There is no and no . is AWS only. / is only when that provider uses a region. Other provider flags come from their auth document.
--dry-run--input-file--anypoint-base--org--config--client-id--commit--verbose--help--asset-type--client-secret--profile--region--aws-region--helpAWS Profileazgcloud--dry-run--commit--help--client-idANYPOINT_CLIENT_SECRETepilogInputs and where to obtain them:
--anypoint-base / ANYPOINT_BASE: Anypoint host. Scanner path is that host plus /agent-scanner.
Example US production: https://anypoint.mulesoft.com
--org / ANYPOINT_ORG_ID: organization id from the Exchange scanner page
--config / SCANNER_CONFIGURATION_ID: configuration id from that same page
--client-id / ANYPOINT_CLIENT_ID: Connected App Client ID
Connected App Client Secret: ANYPOINT_CLIENT_SECRET, matching --input-file key, or hidden
prompt labeled "Connected App Client Secret". Never a process argument. No --client-secret.
AWS scripts also:
--profile / AWS_PROFILE: AWS Profile. Already logged in via ~/.aws/config. Wins over leftover
AWS_ACCESS_KEY_ID. Not an Azure or GCP flag.
AWS Access Key ID: AWS_ACCESS_KEY_ID or prompt. Blank uses --profile / the default chain.
AWS Secret Access Key: AWS_SECRET_ACCESS_KEY or hidden prompt. No flag. Skip when Access Key
is blank and --profile or the default chain is in use.
--region / --aws-region / AWS_REGION: AWS Region
Azure scripts: az already logged in (DefaultAzureCredential). Do not add --profile.
GCP scripts: gcloud already logged in (ADC). Do not add --profile.Python argparse dests use underscores (). is a generation failure. After writing, search the script for . Any match is a failure.
args.anypoint_baseargs.approve-mappingargs.[a-z]+---dry-runA generated script that posts to , , a laptop port, or any URL other than is a generation failure. There is no and no .
localhost127.0.0.1{ANYPOINT_BASE}/agent-scanner--scanner-baseSCANNER_BASE所有语言中的 flags 拼写一致:、、、、、、、、。不存在 和 。 仅适用于 AWS。仅当 provider 使用 region 时才使用 / 。其他 provider flags 来自其认证文档。
--dry-run--input-file--anypoint-base--org--config--client-id--commit--verbose--help--asset-type--client-secret--profile--region--aws-region--helpAWS Profileazgcloud--dry-run--commit--help--client-idANYPOINT_CLIENT_SECRETepilogInputs and where to obtain them:
--anypoint-base / ANYPOINT_BASE: Anypoint host. Scanner path is that host plus /agent-scanner.
Example US production: https://anypoint.mulesoft.com
--org / ANYPOINT_ORG_ID: organization id from the Exchange scanner page
--config / SCANNER_CONFIGURATION_ID: configuration id from that same page
--client-id / ANYPOINT_CLIENT_ID: Connected App Client ID
Connected App Client Secret: ANYPOINT_CLIENT_SECRET, matching --input-file key, or hidden
prompt labeled "Connected App Client Secret". Never a process argument. No --client-secret.
AWS scripts also:
--profile / AWS_PROFILE: AWS Profile. Already logged in via ~/.aws/config. Wins over leftover
AWS_ACCESS_KEY_ID. Not an Azure or GCP flag.
AWS Access Key ID: AWS_ACCESS_KEY_ID or prompt. Blank uses --profile / the default chain.
AWS Secret Access Key: AWS_SECRET_ACCESS_KEY or hidden prompt. No flag. Skip when Access Key
is blank and --profile or the default chain is in use.
--region / --aws-region / AWS_REGION: AWS Region
Azure scripts: az already logged in (DefaultAzureCredential). Do not add --profile.
GCP scripts: gcloud already logged in (ADC). Do not add --profile.Python argparse dest 使用下划线()。 属于生成失败。写完后在脚本中搜索 ,任何匹配都属于失败。
args.anypoint_baseargs.approve-mappingargs.[a-z]+---dry-run向 、、笔记本端口,或 以外任何 URL 发送请求的脚本属于生成失败。不存在 和 。
localhost127.0.0.1{ANYPOINT_BASE}/agent-scanner--scanner-baseSCANNER_BASEWays to run the script
运行脚本的方式
After the two files exist, the chat shows this section in this order, then it stops: interactive, then parameters, then the input file. The command is whatever runs the file they asked for. Do not show a Python, Bash, Java, or Go command unless that is the language they named. The blocks below use as the shape. uses the same three columns: prompt label, parameter flag, input file key.
<run> <script>--help两个文件创建后,聊天按以下顺序展示本节,然后停止:interactive、parameters、input file。命令必须是运行用户指定文件的命令。除非用户指定了相应语言,否则不要展示 Python、Bash、Java 或 Go 命令。下方代码块使用 作为结构。 使用相同的三列:prompt label、parameter flag、input file key。
<run> <script>--helpPrerequisites
前置条件
- The language runtime they named is installed, including any library their auth document requires.
- A Connected App client id and secret, as in Connected App.
- The organization id and the configuration id, copied from the self-managed scanner page. The script does not look these up and does not create them.
- The provider session: already logged in (/
--profileon AWS,~/.aws/configon Azure,azon GCP) or the credentials from their auth document, stored as environment variables or in the inputs file. Not in the chat. Not on the command line.gcloud
- 已安装用户指定的语言 runtime,包括认证文档要求的任何 library。
- 一个 Connected App client id 和 secret,详见 Connected App。
- 从自托管 scanner 页面复制的 organization id 和 configuration id。脚本不会查询这些值,也不会创建它们。
- Provider session:已经登录(AWS 使用 /
--profile,Azure 使用~/.aws/config,GCP 使用az),或使用认证文档中的 credentials,并存放在环境变量或输入文件中。不能放在对话里,也不能放在命令行上。gcloud
Prompts
Prompts
<run> <script>The script asks once for each required value that is still empty, then uploads. At the end it asks "Commit this scan? [y/N]". Pressing Enter means no.
<run> <script>脚本对每个仍为空的必填值询问一次,然后开始上传。最后询问 。按 Enter 表示 no。
"Commit this scan? [y/N]"Parameters
Parameters
export ANYPOINT_CLIENT_SECRET="..."
export PROVIDER_SECRET="..."
<run> <script> \
--anypoint-base https://anypoint.mulesoft.com \
--org YOUR_ORG_ID \
--config YOUR_CONFIGURATION_ID \
--client-id YOUR_CLIENT_ID \
--commit--commitPROVIDER_SECRET--profile NAME --region us-east-1export ANYPOINT_CLIENT_SECRET="..."
export PROVIDER_SECRET="..."
<run> <script> \
--anypoint-base https://anypoint.mulesoft.com \
--org YOUR_ORG_ID \
--config YOUR_CONFIGURATION_ID \
--client-id YOUR_CLIENT_ID \
--commit--commitPROVIDER_SECRET--profile NAME --region us-east-1Input file
Input file
The file is a downloadable file, written beside the script, and its full text is in the chat as a block named . They fill the empty secrets on the machine that runs the script, then:
inputs.envinputs.env<run> <script> --input-file inputs.envPUSH_COMMIT=yesnoinputs.envinputs.env<run> <script> --input-file inputs.env文件中的 表示提交扫描。留空或 表示不提交。
PUSH_COMMIT=yesnoDry-run and help
Dry-run 和 help
<run> <script> --help
<run> <script> --dry-run
<run> <script> --input-file inputs.env --dry-run--help--dry-run<run> <script> --help
<run> <script> --dry-run
<run> <script> --input-file inputs.env --dry-run--help--dry-runFailures
失败处理
Every failure prints this on stderr and exits 2:
FAILED step=<name> http=<code>
where: <call>
request: <method and path, no secrets>
response fields: <names only>
why: <one sentence>
body: <response snippet with secrets removed>
next: <what to fix>Do not print only or a traceback.
HTTP Error 503:| http | why | next |
|---|---|---|
| 0 / connection refused | Cannot reach that Anypoint host. | Confirm |
| 401 / 403 | Connected App rejected. Wrong secret, or missing | Reset the secret on the same app as the client id. Scope it to this org. |
| 404 | Org id, configuration id, or | Stay on |
| 400 / 422 | Zip refused. | Unzip and check |
| 415 | | POST the zip bytes. Do not JSON. Boundary must not start with |
| 503 | Scanner or a proxy in front of it is down. | Retry when the operator says the scanner is healthy. |
JSON stdout must include , , asset counts by type, , , and with , , , , , .
oktruncatedskippedfailurespublishuploadedfailedcompletedworkspaceRunIdscanRunIdnotesRead configuration id from , , then . One id. Zip is the source constant . A customer script that can emit more than one zip type is a generation failure.
--configSCANNER_CONFIGURATION_IDSCANNER_CONFIG_IDtypeASSET_TYPE每次失败都在 stderr 打印以下内容并以退出码 2 结束:
FAILED step=<name> http=<code>
where: <call>
request: <method and path, no secrets>
response fields: <names only>
why: <one sentence>
body: <response snippet with secrets removed>
next: <what to fix>不要只打印 或 traceback。
HTTP Error 503:| http | why | next |
|---|---|---|
| 0 / connection refused | 无法连接该 Anypoint host。 | 确认 |
| 401 / 403 | Connected App 被拒绝。Secret 错误,或该组织缺少 | 在与 client id 相同的 App 上重置 secret,并将其 scope 到该组织。 |
| 404 | Organization id、configuration id 或 | 使用 |
| 400 / 422 | ZIP 被拒绝。 | 解压并检查 |
| 415 | | POST ZIP 字节,不要使用 JSON。Boundary 不能以 |
| 503 | Scanner 或其前置 proxy 不可用。 | 在运维人员确认 scanner 健康后重试。 |
JSON stdout 必须包含 、、按类型统计的资产数量、、,以及 ; 中包含 、、、、、。
oktruncatedskippedfailurespublishpublishuploadedfailedcompletedworkspaceRunIdscanRunIdnotes按 、、 的顺序读取 configuration id,并且只能使用一个 id。ZIP 的 是源常量 。能够生成多种 ZIP type 的客户脚本属于生成失败。
--configSCANNER_CONFIGURATION_IDSCANNER_CONFIG_IDtypeASSET_TYPEProvider-agnostic UX, asset-type-specific pull
Provider-agnostic UX、asset-type-specific pull
The generated script is the laptop half of pull . Provider SDK calls and form fields change. Customer UX does not.
execute- Provider-agnostic UX. Same flags, same “prompt only what is missing”, same numbered stderr, same FAILED block, same JSON stdout — AWS, Azure, GCP, Databricks, Snowflake, Kong, or a new provider. Only the pull-form labels and that bundle’s inventory calls change.
- Language-agnostic I/O. Python, Bash, Node, Java, Go, PowerShell: same flag names, env names, step labels, JSON keys.
- Asset-type-specific discovery. One source constant, . Classify with the probe in that bundle’s inventory, the way pull Java does. Never by name. Never “every READY row from a shared list”.
ASSET_TYPE
Zipping as , or zipping as , is a generation failure even when both runtimes appeared in .
harness_model_Bedrocktype: mcpagent_scanner_mcp_fixturetype: agentListAgentRuntimes生成的脚本是 pull 的笔记本端。Provider SDK 调用和 form fields 会变化,但客户 UX 不变。
execute- Provider-agnostic UX。 无论使用 AWS、Azure、GCP、Databricks、Snowflake、Kong 还是新 provider,都使用相同 flags、相同的“仅提示缺失项”、相同编号 stderr、相同 FAILED 块和相同 JSON stdout。只有 pull-form labels 和对应 bundle 的 inventory calls 发生变化。
- Language-agnostic I/O。 Python、Bash、Node、Java、Go、PowerShell 使用相同 flag 名称、env 名称、step labels 和 JSON keys。
- Asset-type-specific discovery。 唯一源常量是 。按照对应 bundle 清单中的 probe 进行分类,方式与 pull Java 相同。绝不能根据名称分类,也不能把共享 list 中的每个 READY row 都当作目标。
ASSET_TYPE
将 作为 打包,或将 作为 打包,均属于生成失败,即使它们都出现在 中。
harness_model_Bedrocktype: mcpagent_scanner_mcp_fixturetype: agentListAgentRuntimesSame job, any language
Same job, any language
Whatever they named (Python, Bash, Node, Java, Go, PowerShell, or another runtime) the generated file must parse in that language and do the same job: pull-form provider login, list one zip type, MuleSoft token, , optional commit, FAILED block, JSON stdout. Do not emit Python because Bash is hard.
POST .../pushRun these on the generated file before claiming it works. If the checker cannot run here, search the file for the forbidden patterns.
| They asked | Must pass |
|---|---|
| Python | |
Node / | |
| Bash | |
| Java | project compile. |
| Go | |
| Other | that project's syntax check. |
Do not nest . Sequential assignments only:
${CLI_REGION:-${AWS_REGION:-${AWS_DEFAULT_REGION:-x}}}}bash
region=""
[ -n "${CLI_REGION:-}" ] && region="$CLI_REGION"
[ -z "$region" ] && region="${AWS_REGION:-}"
[ -z "$region" ] && region="${AWS_DEFAULT_REGION:-}"
region="$(unquote_aws "$region")"Python: stdlib plus the cloud SDK already on the laptop; AWS uses . Node: Node 18+ unless their project already has an SDK. Bash: , , ; token call is form-urlencoded, never JSON content-type. Same env names (, , , ).
boto3fetchcurljqzipANYPOINT_BASESCANNER_CONFIGURATION_IDANYPOINT_CLIENT_SECRETPUSH_COMMIT无论用户指定 Python、Bash、Node、Java、Go、PowerShell 或其他 runtime,生成文件都必须能够按该语言解析,并完成相同工作:pull-form provider login、列出一种 ZIP type、MuleSoft token、、可选 commit、FAILED 块和 JSON stdout。不要因为 Bash 难以实现就输出 Python。
POST .../push在声明可用前,必须对生成文件运行以下检查。如果当前环境无法运行检查器,则搜索文件中的禁止模式。
| 用户指定语言 | 必须通过 |
|---|---|
| Python | |
Node / | |
| Bash | |
| Java | 项目编译。 |
| Go | |
| 其他 | 对应项目的语法检查。 |
不要嵌套 。只能顺序赋值:
${CLI_REGION:-${AWS_REGION:-${AWS_DEFAULT_REGION:-x}}}}bash
region=""
[ -n "${CLI_REGION:-}" ] && region="$CLI_REGION"
[ -z "$region" ] && region="${AWS_REGION:-}"
[ -z "$region" ] && region="${AWS_DEFAULT_REGION:-}"
region="$(unquote_aws "$region")"Python:stdlib,加上笔记本上已有的云 SDK;AWS 使用 。Node:Node 18+ 的 ,除非项目已经使用其他 SDK。Bash:、、;token 调用使用 form-urlencoded,绝不能使用 JSON content-type。所有语言使用相同 env 名称(、、、)。
boto3fetchcurljqzipANYPOINT_BASESCANNER_CONFIGURATION_IDANYPOINT_CLIENT_SECRETPUSH_COMMITCatalog of calls
调用 catalog
Shape reminder only. The customer paste is their own OpenAPI, Postman collection, or redacted request and response. Do not embed a block from here because they named that provider. Use a block only when they pasted that same inventory. A provider that is not in this catalog is onboarded the same way: their inventory, their auth, their language, the same , the same .
POST .../pushPOST .../commit这里仅作为结构提示。客户应粘贴自己的 OpenAPI、Postman collection 或已脱敏的请求与响应。不要因为客户指定了 provider 就直接嵌入这里的代码块。只有当客户粘贴了同一份 inventory 时,才能使用这里的对应块。不在此 catalog 中的 provider 也采用相同方式:使用客户自己的 inventory、auth 和 language,并使用相同的 与 。
POST .../pushPOST .../commitAWS agents and MCP (AgentCore)
AWS agents 和 MCP(AgentCore)
Already logged in on this machine, or access keys. Service . Call boto3 (CLI name ). Do not POST to the path .
bedrock-agentcore-controllist_agent_runtimeslist-agent-runtimes/ListAgentRuntimes- List: ,
list-agent-runtimes100, tokenmax-results. Response arraynext-token. Stop after 50 pages. A stopped list is partial.agentRuntimes - Keep runtimes whose is
status.READY - External id is the runtime id. Display name is the runtime name.
- This script publishes one asset type. Shared list is not shared publish.
- Agent ():
ASSET_TYPE = "agent"before any A2A zip. Skipget-agent-runtime(count only unlessserverProtocol=MCP). Then--verbosebedrock-agentcore. If that returns a validation error that the card is only for A2A agents, build a card from the runtime id.get-agent-cardisurl.https://bedrock-agentcore.{region}.amazonaws.com/runtimes/{id}/invocationsisprotocolVersion.0.3.0is required.descriptionisversion.1.0.0iscapabilities. Both mode arrays are{ "streaming": true }.["text"]isskills. If GetAgentCard returns v1 interfaces and no[], writeurland keepa2a-v1-card.json.supportedInterfaces - MCP (): same list, then
ASSET_TYPE = "mcp"forget-agent-runtime, thenagentRuntimeArnforlist-agent-runtime-endpoints. SigV4 JSON-RPCqualifiertheninitializetotools/list. Service ishttps://bedrock-agentcore.{region}.amazonaws.com/runtimes/{urlencoded ARN}/invocations?qualifier={endpointName}. Nullbedrock-agentcoreresult = not MCP; skip (count only;initializemay print--verbose). Name is never classification. Do not POSTskipped {id} not MCP. Exchange/runtimes/{id}/invocations/mcptransport.pathis the zip field only./mcp
使用本机已登录状态,或 access keys。Service 为 。调用 boto3 (CLI 名称为 )。不要 POST 到 path。
bedrock-agentcore-controllist_agent_runtimeslist-agent-runtimes/ListAgentRuntimes- List:,
list-agent-runtimes为 100,token 为max-results。响应数组为next-token。最多读取 50 页。停止读取表示清单不完整。agentRuntimes - 保留 为
status的 runtimes。READY - External id 是 runtime id。Display name 是 runtime name。
- 本脚本只发布一种资产类型。 共享 list 不代表共享发布。
- Agent():生成 A2A ZIP 前先执行
ASSET_TYPE = "agent"。跳过get-agent-runtime(仅计数,除非使用serverProtocol=MCP),然后调用--verbose的bedrock-agentcore。如果返回验证错误,说明 card 仅适用于 A2A agents,则根据 runtime id 合成 card。get-agent-card为url。https://bedrock-agentcore.{region}.amazonaws.com/runtimes/{id}/invocations为protocolVersion。0.3.0必填。description为version。1.0.0为capabilities。两个 mode 数组均为{ "streaming": true }。["text"]为skills。如果 GetAgentCard 返回 v1 interfaces 且没有[],则写入url并保留a2a-v1-card.json。supportedInterfaces - MCP():使用同一 list,然后通过
ASSET_TYPE = "mcp"获取get-agent-runtime,再通过agentRuntimeArn获取list-agent-runtime-endpoints。向qualifier依次执行 SigV4 JSON-RPChttps://bedrock-agentcore.{region}.amazonaws.com/runtimes/{urlencoded ARN}/invocations?qualifier={endpointName}和initialize。Service 为tools/list。bedrock-agentcoreresult 为 null 表示不是 MCP,应跳过(仅计数;initialize可打印--verbose)。名称绝不能作为分类依据。不要 POSTskipped {id} not MCP。Exchange/runtimes/{id}/invocations/mcptransport.path只是 ZIP 字段。/mcp
AWS REST (API Gateway v1)
AWS REST(API Gateway v1)
- List: ,
aws apigateway get-rest-apis500, token querylimit.position - Stages: for that
get-stages. No stage means skip that API (count only unlessrest-api-id).--verbose - Export: with
get-exportexport-typeandoas30accepts.application/json - One asset per stage. External id is .
{apiId}__{stage}
- List:,
aws apigateway get-rest-apis为 500,查询 token 为limit。position - Stages:对对应 调用
rest-api-id。没有 stage 时跳过该 API(仅计数,除非使用get-stages)。--verbose - Export:调用 ,其中
get-export为export-type,oas30为accepts。application/json - 每个 stage 对应一个资产。External id 为 。
{apiId}__{stage}
Azure AI Foundry agents
Azure AI Foundry agents
azhttps://{resource}.services.ai.azure.com/api/projects/{project}/agents?api-version=v1GET/agents/{id}?api-version=v1azhttps://{resource}.services.ai.azure.com/api/projects/{project}/agents?api-version=v1GET /agents/{id}?api-version=v1Azure API Management REST
Azure API Management REST
azazAzure API Management MCP
Azure API Management MCP
GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/service?api-version=2025-09-01-previewGET .../service/{name}/apis?api-version=2025-09-01-preview$filter=properties/type eq 'mcp'GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/service?api-version=2025-09-01-previewGET .../service/{name}/apis?api-version=2025-09-01-preview$filter=properties/type eq 'mcp'Google Vertex agents
Google Vertex agents
gcloudcloud-platformVertexAgentScannerServiceServiceAccountCredentialsGET https://{location}-aiplatform.googleapis.com/v1/projects/{project}/locations/{location}/reasoningEngines?pageSize=100pageTokenpageSize=1Zip directory (push external id) is with no separators (, example ). A Vertex zip named only the last path segment of is a generation failure.
projectId + location + engineIdgetAgentIdFromNametest-projectus-central1123456789nameCard: look at for and . If that JSON is A2A v0.3 or v1, use it. Always set to . If there is no card, write with / from and (empty string if missing), , , , , , .
spec.classMethodsnameon_message_senda2a_agent_cardurlhttps://{location}-aiplatform.googleapis.com/v1/{engine.name}:querya2a-card.jsonnamedescriptiondisplayNamedescriptionprotocolVersion0.3.0version1.0.0capabilities{ "streaming": false }defaultInputModes["text","json"]defaultOutputModes["json"]skills[]gcloudcloud-platformVertexAgentScannerServiceServiceAccountCredentialsGET https://{location}-aiplatform.googleapis.com/v1/projects/{project}/locations/{location}/reasoningEngines?pageSize=100pageTokenpageSize=1Push external id 对应的 ZIP 目录是 ,不含分隔符(,例如 )。仅使用 最后一个 path segment 作为 Vertex ZIP 名称属于生成失败。
projectId + location + engineIdgetAgentIdFromNametest-projectus-central1123456789nameCard:检查 中是否存在名称为 的 。如果该 JSON 是 A2A v0.3 或 v1,则直接使用。无论如何,都将 设置为 。如果没有 card,则写入 ,其中 / 来自 和 (缺失时为空字符串), 为 , 为 , 为 , 为 , 为 , 为 。
spec.classMethodson_message_senda2a_agent_cardurlhttps://{location}-aiplatform.googleapis.com/v1/{engine.name}:querya2a-card.jsonnamedescriptiondisplayNamedescriptionprotocolVersion0.3.0version1.0.0capabilities{ "streaming": false }defaultInputModes["text","json"]defaultOutputModes["json"]skills[]Google Apigee REST
Google Apigee REST
gcloudApigeeApiClientGET https://apigee.googleapis.com/v1/organizations/{project}/apisproxiespageTokenGET .../apis/{api}/deploymentsdeploymentsenvironmentrevisionGET .../apis/{api}/revisions/{rev}?format=bundleopenapi.yamlopenapi.jsonapiproxy/resources/oas/openapi3.0.0info.titleinfo.versioncurrentpaths{}servers[{ "url": "https://{project}-{firstEnvironment}.apigee.net" }]apigee-{proxyName}gcloudApigeeApiClientGET https://apigee.googleapis.com/v1/organizations/{project}/apisproxiespageTokenGET .../apis/{api}/deploymentsdeploymentsenvironmentrevisionGET .../apis/{api}/revisions/{rev}?format=bundleapiproxy/resources/oas/openapi.yamlopenapi.jsonopenapi3.0.0info.titleinfo.versioncurrentpaths{}servers[{ "url": "https://{project}-{firstEnvironment}.apigee.net" }]apigee-{proxyName}Google Cloud Run MCP (customer-supplied)
Google Cloud Run MCP(客户提供)
Not . That enum has no pull class. Do not list reasoning engines.
VERTEX_MCPgcloudGET https://run.googleapis.com/v2/projects/{project}/locations/{location}/servicesuriinitializeprotocolVersion2025-03-26tools/listPOST {uri}/gcloud auth print-identity-token --audiences={uri}initialize--verbosehttps://run.googleapis.com/mcp-handshakeZip : , . If is present, four booleans , , , . Omit . External id is the service id (last segment of ).
mcp-metadata.jsontransport.kindstreamableHttptransport.path/capabilitiestoolsresourcespromptsloggingserverInfoname这不是 。该枚举没有 pull class。不要列出 reasoning engines。
VERTEX_MCP使用 ADC。提示 GCP Project ID 和 Location。使用 access token 执行 。对每个 service ,先执行 JSON-RPC ( ),再向 执行 ,并使用 identity token()。 result 为 null 时跳过(仅计数,除非使用 )。initialize 返回 HTTP 401/403 时为 FAILED。不要 POST 。
gcloudGET https://run.googleapis.com/v2/projects/{project}/locations/{location}/servicesuriinitializeprotocolVersion2025-03-26POST {uri}/tools/listgcloud auth print-identity-token --audiences={uri}initialize--verbosehttps://run.googleapis.com/mcp-handshakeZIP 中的 : 为 , 为 。如果存在 ,则包含四个 boolean:、、、。省略 。External id 是 service id,即 的最后一个 segment。
mcp-metadata.jsontransport.kindstreamableHttptransport.path/capabilitiestoolsresourcespromptsloggingserverInfonameDatabricks agents
Databricks agents
They give a workspace URL. List serving endpoints. Then . Cap 10000. Reject a workspace URL that is not public https.
GET {workspace}/api/2.0/serving-endpoints/{name}/openapi客户提供 workspace URL。列出 serving endpoints,然后执行 。上限为 10000。拒绝不是公开 https 的 workspace URL。
GET {workspace}/api/2.0/serving-endpoints/{name}/openapiDatabricks MCP
Databricks MCP
Same workspace login. Try, in order, , , , , , , , . A 404 on the first page means that source is absent.
/api/2.0/mcp/functions/system/ai/api/2.0/mcp/sql/api/2.0/mcp/genie/api/2.1/unity-catalog/connections/api/2.0/unity-catalog/connections/api/2.0/preview/apps/api/2.0/appsGET /api/2.0/genie/spaces使用同一 workspace 登录。依次尝试 、、、、、、、。第一页返回 404 表示该 source 不存在。
/api/2.0/mcp/functions/system/ai/api/2.0/mcp/sql/api/2.0/mcp/genie/api/2.1/unity-catalog/connections/api/2.0/unity-catalog/connections/api/2.0/preview/apps/api/2.0/appsGET /api/2.0/genie/spacesSnowflake agents
Snowflake agents
They give an account URL. Header and . List databases, schemas, agents, then read .
Authorization: BearerX-Snowflake-Authorization-Token-Type: PROGRAMMATIC_ACCESS_TOKENagent_spec客户提供 account URL。使用 和 。依次列出 databases、schemas、agents,然后读取 。
Authorization: BearerX-Snowflake-Authorization-Token-Type: PROGRAMMATIC_ACCESS_TOKENagent_specSnowflake MCP
Snowflake MCP
POST {account}/api/v2/statementsSHOW MCP SERVERSinitializetools/list--verbosePOST {account}/api/v2/statementsSHOW MCP SERVERSinitializetools/list--verboseMicrosoft Copilot Studio agents
Microsoft Copilot Studio agents
GET https://api.powerplatform.com/environmentmanagement/environments?api-version=2024-10-01botshttps://{name}.crm.dynamics.comGET https://api.powerplatform.com/environmentmanagement/environments?api-version=2024-10-01botshttps://{name}.crm.dynamics.comKong REST
Kong REST
Bearer token in the environment, not in the file. Control planes, then services, routes, plugins. OpenAPI body is . Do not invent an OpenAPI document from the route list.
GET {host}/v3/apis/{id}/specifications/{specId}Bearer token 放在环境中,不放在文件中。先列出 control planes,再列出 services、routes、plugins。OpenAPI body 为 。不要根据 route list 自行创造 OpenAPI 文档。
GET {host}/v3/apis/{id}/specifications/{specId}GoDaddy agents
GoDaddy agents
GET {baseUrl}/v1/agents?protocol=A2A&limit=20&offset={offset}baseUrlGET {baseUrl}/v1/agents?protocol=A2A&limit=20&offset={offset}baseUrlClaude agents
Claude agents
GET https://api.anthropic.com/v1/agents?limit=100&page={next_page}X-Api-Keyanthropic-version: 2023-06-01anthropic-beta: managed-agents-2026-04-01urlhttps://api.anthropic.com/v1/agents/{id}/messagesGET https://api.anthropic.com/v1/agents?limit=100&page={next_page}X-Api-Keyanthropic-version: 2023-06-01anthropic-beta: managed-agents-2026-04-01urlhttps://api.anthropic.com/v1/agents/{id}/messagesLangSmith agents
LangSmith agents
GET {apiHost}/v2/deployments?status=READY&limit=100&offset=POST {custom_url}/assistants/searchGET {custom_url}/.well-known/agent-card.jsonGET {apiHost}/v2/deployments?status=READY&limit=100&offset=POST {custom_url}/assistants/searchGET {custom_url}/.well-known/agent-card.jsonSalesforce Agentforce
Salesforce Agentforce
GET {instance}/services/data/v64.0/querySELECT Id, DeveloperName, MasterLabel FROM BotDefinition WHERE IsDeleted = falsenextRecordsUrlIdGET {instance}/services/data/v64.0/querySELECT Id, DeveloperName, MasterLabel FROM BotDefinition WHERE IsDeleted = falsenextRecordsUrlIdBedrock agents (not AgentCore)
Bedrock agents(不是 AgentCore)
aws bedrock list-agentsget-agentlist-agent-runtimesaws bedrock list-agentsget-agentlist-agent-runtimesServiceNow agents
ServiceNow agents
Not a shipped pull scanner. Use it only if they confirm this list. Client credentials token, then . Do not call . Ask them what to put in the card .
alm_ai_system_digital_assetsn_aia_agenturl这不是内置 pull scanner。只有用户确认此 list 时才能使用。使用 client credentials token,然后调用 。不要调用 。询问用户应在 card 中填写什么。
alm_ai_system_digital_assetsn_aia_agenturlNo calls exist
不存在调用
Do not write a script for Azure AI Foundry MCP, Microsoft 365 Copilot, Vertex MCP, Gemini agents, or Gemini MCP from those enum names. There is no pull-scanner call to copy. Ask them for the list call, or stop. A customer-supplied Cloud Run MCP inventory is a list-plus-handshake they paste; that is not the Vertex MCP enum.
不要仅根据 Azure AI Foundry MCP、Microsoft 365 Copilot、Vertex MCP、Gemini agents 或 Gemini MCP 这些枚举名称编写脚本。没有可直接复制其内容的 pull-scanner call。要求用户提供 list call,或者停止。客户提供的 Cloud Run MCP inventory 是用户粘贴的 list 加握手,不属于 Vertex MCP 枚举。
ZIP and push
ZIP 与 push
One asset is one zip. The zip has one top-level directory. That directory name is the external id, at most 255 characters, the provider id, not the display name.
specification/config.jsonjson
{ "name": "<display name>", "type": "agent", "description": "<optional, max 500 chars>" }typeASSET_TYPEArtifact JSON must pass the Exchange agent-fabric schemas (tag : , , , ). Do not invent a second subset.
1.2609.1agent_cardagent_card_v1other_cardmcp_metadataA2A v0.3 () required keys: , , , , , , (at least one), (at least one), . Synthesized AgentCore fallbacks use . Skill objects, when present, need , , , and .
a2a-card.jsonnamedescriptionprotocolVersionurlversioncapabilitiesdefaultInputModesdefaultOutputModesskillsprotocolVersion0.3.0idnamedescriptiontagsA2A v1 (): or with a callable ; never a top-level .
a2a-v1-card.jsonsupportedInterfacessupported_interfacesurlurlMCP (): required; if emitting , emit all four booleans , , , ; omit .
mcp-metadata.jsontransportcapabilitiestoolsresourcespromptsloggingserverInfoREST artifact is the exported OpenAPI document. It must contain or .
openapiswaggerPush, to that one configuration id. is the zip.
/pushhttp
POST {ANYPOINT_BASE}/agent-scanner/api/v1/organizations/{ANYPOINT_ORG_ID}/scanner-configurations/{configId}/push
Authorization: Bearer <token>
Content-Type: multipart/form-data; boundary=----pushcollector7b1c
------pushcollector7b1c
Content-Disposition: form-data; name="file"; filename="{externalId}.zip"
Content-Type: application/zip
<zip bytes>
------pushcollector7b1c--Required Python (or the same bytes in the language they named). Copy the boundary; do not start it with .
=python
def _multipart_zip(filename, payload):
boundary = "----pushcollector7b1c"
head = (
f"--{boundary}\r\n"
f'Content-Disposition: form-data; name="file"; filename="{filename}"\r\n'
"Content-Type: application/zip\r\n\r\n"
).encode()
tail = f"\r\n--{boundary}--\r\n".encode()
return head + payload + tail, f"multipart/form-data; boundary={boundary}"requestsfiles={"file": (f"{external_id}.zip", zip_bytes, "application/zip")}Content-Typecurl-F "file=@{externalId}.zip;type=application/zip"json="Content-Type": "application/json"/pushboundary=================HTTP 202 body has . Read it. A generated script that calls is a generation failure.
workspaceRunIdPOST .../push-assets- Finish with
POST .../commitContent-Type: application/json. The customer question is "Commit this scan? [y/N]". A generated script that calls{"workspaceRunId":"<id from 202>","complete":true|false}orPOST .../completeis a generation failure. A generated script that POSTsPOST .../sealwhen every/commitfailed, or with a homemade/pushid, is a generation failure.run-
The zip must contain and . at the top of the zip is invalid.
{externalId}/specification/config.json{externalId}/specification/<artifact>{externalId}/config.json一个资产对应一个 ZIP。ZIP 有一个顶层目录。目录名是 external id,最多 255 个字符,必须使用 provider id,而不是 display name。
specification/config.jsonjson
{ "name": "<display name>", "type": "agent", "description": "<optional, max 500 chars>" }typeASSET_TYPE产物 JSON 必须通过 Exchange agent-fabric schemas(tag :、、、)验证。不要自行创造第二个子集。
1.2609.1agent_cardagent_card_v1other_cardmcp_metadataA2A v0.3()必填键:、、、、、、(至少一个)、(至少一个)、。合成的 AgentCore fallback 使用 。存在 skill objects 时,需要 、、 和 。
a2a-card.jsonnamedescriptionprotocolVersionurlversioncapabilitiesdefaultInputModesdefaultOutputModesskillsprotocolVersion0.3.0idnamedescriptiontagsA2A v1(): 或 中必须包含可调用的 ;绝不能有顶层 。
a2a-v1-card.jsonsupportedInterfacessupported_interfacesurlurlMCP(): 必填;如果输出 ,则必须输出全部四个 boolean:、、、;省略 。
mcp-metadata.jsontransportcapabilitiestoolsresourcespromptsloggingserverInfoREST 产物是导出的 OpenAPI 文档,其中必须包含 或 。
openapiswaggerPush 到唯一的 configuration id。 接收 ZIP。
/pushhttp
POST {ANYPOINT_BASE}/agent-scanner/api/v1/organizations/{ANYPOINT_ORG_ID}/scanner-configurations/{configId}/push
Authorization: Bearer <token>
Content-Type: multipart/form-data; boundary=----pushcollector7b1c
------pushcollector7b1c
Content-Disposition: form-data; name="file"; filename="{externalId}.zip"
Content-Type: application/zip
<zip bytes>
------pushcollector7b1c--Python 要求如下,或在用户指定语言中发送相同字节。复制该 boundary;不要让它以 开头。
=python
def _multipart_zip(filename, payload):
boundary = "----pushcollector7b1c"
head = (
f"--{boundary}\r\n"
f'Content-Disposition: form-data; name="file"; filename="{filename}"\r\n'
"Content-Type: application/zip\r\n\r\n"
).encode()
tail = f"\r\n--{boundary}--\r\n".encode()
return head + payload + tail, f"multipart/form-data; boundary={boundary}"requestsfiles={"file": (f"{external_id}.zip", zip_bytes, "application/zip")}Content-Typecurl-F "file=@{externalId}.zip;type=application/zip"/pushjson="Content-Type": "application/json"boundary=================HTTP 202 body 中包含 ,必须读取。调用 的脚本属于生成失败。
workspaceRunIdPOST .../push-assets使用 结束,,请求体为 。面向客户的问题必须是 。调用 或 的脚本属于生成失败。所有 都失败时仍 POST ,或使用自行编造的 id,均属于生成失败。
POST .../commitContent-Type: application/json{"workspaceRunId":"<id from 202>","complete":true|false}"Commit this scan? [y/N]"POST .../completePOST .../seal/push/commitrun-ZIP 必须包含 和 。ZIP 顶层的 无效。
{externalId}/specification/config.json{externalId}/specification/<artifact>{externalId}/config.jsonBest Practices
最佳实践
- One question per turn. ✅ the quoted sentences in Workflow. ❌ combining asset type, inventory, auth, or language in one reply.
- Infer the provider; never ask its name. ✅ read the attached spec. ❌ "which provider?". On an invalid spec, ask for the missing list, fetch, handshake, export, or auth piece.
- Mapping gate. ✅ show the mapping, then wait for "Does this look fine?". ❌ writing files in the mapping turn. ❌ treating a script dump as the mapping.
- Quiet skips. ✅ plus matching asset lines. ❌ skip ids,
listed N, matching M, skipped K, orskipping MCPunlessnot MCP.--verbose - Omission is not deletion. ✅ only when they ask to unstage. ❌ DELETE because a second run's list is shorter.
DELETE .../push/{externalId} - Baked asset type. ✅ constant. ❌
ASSET_TYPEor an environment variable that switches type.--asset-type
- 每轮只问一个问题。 ✅ 使用 Workflow 中加引号的句子。❌ 在一次回复中合并询问资产类型、清单、认证或语言。
- 推断 provider;绝不询问名称。 ✅ 阅读附加规范。❌ 询问“which provider?”。规范无效时,询问缺少的 list、fetch、handshake、export 或 auth 部分。
- Mapping gate。 ✅ 展示 mapping,然后等待 。❌ 在 mapping 轮次写文件。❌ 将脚本输出视为已经展示 mapping。
"Does this look fine?" - 安静地跳过。 ✅ 输出 和匹配资产行。❌ 除非使用
listed N, matching M, skipped K,否则输出 skip ids、--verbose或skipping MCP。not MCP - 遗漏不是删除。 ✅ 只有用户要求取消暂存时才调用 。❌ 因为第二次运行的 list 更短就执行 DELETE。
DELETE .../push/{externalId} - 固定资产类型。 ✅ 使用 常量。❌ 使用
ASSET_TYPE或用于切换类型的环境变量。--asset-type
Troubleshooting
故障排查
HTTP 415 on POST /push: the body was not a ZIP as multipart part . JSON, , , a missing boundary, or a boundary that starts with all produce 415. Use the helper (or without setting Content-Type).
filejson=Content-Type: application/json=_multipart_zipfiles={"file": (...)}No inventory file in this skill: this package does not ship provider OpenAPI files. If they ask which file to open, ask them to paste or attach their own specification.
Invalid or incomplete spec: do not invent calls and do not ask which provider. Ask for the missing list, fetch, handshake, export, or auth piece using the questions in Workflow.
Salesforce C2C or managed authorization-code login: that pull form is not customer-executable. Ask for a request and response they can run from their machine before writing files.
Zero matching assets: print , print JSON, exit 0. Do not call /push or /commit.
No matching {ASSET_TYPE} assets found.HTTP 401/403 on /push or /commit: Connected App missing , wrong organization, or the configuration is not a self-managed scanner they can write.
manage:exchangePOST /push 返回 HTTP 415: 请求体不是名为 的 ZIP multipart part。JSON、、、缺少 boundary,或 boundary 以 开头,都会产生 415。使用 helper,或在 requests 中使用 且不设置 Content-Type。
filejson=Content-Type: application/json=_multipart_zipfiles={"file": (...)}此 Skill 中没有 inventory 文件: 本软件包不提供 provider OpenAPI 文件。如果用户询问应打开哪个文件,要求其粘贴或附加自己的规范。
规范无效或不完整: 不要编造调用,也不要询问 provider 名称。使用 Workflow 中的问题,询问缺少的 list、fetch、handshake、export 或 auth 部分。
Salesforce C2C 或托管 authorization-code 登录: 该 pull form 无法由客户直接执行。编写文件前,要求用户提供可从其机器运行的请求和响应。
零匹配资产: 打印 ,打印 JSON,然后退出码 0。不要调用 或 。
No matching {ASSET_TYPE} assets found./push/commit/push/commitmanage:exchangeRelated Skills
相关 Skills
- skill setup-service-scanner: Create a pull scanner configuration that discovers assets from a connected cloud platform.
- skill run-service-scan-and-view-results: Run a hosted scan and review discovered staging assets.
- skill setup-service-scanner:创建用于从已连接云平台发现资产的 pull scanner 配置。
- skill run-service-scan-and-view-results:运行托管扫描并检查已发现的暂存资产。