-
Notifications
You must be signed in to change notification settings - Fork 279
Description
Extension SDK Core & MCP Framework — Critical Items
This work unit covers all P0 (Critical) proposals from the parent issue. These are the foundational framework improvements that eliminate the most boilerplate and benefit every extension author.
Extension SDK Base
P0-1: Extension Base Command Builder
Provide NewExtensionRootCommand() that auto-registers azd's global flags, sets up OpenTelemetry trace context, calls WithAccessToken(), and provides a structured ExtensionContext.
Current duplication (identical code in every extension):
- azd-exec/main.go L21-41, L189-194 — flag variables + registration
- azd-app/main.go L17-23, L83-87
- azd-copilot/main.go L22-37, L138-141
- azd-rest/root.go L19-35, L77-91
Identical trace context extraction in every extension:
P0-2: Global Flags Propagation via Environment Variables
Modify runner.go and middleware/extensions.go to export AZD_DEBUG, AZD_NO_PROMPT, AZD_CWD, AZD_ENVIRONMENT when spawning extensions.
Framework only passes 4 env vars today:
P0-3: BaseServiceTargetProvider with No-Op Defaults
Add BaseServiceTargetProvider so extensions embed it and only override needed methods.
- azure-dev ServiceTargetProvider interface (6+ required methods)
- azd-app stub implementation L17-111 — mostly no-ops
P0-4: Standard Command Scaffolding (listen, metadata, version, mcp)
Provide NewListenCommand(), NewMetadataCommand(), NewVersionCommand(), NewMCPServeCommand().
Identical listen commands:
Identical metadata commands:
Identical version commands:
MCP Server Framework
P0-5: MCP Server Builder with Middleware
Wrap mark3labs/mcp-go with rate limiting, path validation, and security middleware applied automatically.
Rate limiter duplicated in every MCP extension:
- azd-exec/mcp_ratelimit.go L7 —
var globalRateLimiter = azdextutil.NewRateLimiter(10, 1.0) - azd-rest/mcp.go L24 — same pattern
- azd-app/mcp_ratelimit.go L63 — custom TokenBucket (doesn't even use shared impl)
- azd-core RateLimiter impl L9-56
Manual rate limit checks in every tool handler:
- azd-exec/mcp.go L115, L204, L267, L314 —
if !globalRateLimiter.Allow()repeated 4 times
P0-6: Typed MCP Argument Parsing
Add ParseToolArgs(), RequireString(), OptionalBool(), OptionalInt().
Duplicate arg parsing helpers:
- azd-exec/mcp.go L360-376 — local
getArgsMap()+getStringParam() - azd-core/azdextutil/mcp.go L12-30 — shared
GetArgsMap()+GetStringParam()(azd-exec doesn't use these)
P0-7: MCP Result Marshaling Helpers
Add MCPTextResult(), MCPJSONResult(), MCPErrorResult().
- azd-exec/mcp.go L385-408 — custom
marshalExecResult()+marshalToolResult()
P0-8: MCP Security Middleware
Centralize SSRF protection, path validation, header redaction as pluggable middleware.
Hardcoded blocklists in azd-rest:
- azd-rest/mcp.go L34-66 —
blockedHeaders,blockedHosts,blockedCIDRs - azd-rest/mcp.go L84-134 —
isBlockedIP(),isBlockedURL()with DNS + CIDR checking
Path validation in azd-core:
- azd-core/security/security.go L33, L175 —
ValidatePath(),ValidatePathWithinBases()
Estimated Impact
- ~300-500 lines of boilerplate eliminated per extension
- All 8 P0 proposals addressed
- Every current and future extension benefits