Releases: aiperceivable/apcore-mcp-python
Releases · aiperceivable/apcore-mcp-python
Release 0.14.0
Changed
- Dependency bump:
apcore >= 0.19.0(was>= 0.18.0). - New dependency:
apcore-toolkit >= 0.5.0— picks up theScannedModule.displayfield and theBindingLoaderpure-data loader (not wired in apcore-mcp; this project does not load binding YAML directly). ExecutionRouter.handle_callresponsecontentitem type widened fromlist[dict[str, str]]tolist[dict[str, Any]]to carry the optional_metafield. The factory translates this to MCPTextContent.metaon wire.MCPServerFactory.register_handlersgains optionalasync_bridgeanddescriptor_lookupkwargs. Backward-compatible: when omitted, behavior is unchanged.
Added
- W3C Trace Context propagation —
ExecutionRouternow parses_meta.traceparenton inboundtools/callrequests and seeds the apcoreContextwith the extractedTraceParent. Responses carry_meta.traceparent(perTextContent.meta) built fromTraceContext.inject(context), letting MCP clients correlate trace chains across module boundaries. Relies on apcore 0.19's strict validation inContext.create(trace_parent=...)(all-zero/all-f trace ids are regenerated with a WARN). - Async Task Bridge (F-043) — new
apcore_mcp.server.async_task_bridge.AsyncTaskBridgewraps apcore'sAsyncTaskManager. Modules whose descriptor carriesmetadata.async == Trueorannotations.extra["mcp_async"] == "true"are routed toAsyncTaskManager.submit()and return an immediate{"task_id", "status": "pending"}envelope. Four reserved MCP meta-tools are registered:__apcore_task_submit,__apcore_task_status,__apcore_task_cancel,__apcore_task_list. Progress fan-out is available via_meta.progressToken(bound per task).MCPServerFactory.build_toolnow rejects any module whose id starts with__apcore_. Enable/disable viaAPCoreMCP(async_tasks=...)orserve(async_tasks=...)(default on). Tuning knobs:async_max_concurrent,async_max_tasks. - Observability auto-wiring —
serve(observability=True)/APCoreMCP(observability=True)instantiateapcore.observability.MetricsCollector+MetricsMiddlewareandUsageCollector+UsageMiddlewareon the Executor and expose/{explorer_prefix}/api/usage(and/api/usage/{module_id}) returningModuleUsageSummary/ModuleUsageDetailJSON. Themetrics_collector=Truesentinel auto-provisions only the metrics middleware (no usage tracking). A user-suppliedMetricsExporterobject continues to work unchanged (back-compat). --observabilityCLI flag — toggles metrics + usage middleware and usage routes.- isinstance-based error dispatch in
adapters/errors.py—TaskLimitExceededError,DependencyNotFoundError, andDependencyVersionMismatchErrorare dispatched viaisinstancechecks against the apcore 0.19 error classes, not duck-typed codes. - Expanded
ModuleAnnotationssurfacing inAnnotationMapper.to_description_suffix:cache_ttl,cache_key_fields, andpagination_stylenow appear in the description annotation block when non-default. Aligns with apcore 0.19's 12-fieldModuleAnnotations. DEFAULT_ANNOTATIONSinadapters/annotations.pyextended withcache_ttl=0,cache_key_fields=None, andpagination_style="cursor"to match apcore 0.19 defaults.- New error codes in
constants.ERROR_CODESandErrorMapper: DEPENDENCY_NOT_FOUND— raised byresolve_dependenciesfor missing required deps (replaces priorModuleLoadErrorpath per PROTOCOL_SPEC §5.15.2).DEPENDENCY_VERSION_MISMATCH— raised when a declaredversionconstraint is unsatisfied.TASK_LIMIT_EXCEEDED— raised byAsyncTaskManager.submitat capacity. Mapped withretryable: True.VERSION_CONSTRAINT_INVALID— raised on malformed version constraint strings.BINDING_SCHEMA_INFERENCE_FAILED— replaces the deprecatedBINDING_SCHEMA_MISSINGcode for auto-schema inference failures.BINDING_SCHEMA_MODE_CONFLICT,BINDING_STRICT_SCHEMA_INCOMPATIBLE,BINDING_POLICY_VIOLATION— parse-time binding validation errors per DECLARATIVE_CONFIG_SPEC.
Notes
- The
displayoverlay resolution inserver/factory.pyalready consumesmetadata["display"]["mcp"](alias / description / guidance) as produced byDisplayResolver; no changes needed for the 0.19 canonicalDisplayOverlayshape. - The apcore-toolkit
BindingLoaderwas not wired in: apcore-mcp does not load.binding.yamlfiles directly. Registry-bound loads continue to flow through apcore's ownBindingLoaderinside the upstream SDK. - Async task bridge is in-memory only; tasks do not survive server restart (matches apcore semantics).
- Meta-tool names use the reserved
__apcore_prefix; user-registered modules with this prefix are now rejected atbuild_tooltime to prevent shadowing. - Usage endpoints are only mounted when Explorer is enabled; headless stdio deployments continue to have no HTTP surface.
Cross-language sync (deferred-modules round, 2026-04-28)
- Dependency bump:
mcp-embedded-ui >= 0.4.0(was>= 0.3.1). The new release shipsPOST /tools/{name}/validate(F7) — read-only schema validation, ungated byallow_executeorauth_hook. The route flows automatically throughcreate_explorer_mount. Resolves EUI-1. - JWT-1 —
Authenticator.authenticateis nowasync. Existing sync implementations continue to work via the newapcore_mcp.auth.protocol.call_authenticator(auth, headers)helper, which inspects the return value and awaits if it's a coroutine. Aligns with TS+Rust on the unified(headers: HeaderMap) -> Awaitable<Identity | None>contract. Tests forJWTAuthenticatorare nowasync def. - TM-4 — transport-disconnect cancellation forwarding.
TransportManager.set_async_task_bridge(bridge)matches TSsetAsyncTaskBridgeand Rustset_cancel_handler. The transport scopes a per-connection session id via the newtransport_session_varContextVar;factory.handle_call_toolforwards it assession_keytobridge.submit(...), and on transport teardown the manager callsbridge.cancel_session_tasks(session_id). Wired automatically byserve(),async_serve(), andAPCoreMCP.serve/async_servewhen an async bridge is present. 6 regression tests. - EB-2 — adapter-hook kwargs.
serve()andasync_serve()acceptschema_converter,annotation_mapper,error_mapperkwargs that override the factory's built-in adapters. - EM-1 —
McpErrorFormattercanonical class name. Added as the preferred PascalCase name (matches TS+Rust). The pre-existingMCPErrorFormatter(all-caps) is kept as a backwards-compatible alias. Both are exported fromapcore_mcpandapcore_mcp.adapters. - EM-3 —
userFixable=truestamp.ErrorMappernow hardcodesuserFixable: trueforDEPENDENCY_NOT_FOUND,DEPENDENCY_VERSION_MISMATCH,VERSION_CONSTRAINT_INVALID, and the fourBINDING_*codes (matches TS). apcore 0.19's error classes don't yet setuser_fixable=truethemselves, so the bridge stamps the hint to give MCP clients a consistent self-healing signal. 9 regression tests. - MID-5 —
ModuleIDNormalizer.try_denormalize. New bijection-guarded variant validates the dash→dot-replaced result againstMODULE_ID_PATTERN, returningNonefor inputs that aren't valid pre-images ofnormalize. Plaindenormalizestays lenient. 8 regression tests. - JWT-2 — case-insensitive
Authorizationheader lookup.JWTAuthenticator.authenticatenow tries bothheaders["authorization"]andheaders["Authorization"]. ASGI lower-cases header names but direct callers may pass the capitalised form; RFC 7230 §3.2 mandates case-insensitive header names. Matches TS+Rust behaviour. 1 regression test. - AM-L1 — F-041 annotation extras format aligned with TS+Rust.
mcp_*extras are now appended after the[Annotations: ...]block separated by a single newline (was each extra as its own\n\n-separated section). 1 regression test. - TC-011 integration tests added in
tests/explorer/test_explorer.py::TestTC011Validatepinning the/validatewire-up.
Release 0.13.0
Added
- Pipeline Strategy Selection (F-036) —
serve(strategy=)parameter and CLI--strategyflag with 5 presets: standard, internal, testing, performance, minimal. - Tool Output Redaction (F-038) —
serve(redact_output=True)appliesredact_sensitive()to tool output before MCP serialization. Enabled by default. - Pipeline Observability (F-037) —
serve(trace=True)enablescall_async_with_trace()for per-step pipeline timing in responses. - Tool Preflight Validation (F-039) —
ExecutionRouter.validate_tool()for dry-run validation viaExecutor.validate(). - YAML Pipeline Configuration (F-040) — Config Bus
mcp.pipelinesection for declarative pipeline customization. - Annotation Metadata Passthrough (F-041) —
ModuleAnnotations.extrakeys prefixed withmcp_flow to tool descriptions. - 4 new error mappings —
ConfigEnvMapConflictError,PipelineAbortError,StepNotFoundError,VersionIncompatibleError. - RegistryListener wired to
serve(dynamic=True)— dynamic tool registration now operational.
Changed
- Dependency bump:
apcore >= 0.17.1(was>= 0.15.1). - Pipeline v2 alignment: 11-step pipeline,
call_chain_guardrename, middleware before input validation.
Release 0.12.0
Added
- Config Bus namespace registration (F-033) — Registers
mcpnamespace with apcore Config Bus (APCORE_MCPenv prefix). MCP configuration (transport, host, port, auth, explorer) can be managed via unifiedapcore.yaml. - Error Formatter Registry integration (F-034) —
MCPErrorFormatterregistered with apcore'sErrorFormatterRegistry, formalizing MCP error formatting into the shared protocol. - Dot-namespaced event constants (F-035) —
APCORE_EVENTSdict with canonical event type names from apcore 0.15.0 (§9.16). - 6 new error code mappings —
CONFIG_NAMESPACE_DUPLICATE,CONFIG_NAMESPACE_RESERVED,CONFIG_ENV_PREFIX_CONFLICT,CONFIG_MOUNT_ERROR,CONFIG_BIND_ERROR,ERROR_FORMATTER_DUPLICATE.
Changed
- Dependency bump: requires
apcore >= 0.15.1(was>= 0.14.0) for Config Bus (§9.4), Error Formatter Registry (§8.8), and dot-namespaced event types (§9.16).
Release 0.11.0
Added
- Display overlay in
build_tool()(§5.13) — MCP tool name, description, and guidance now sourced frommetadata["display"]["mcp"]when present. - Tool name:
metadata["display"]["mcp"]["alias"](pre-sanitized byDisplayResolver, already[a-zA-Z_][a-zA-Z0-9_-]*and ≤ 64 chars). - Tool description:
metadata["display"]["mcp"]["description"], withguidanceappended as\n\nGuidance: <text>when set. - Falls back to raw
module.name/module.descriptionwhen no display overlay is present.
Changed
- Dependency bump: requires
apcore-toolkit >= 0.4.0forDisplayResolver.
Tests
TestBuildToolDisplayOverlay(6 tests): MCP alias used as tool name, MCP description used, guidance appended, surface-specific override wins, fallback to scanner values when no overlay.
Release 0.10.1
Changed
- Rebrand: aipartnerup → aiperceivable
Release 0.10.0
Changed
- BREAKING:
output_formatterdefault changed toNone:APCoreMCPno longer defaults toapcore_toolkit.to_markdown. Results are now serialized as raw JSON by default. To restore Markdown formatting, passoutput_formatter=to_markdownexplicitly (requiresapcore-toolkit). - Dependency bump: Requires
apcore>=0.13.0(was>=0.9.0). Picks up new annotation fields (cacheable,paginated,cache_ttl,cache_key_fields,pagination_style) andExecutionCancelledErrornow extendingModuleError. - Annotation description suffix:
AnnotationMapper.to_description_suffix()now includescacheableandpaginatedwhen set to non-default values.
Removed
apcore-toolkitdependency: Removed frompyproject.tomldependencies.apcore-toolkitis no longer required to useapcore-mcp. Users who want Markdown formatting can install it separately and passto_markdownas theoutput_formatter.
Release 0.9.0
Added
async_serve()context manager: New public API for embedding the MCP server into a larger ASGI application. Returns aStarletteapp viaasync 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. Supportsextra_routesandmiddlewareinjection.ExecutionCancelledErrorhandling:ErrorMappernow maps apcore'sExecutionCancelledErrorto a safeEXECUTION_CANCELLEDresponse withretryable=True. Internal cancellation details are never leaked.- New error codes:
VERSION_INCOMPATIBLE,ERROR_CODE_COLLISION, andEXECUTION_CANCELLEDadded toERROR_CODESconstants. - 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 upPreflightResult, 11-step executor pipeline, retry middleware, error code registry, and more. - Preflight validation aligned with apcore 0.9.0:
ExecutionRouternow passes the router-builtContext(with identity, callbacks) toExecutor.validate(), enabling accurate ACL and call-chain preflight checks. Error formatting handles all threePreflightResulterror 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:
AuthMiddlewarenow attempts identity extraction on exempt paths. Valid tokens populateauth_identity_vareven when auth is not required, allowing downstream handlers to use identity when available.
Release 0.8.1
Release version 0.8.1
See CHANGELOG.md for details.
Release 0.8.0
Added
- Approval system (F-028): Full runtime approval support via
ElicitationApprovalHandlerthat bridges MCP elicitation to apcore's approval system. Newapproval_handlerparameter onserve(). Supportsrequest_approval()andcheck_approval()methods. ElicitationApprovalHandler: Presents approval requests to users via MCP elicitation. Maps elicit actions (accept/decline/cancel) toApprovalResultstatuses.- CLI
--approvalflag with choices:elicit,auto-approve,always-deny,off(default). - Approval error codes:
APPROVAL_DENIED,APPROVAL_TIMEOUT,APPROVAL_PENDINGadded toERROR_CODES. - Enhanced error responses with AI guidance:
ErrorMappernow extractsretryable,ai_guidance,user_fixable, andsuggestionfields from apcoreModuleErrorand includes non-None values in error response dicts.ExecutionRouterappends AI guidance as structured JSON to error text content for AI agent consumption. - AI intent metadata in tool descriptions:
MCPServerFactory.build_tool()readsdescriptor.metadatafor AI intent keys (x-when-to-use,x-when-not-to-use,x-common-mistakes,x-workflow-hints) and appends them to tool descriptions for agent visibility. - Streaming annotation:
DEFAULT_ANNOTATIONSnow includesstreamingfield.AnnotationMapper.to_description_suffix()includesstreaming=truewhen the annotation is set.
Changed
APPROVAL_TIMEOUTauto-retryable:ErrorMappersetsretryable=TrueforAPPROVAL_TIMEOUTerrors, signaling to AI agents that the operation can be retried.APPROVAL_PENDINGincludesapproval_id:ErrorMapperextractsapproval_idfrom error details forAPPROVAL_PENDINGerrors.- Error text content enriched: Router error text now includes AI guidance fields as a structured JSON appendix when present, enabling AI agents to parse retry/fix hints.
Release 0.7.0
Added
- JWT Authentication (F-027): Optional JWT-based authentication for HTTP transports (
streamable-http,sse). Newauthenticatorparameter onserve()andMCPServer. Validates Bearer tokens, maps JWT claims to apcoreIdentity, and injects identity intoContextfor ACL enforcement. JWTAuthenticator: Configurable JWT validation withClaimMappingfor flexible claim-to-Identity field mapping. Supports custom algorithms, audience, issuer, and required claims.AuthMiddleware: ASGI middleware that bridges HTTP authentication to MCP handlers viaContextVar[Identity]. Supportsexempt_paths(exact match) andexempt_prefixes(prefix match) for unauthenticated endpoints.AuthenticatorProtocol:@runtime_checkableprotocol for custom authentication backends.- Permissive auth mode:
require_auth=Falseparameter onserve()andMCPServerallows unauthenticated requests to proceed without identity instead of returning 401. exempt_pathsparameter:serve()andMCPServeracceptexempt_pathsfor exact-path authentication bypass (e.g.{"/health", "/metrics"}).- CLI JWT flags:
--jwt-secret,--jwt-algorithm,--jwt-audience,--jwt-issuerarguments for enabling JWT authentication from the command line. - CLI
--jwt-key-file: Read JWT verification key from a PEM file (e.g. RS256 public key). Takes priority over--jwt-secretandJWT_SECRETenv var. - CLI
--jwt-require-auth/--no-jwt-require-auth: Toggle permissive auth mode from the command line. - CLI
--exempt-paths: Comma-separated list of paths exempt from authentication. JWT_SECRETenv var fallback: CLI resolves JWT key in priority order:--jwt-key-file>--jwt-secret>JWT_SECRETenvironment variable.- Explorer Authorization UI: Swagger-UI-style Authorization input field in the Tool Explorer. Paste a Bearer token to authenticate tool execution requests. Generated cURL commands automatically include the Authorization header.
- Explorer auth enforcement: When
authenticatoris set, tool execution via the Explorer returns 401 Unauthorized without a valid Bearer token. The Explorer UI displays a clear error message prompting the user to enter a token. - Auth failure audit logging:
AuthMiddlewareemits aWARNINGlog with the request path on authentication failure. extract_headers()utility: Public helper to extract ASGI scope headers as a lowercase-key dict. Exported fromapcore_mcp.auth.- JWT authentication example:
examples/run.pysupportsJWT_SECRETenvironment variable to demonstrate JWT authentication with a sample token. - PyJWT dependency: Added
PyJWT>=2.0to project dependencies.
Changed
- Explorer UI layout: Redesigned from a bottom-panel layout to a Swagger-UI-style inline accordion. Each tool expands its detail, schema, and "Try it" section directly below the tool name. Only one tool can be expanded at a time. Detail is loaded once on first expand and cached.
- AuthMiddleware
exempt_prefixes: Addedexempt_prefixesparameter for prefix-based path exemption. Explorer paths are automatically exempt when bothexplorerandauthenticatorare enabled, so the Explorer UI always loads. extract_headersrefactored: Moved from privateAuthMiddleware._extract_headers()to module-levelextract_headers()function for reuse in Explorer routes.