docs(decisions): ADR-019 unify agent tools behind an AgentCore Gateway (#641) - #663
Conversation
Starlight requires `autogenerate` as a sibling of `label`, not wrapped in `items[]`. The nested form failed `astro check` on main; this unblocks the docs CI build for the ADR-019 PR.
isadeks
left a comment
There was a problem hiding this comment.
Thanks for writing this up — the general decision is sound and matches the intent of #641: Gateway as a managed tool plane, substrate-portable inbound (SigV4 default / JWT), outbound auth that branches by target type, registry-declared targets, and the tool credential never entering the container. The ADR-016 relationship, the candidate-numbering note, and the astro.config.mjs sidebar fix are all handled well.
However, the near-term scope (Linear + Jira MCP as P1/P2) needs to change before this moves toward accepted. It contradicts #641, reverses ADR-016, and rests on a factual error about the code it cites. Requesting changes on those points; the mechanism itself is fine.
1. Factual error: "the two MCP servers ABCA uses today" — there is one, and it's a non-functional placeholder
The ADR's Context and Scope sections describe agent/src/channel_mcp.py as hosting "the two MCP servers ABCA uses today — Linear and Jira" and calls Linear "functional today via a direct Bearer ${LINEAR_API_TOKEN} entry." The code says the opposite:
- One builder entry exists, not two:
CHANNEL_MCP_BUILDERS = { "jira": (...) }— no Linear. - Linear MCP is not just absent, it's forbidden and actively stripped. The module docstring: "Linear is NOT written here… There is no Linear MCP… The Linear MCP was removed after it proved non-functional."
strip_linear_mcp_servers()deletes any Linear MCP entry from.mcp.jsonbefore the SDK loads it, on every task, as ADR-016 enforcement. - Jira's entry is itself a non-functional placeholder (headless OAuth 2.1 can't connect; the live path is the
jira_reactions.pyREST shim, per ADR-015).
So the count of functional platform-managed MCP servers the agent uses today is zero, and Linear specifically was tried, proven non-functional, removed, and is now scrubbed. The ADR should state this accurately.
2. Scope contradicts #641
#641 was written specifically to steer away from a Linear-first cut:
- The spike branch is "Linear-coupled and out of scope — use it as a reference for the mechanism, not a base… do NOT continue off it."
- "Test multiple target TYPES (not just one OAuth server). The prior spike only exercised a single 3LO-OAuth MCP-server target."
- "OAuth is one option among several… most targets we'd add never touch OAuth", and "the UX must not make API-key / IAM / 2LO targets pay [the 3LO] cost."
This ADR makes Linear + Jira — both 3LO-OAuth remote MCP servers, the single hardest auth path — the P1/P2 deliverable, and frames it as a positive ("the near-term tests exercise the hardest auth path"). That's the opposite of what #641 asked: lead with the simpler, common target types.
3. The ADR-016 reversal can't be deferred
The ADR's ADR-016 tension callout is honest and appreciated — but it treats the conflict as a "follow-up, not resolved unilaterally in this ADR." It's the crux, not a footnote: ADR-016 + shipping enforcement code (strip_linear_mcp_servers) mandate that the agent has no Linear MCP, while this ADR's P1 is "route Linear MCP through an agent-reachable gateway." An ADR can't reach accepted when its first deliverable is barred by an accepted ADR and by enforcement code in the tree. This must be resolved (reconcile or explicit carve-out) before landing, not after.
4. "Admin direction" isn't reflected in #641
The Linear+Jira scope is attributed to "admin direction," but #641 contains no such scoping — it de-scopes Linear. If there is a separate directive, please reconcile it with #641 and ADR-016 in writing; as it stands the ADR and its originating issue disagree on scope.
Suggested change — keep the mechanism, swap the exemplar
The decision is good; only the near-term exemplar is wrong. Concretely:
- Pick a near-term target ABCA actually wants the agent to hold as an MCP tool — a Lambda tool, an IAM-signed internal service, or an API-key service. This exercises the simpler, common auth paths first (what #641 asked), proves substrate portability on both microVM and ECS/Fargate, and introduces no ADR-016 conflict.
- Remove Linear and Jira from P1/P2. Linear is deterministic by decision (ADR-016); Jira's real path is the REST shim (ADR-015). If "can a gateway unbreak the non-functional Jira MCP placeholder?" is worth exploring, record it as a speculative later experiment, explicitly noting it does not re-introduce agent-side Linear/Jira MCP into the deterministic reaction/orchestration paths.
- Fix the factual claims in Context/Scope about
channel_mcp.py(one entry, non-functional; Linear removed and stripped per ADR-016).
Happy to pair on the revised scope. I'll also drop a note on #641 clarifying that Linear/Jira MCP is explicitly not the goal so this doesn't recur.
…aws-samples#666) (aws-samples#669) Adopt EARS (Easy Approach to Requirements Syntax) as the required syntax for normative requirements in ADRs. The ADR states its own Decision in EARS to dogfood the standard; explanatory prose is intentionally out of scope. Regenerates the Starlight decisions mirror via docs:sync. Status: proposed (flips to accepted when this PR merges). Note: ADR-018 (aws-samples#548, aws-samples#662) and ADR-019 (aws-samples#663) are claimed by in-flight PRs; 020 is the first free number. May need renumbering if the queue shuffles before merge. Co-authored-by: scottschreckengaust <345885+scottschreckengaust@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…inear/Jira MCP (aws-samples#641) Address review on aws-samples#663: - Fix Context/Scope facts: zero functional platform-managed MCP servers today (one non-functional jira placeholder; Linear removed and stripped per ADR-016), not "Linear + Jira". - Reorder phasing: P1 leads with a Lambda tool target (IAM execution role, no stored credential, no consent) per aws-samples#641; the 3LO-OAuth remote-MCP path is exercised last. - Remove Linear + Jira from near-term scope; Linear stays deterministic (ADR-016), Jira stays the REST shim (ADR-015). Gateway-unbreaks-Jira-MCP demoted to a separately-gated speculative P4 experiment touching neither deterministic path. - Drop "admin direction" framing and the deferred ADR-016 tension callout; no reversal remains to reconcile.
|
Thanks for the thorough review — agreed on all four points, and the mechanism-vs-exemplar framing was exactly the right cut. Addressed in
Phasing table and Testing section were reordered to match (P1 = Lambda/no-credential; the target × auth matrix broadens from simplest to hardest). |
Commit 23e9810 rewrote the Decisions sidebar entry to the sibling form `autogenerate: { directory: 'decisions' }`, but Starlight's config schema rejects that here (sidebar.6 'Did not match union' → the `build (agentcore)` CI job failed at //docs:build). The nested form on main — `items: [{ autogenerate: { directory: 'decisions' } }]` — is what both `astro check` (0 errors) and `docs:build` (69 pages) accept. Restore it.
- Drop stale candidate-numbering blockquote: ADR-018/020/021 are all on main now and ADR-019 is unambiguously free; PR aws-samples#548 (titled ADR-018) is the actual numbering collision, not this ADR. - Clarify the AGENTCORE_GATEWAY_MCP_SPIKE.md references live only on the upstream feat/agentcore-gateway-mcp branch, not merged to main. - Regenerate Starlight mirror.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #663 +/- ##
=======================================
Coverage ? 91.93%
=======================================
Files ? 298
Lines ? 83853
Branches ? 9319
=======================================
Hits ? 77090
Misses ? 6763
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ws-samples#246) ADR-018 is already taken on main (ADR-018-linear-agent-session-interaction), and 019/020/021 are claimed by open PR aws-samples#663 and merged main ADRs. 022 is the next unclaimed number. Renames the source + Starlight mirror and updates the H1 titles; numbers are never reused (docs/decisions/README.md).
…ws-samples#246) ADR-018 is already taken on main (ADR-018-linear-agent-session-interaction), and 019/020/021 are claimed by open PR aws-samples#663 and merged main ADRs. 022 is the next unclaimed number. Renames the source + Starlight mirror and updates the H1 titles; numbers are never reused (docs/decisions/README.md).
…mples#246) (aws-samples#548) * docs(decisions): ADR-018 propose central agent asset registry (aws-samples#246) Draft ADR proposing a versioned, immutable-per-version asset registry for MCP servers, Cedar policy modules, and skills. Fixes the contract (semver grammar, immutability, resolve-at-create-task, descriptor validation, governance workflow) and defers substrate selection to the design PR. Ranks AWS Agent Registry as preferred with DynamoDB+S3 as fallback; surveys mcp-gateway-registry, agentregistry.ai, and Entra Agent Registry+AGT as considered alternatives. Status: proposed. Requires the aws-samples#246 `approved` label before opening a follow-up implementation PR (per ADR-003). Includes regenerated Starlight mirror. * docs(decisions): reconcile ADR-018 with shipped AgentCore implementation (aws-samples#246) Addresses review on aws-samples#548 (@scottschreckengaust, @isadeks) and records the resolved substrate decision. Refinements (not a reversal — the ranking, alternatives, and flip-conditions are retained as the decision record): - Status proposed → accepted; substrate resolved to AWS Agent Registry (Bedrock AgentCore), built behind the RegistryClient seam and proven E2E. - Resolution owner: TypeScript orchestrator owns catalog/semver resolution; Python loads the already-resolved bundle (mirrored resolver only for the parity contract + direct lookups). Keeps sub-decision 6 true. - Governance: separated substrate-provided lifecycle machinery from the thin ABCA MVP surface (publish + auto_approve + resolve/list/show); standalone promote/reject/deprecate, env-gated auto-approve, and event consumption named as future scope (aws-samples#478/aws-samples#230). - Descriptor validation: MVP delegates to native descriptor types (MCP server.json, skill frontmatter, CUSTOM); shared JSON Schema capability descriptor is future scope (aws-samples#481). - Grammar: reframed "already committed" → "extends the committed shape"; authoritative strict grammar in registry/ref.{ts,py}. - Accuracy: single canonical `approved` token; aws-samples#381-split ref 12 → 13; reference URLs normalized (cloud.google.com, learn.microsoft.com). - Added dated Changelog per docs/decisions/README refinement rules. Starlight mirror regenerated via docs sync (not hand-edited). * docs(decisions): de-link not-yet-merged ref.{ts,py} paths to fix link-check (aws-samples#246) The ADR cited cdk/src/handlers/shared/registry/ref.ts and agent/src/registry/ref.py as relative-path links, but those files ship in the implementation PRs (aws-samples#664/aws-samples#665), not on this ADR branch or main — so //docs:link-check failed with 2 dead links. Demoted both to inline code spans (with a note that they land with aws-samples#664/aws-samples#665) until the implementation merges. Mirror regenerated via docs sync. * docs(decisions): keep ADR-018 proposed + address review (vocab, federation, cutover) (aws-samples#246) Addresses review feedback from @krokoko, @scottschreckengaust, @isadeks: - Revert premature proposed→accepted (README rule: accepted on impl-PR merge; aws-samples#664/aws-samples#665 still in review). Soften "shipped / proven E2E on a live stack" to "targeted by aws-samples#664/aws-samples#665, exercised on a dev stack during review"; stop citing the parked DDB+S3 PRs (aws-samples#632-aws-samples#634) as current. Add a Status note in Decision. - Add short-vs-long-form kind-vocabulary migration note to sub-decision 1: WORKFLOWS.md short forms (registry://mcp/…) are lenient-only forward-decls; only the long form (mcp_server/ns/name@constraint) resolves. No auto-aliasing. - Add a federation / "registry of registries" Non-goal (answers Scott's Jul-8 question): single operator-curated catalog; external registries are discovery-only; no federation in aws-samples#246. - Promote the 2026-08-06 AgentCore namespace cutover from a cost input to a hard gate: no production dependency until the migration is GA in-region. Mirror regenerated via docs sync (idempotent). * docs(decisions): renumber registry ADR 018 -> 022 to avoid collision (aws-samples#246) ADR-018 is already taken on main (ADR-018-linear-agent-session-interaction), and 019/020/021 are claimed by open PR aws-samples#663 and merged main ADRs. 022 is the next unclaimed number. Renames the source + Starlight mirror and updates the H1 titles; numbers are never reused (docs/decisions/README.md). * docs(decisions): add read-path + descriptor-integrity invariants to ADR-022 (aws-samples#246) Second review pass (@scottschreckengaust): - Sub-decision 11 + the substrate-invariant list gain read-path confidentiality: runtime payloads reference credentials (never inline), and open read surfaces redact by allowlist, not denylist. - Sub-decision 7 requires the validated descriptor be carried isolated from caller-controlled discovery prose (non-bypassable validation), incl. CUSTOM. - Collapse the residual submitted/PENDING_APPROVAL dual token; bump Last-updated; add the 018->022 renumber changelog entry; mark previously-pending items landed. --------- Co-authored-by: bgagent <bgagent@noreply.github.com>
What
Adds ADR-019: Unify agent tools behind an AgentCore Gateway — the tool-plane complement to ADR-016. Records the decision to federate ABCA's agent tools behind an Amazon Bedrock AgentCore Gateway (managed MCP aggregation + dual-sided auth), portable across the AgentCore microVM and ECS/Fargate substrates.
Docs-only: the ADR plus its regenerated Starlight mirror.
Scope (near-term)
Lead with the simplest, most common target type — not the hardest. Per #641, OAuth is one option among several and most targets never touch it; the prior spike's mistake was exercising only a single 3LO-OAuth target. So the ADR phases delivery off the easiest outbound leg:
Linear and Jira MCP are explicitly out of near-term scope. Linear stays deterministic by decision (ADR-016, enforced by
strip_linear_mcp_servers()); Jira's live path stays the REST shim (ADR-015). Whether a gateway that owns the OAuth flow could unbreak the non-functional Jira MCP placeholder is recorded as a P4 speculative experiment, gated separately.Key decisions
Governance note
Filing this ADR PR as the mechanism to move the #641 decision toward
accepted. Implementation PRs (P1+) will follow ADR-003 governance once the decision lands.Validation
mise //docs:sync— mirror regenerated and in sync.mise //docs:link-check— clean.Refs #641. Grounded in the
feat/agentcore-gateway-mcpspike (verdict: GO) and reference samplesaal80/agentcore-samples,aws-samples/sample-agent-assisted-sdlc,awslabs/agentcore-samples(SRE-agent).