Skip to content

Release 0.9.0

Choose a tag to compare

@tercel tercel released this 06 Mar 10:20
· 18 commits to main since this release

Added

  • async_serve() context manager: New public API for embedding the MCP server into a larger ASGI application. Returns a Starlette app via async with async_serve(registry) as mcp_app:, enabling co-hosting with A2A, Django ASGI, or other services under a single uvicorn process.
  • TransportManager.build_streamable_http_app(): Low-level async context manager that builds a Starlette ASGI app with MCP transport, health, and metrics routes. Supports extra_routes and middleware injection.
  • ExecutionCancelledError handling: ErrorMapper now maps apcore's ExecutionCancelledError to a safe EXECUTION_CANCELLED response with retryable=True. Internal cancellation details are never leaked.
  • New error codes: VERSION_INCOMPATIBLE, ERROR_CODE_COLLISION, and EXECUTION_CANCELLED added to ERROR_CODES constants.
  • Deep merge for streaming: Streaming chunk accumulation uses recursive deep merge (depth-capped at 32) instead of shallow merge, correctly handling nested response structures.

Changed

  • Dependency bump: Requires apcore>=0.9.0 (was >=0.7.0). Picks up PreflightResult, 11-step executor pipeline, retry middleware, error code registry, and more.
  • Preflight validation aligned with apcore 0.9.0: ExecutionRouter now passes the router-built Context (with identity, callbacks) to Executor.validate(), enabling accurate ACL and call-chain preflight checks. Error formatting handles all three PreflightResult error shapes: nested schema errors, flat field errors, and code-only errors.
  • Annotation description suffix: AnnotationMapper.to_description_suffix() now produces safety warnings (WARNING: DESTRUCTIVE, REQUIRES APPROVAL) as a separate section above the machine-readable annotation block, improving AI agent awareness of dangerous operations.
  • Auth middleware best-effort identity on exempt paths: AuthMiddleware now attempts identity extraction on exempt paths. Valid tokens populate auth_identity_var even when auth is not required, allowing downstream handlers to use identity when available.