feat(api): wire MCP + A2A protocol endpoints into Nexo.API - #267
Merged
Conversation
Contributor
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
All four protocol directions become available on the API host, feature-flagged off by default (appsettings ships explicit disabled sections): - Program.cs: AddNexoMcpServer().WithHttpTransport() + AddNexoMcpClient + AddNexoA2AServer + AddNexoA2ATransport (before AddNexo so its scheme registration joins the remote-transport composition); read-only repo tools registered for MCP allowlisting; MapNexoMcpEndpoint + MapNexoA2AEndpoints after the security chain with named per-IP rate-limit policies (nexo-mcp / nexo-a2a, off by default via NexoMiddlewareIngressOptions fields). - NexoApiKeyAuthMiddleware: protocol-path handling - /api/mcp, /api/a2a, and the /.well-known/agent-card.json discovery path are protected on ALL verbs (the MCP SSE listen channel is a GET the mutating-verb scope would have ignored, and the root card lives outside /api entirely). Agent-card anonymity is an explicit opt-in mirrored from Nexo:A2A:Server via the new NexoProtocolIngressOptions so the middleware stays decoupled from adapters. - AgentRegistryA2ACatalog: host-side INexoA2AAgentCatalog over IAgentRegistry (the one place the domain persona model meets the A2A descriptor). - IngressCapability mcp/a2a keys + IngressCatalog operator-inventory rows. Live smoke on the built host: disabled => /health 200, /api/mcp 405, root card 404; enabled+ApiKey => 401 without key, 200 initialize with key (protocol version negotiated down to the client's 2025-06-18). [skip-prod-style]: ProdStyle endpoint tests live in src/Nexo.Tests.Infrastructure (layer boundary forbids src/** changes here); they land in the follow-up src-side PR together with the mcp-a2a CI gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
IanFrelingerforce-pushed
the
application/mcp-a2a
branch
from
August 13, 2026 18:17
336a6fa to
076bc62CompareIanFrelingerforce-pushed
the
application/mcp-a2a-endpoints
branch
from
August 13, 2026 18:17
503c49c to
74d58bcCompareUh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR-4 of the MCP/A2A series — the application-layer wiring, targeting the long-lived
application/mcp-a2aintegration branch (created from the src-side chain #263→#266 so the adapter code exists underneath; this PR''s diff touches onlyapplication/**per the layer-boundary rules; lands on master via coordinated merge once the src chain is in).All four protocol directions become available on the API host, feature-flagged off by default.
Changes
Program.cs:AddNexoMcpServer().WithHttpTransport()+AddNexoMcpClient+AddNexoA2AServer+AddNexoA2ATransport(beforeAddNexo()so its scheme registration joins the remote-transport composition); read-only repo tools (repo.fs.read/repo.fs.list) registered for MCP allowlisting — mutating tools deliberately not pre-registered;MapNexoMcpEndpoint()+MapNexoA2AEndpoints()after the security chain with named per-IP rate-limit policies (nexo-mcp/nexo-a2a, off by default). NoAllowAnonymousanywhere.NexoApiKeyAuthMiddleware: protocol-path handling —/api/mcp,/api/a2a, and the spec-mandated root/.well-known/agent-card.jsonare protected on all verbs (the MCP SSE listen channel is a GET that the default mutating-verb scope ignored, and the root card lives outside/apientirely). Card anonymity is an explicit opt-in mirrored fromNexo:A2A:Server:AllowAnonymousAgentCardvia the newNexoProtocolIngressOptions, keeping the middleware decoupled from adapter packages.AgentRegistryA2ACatalog: host-sideINexoA2AAgentCatalogoverIAgentRegistry— the single place the domain persona model meets the A2A descriptor (adapter can''t referenceCore.Domainper layering).IngressCapabilitymcp/a2akeys,IngressCatalogoperator-inventory rows,NexoMiddlewareIngressOptionsrate-limit fields,appsettings.jsonexplicit disabled defaults.Nexo.API.csproj: adapter project references (note in-file: Nexo.API is not packed by any workflow today; if that changes the non-packable A2A refs must be revisited).Testing
Live smoke on the built host (
DOTNET_ROLL_FORWARD=Major, this machine lacks the net8 ASP.NET runtime):/health200 ·POST /api/mcp405 (unmapped) ·/.well-known/agent-card.json404 — surfaces fully darkPOST /api/mcpinitialize 401 without key, 200 with key returning a spec-correct result (protocolVersionnegotiated down to the client''s2025-06-18,serverInfo: nexo, tools capability)Nexo.APIbuilds clean with warnings-as-errors[skip-prod-style]— ProdStyle endpoint tests live insrc/Nexo.Tests.Infrastructurewhich this application-base PR cannot touch; they land in the follow-up src-side PR (ProdStyle suite +mcp-a2a-gate.yml+ compose env rows).Testing strategy (blast radius)
— n/a (no src/ changes)make kernel-coverage-gate— n/amake kernel-gatemake test-prod-style— deferred to follow-up src PR per layer boundary (see[skip-prod-style])Checklist
TODOorNotImplementedExceptionleft unresolvedRelease (only when this PR ships a versioned NuGet/GHCR release)
🤖 Generated with Claude Code