Open
Conversation
Dependency ReviewThe following issues were found:
License Issuesuv.lock
OpenSSF Scorecard
Scanned Files
|
biswapm
added a commit
that referenced
this pull request
Apr 12, 2026
Replace separate _attach_dev_tokens() / _attach_per_audience_tokens(auth, handler, ctx) with a unified _attach_per_audience_tokens(servers, acquire: TokenAcquirer) that accepts a pluggable async callable — aligning with Node.js PR #226. - Add TokenAcquirer type alias: Callable[[MCPServerConfig, str], Awaitable[Optional[str]]] - Add _create_dev_token_acquirer(): reads BEARER_TOKEN_<MCP_SERVER_NAME_UPPER> (now using mcp_server_name, not mcp_server_unique_name, to match Node.js) with BEARER_TOKEN fallback - Add _create_obo_token_acquirer(): performs OBO exchange per unique audience scope - Remove _attach_dev_tokens() entirely - list_tool_servers(): dev branch uses dev acquirer; prod branch uses OBO acquirer when auth context present; both paths go through the unified _attach_per_audience_tokens() - Update TestAttachPerAudienceTokens tests to use _create_obo_token_acquirer() helper
gwharris7
previously approved these changes
Apr 13, 2026
31594a6 to
2678c42
Compare
gwharris7
pushed a commit
that referenced
this pull request
Apr 16, 2026
* Support V1/V2 per-audience token acquisition for MCP servers
V2 MCP servers require individual OAuth tokens scoped to their own
audience GUID rather than the shared ATG token used by V1 servers.
- Add audience, scope, publisher, headers fields to MCPServerConfig
- Add resolve_token_scope_for_server() to determine OAuth scope:
V2 servers (GUID audience) get <audience>/.default, V1 servers
fall back to the shared ATG scope
- Add _attach_per_audience_tokens() to McpToolServerConfigurationService:
acquires one token per unique audience (cached), attaches Authorization
header to each server config after discovery
- Extend list_tool_servers() to accept optional authorization context;
calls _attach_per_audience_tokens() when provided
- Preserve audience/scope/publisher fields in manifest and gateway parsers
- Update McpToolRegistrationService to pass auth context to
list_tool_servers() and use per-server headers instead of a single
shared token
- Update tests to reflect the new header flow
All V1 agents continue working unchanged (audience defaults to None,
falls back to ATG scope).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Extend V1/V2 per-audience token support to all SDK extensions
- Bump gateway discovery endpoint to /agents/v2/{id}/mcpServers
- Update resolve_token_scope_for_server() to use explicit scope when
present (e.g. Tools.ListInvoke.All → {audience}/{scope}), falling
back to {audience}/.default for pre-consented scopes when null
- Fix api:// V2 audience handling — only ATG AppId in api:// URI form
is treated as V1; all other api:// audiences are correctly V2
- Pass authorization/auth_handler_name/turn_context to list_tool_servers
in OpenAI, Semantic Kernel, and Google ADK extensions so
_attach_per_audience_tokens runs for all frameworks (was previously
only wired in AgentFramework extension)
- Replace shared single-token header injection with per-server header
merge ({**base_headers, **server.headers}) in all three extensions
- Add tests for resolve_token_scope_for_server (all V1/V2/null/api://
scenarios), _attach_per_audience_tokens (V1 dedup, V2 per-audience,
mixed, error cases, header preservation)
Backward compatible: V1 agents (null/ATG audience) continue using the
shared ATG token unchanged. Row 3 (New blueprint + Old SDK) is by
design not supported — upgrade to this SDK is the migration path.
* Extend V1/V2 per-audience token support to all SDK extensions
- Pass authorization/auth_handler_name/turn_context to list_tool_servers
in OpenAI and Semantic Kernel extensions so _attach_per_audience_tokens
runs for all frameworks (Google ADK already staged in prior commit)
- Replace shared single-token header injection with per-server header
merge ({**base_headers, **server.headers}) in OpenAI and SK extensions
- Use explicit scope for V2 token resolution: {audience}/{scope} when
scope is present, {audience}/.default as pre-consented fallback
- Fix api:// V2 audience handling — only ATG AppId in api:// URI form
is treated as V1; all other api:// audiences are correctly V2
- Add comprehensive tests for resolve_token_scope_for_server covering
all V1/V2/null/api:// scenarios including test env audience handling
- Add CHANGELOG entry for microsoft-agents-a365-tooling package
Backward compatible: V1 agents (null/ATG audience) continue using the
shared ATG token unchanged. V2 blueprint + old SDK is by design not
supported — upgrade to this SDK is the migration path.
* Fix manifest/gateway parsing and add local dev per-server token support
- Normalize "default" audience → None and "null" scope → None in both
_parse_manifest_server_config() and _parse_gateway_server_config() so
Dataverse-style servers are correctly treated as V1 (shared ATG token)
instead of triggering a bogus V2 token exchange
- Add "default" guard to resolve_token_scope_for_server() as defense-in-depth
- Fall back to mcpServerName when mcpServerUniqueName is absent from the
manifest or gateway response
- Add _attach_dev_tokens() — reads BEARER_TOKEN_<SERVER_UNIQUE_NAME> and
BEARER_TOKEN env vars written by `a365 develop get-token` and attaches
per-server Authorization headers during local dev manifest loading;
no-op in production where OBO via _attach_per_audience_tokens() is used
* fixed formatting
* mcp_tool_registration_service.py — threaded auth, auth_handler_name, context from add_tool_servers_to_agent into _get_mcp_tool_definitions_and_resources, which now passes them as keyword args to list_tool_servers() so _attach_per_audience_tokens() runs for V2 servers. Header injection reads server.headers (per-audience token) with fallback to the shared auth_token.
test_mcp_tool_registration_service.py — 7 tests covering: auth context forwarding, per-audience token used over shared token, fallback when headers empty, no double Bearer prefix, User-Agent header, and per-server isolation across multiple servers.
* Dev mode (manifest): _attach_dev_tokens() runs, OBO never fires regardless of what auth context the extension passes
Prod mode (gateway): OBO runs only when auth context is present
* Refactor token acquisition to TokenAcquirer strategy pattern
Replace separate _attach_dev_tokens() / _attach_per_audience_tokens(auth, handler, ctx)
with a unified _attach_per_audience_tokens(servers, acquire: TokenAcquirer) that accepts
a pluggable async callable — aligning with Node.js PR #226.
- Add TokenAcquirer type alias: Callable[[MCPServerConfig, str], Awaitable[Optional[str]]]
- Add _create_dev_token_acquirer(): reads BEARER_TOKEN_<MCP_SERVER_NAME_UPPER> (now using
mcp_server_name, not mcp_server_unique_name, to match Node.js) with BEARER_TOKEN fallback
- Add _create_obo_token_acquirer(): performs OBO exchange per unique audience scope
- Remove _attach_dev_tokens() entirely
- list_tool_servers(): dev branch uses dev acquirer; prod branch uses OBO acquirer when
auth context present; both paths go through the unified _attach_per_audience_tokens()
- Update TestAttachPerAudienceTokens tests to use _create_obo_token_acquirer() helper
* updated prod endpoint
* Add x-ms-correlation-id header to gateway requests
Propagates the inbound activity ID (turn_context.activity.id) as the
x-ms-correlation-id header on all tooling gateway requests, falling back
to a freshly generated UUID4 when no TurnContext is available.
* Add MCP V1/V2 per-audience token acquisition and dev token flow
- McpToolServerConfigurationService: add _create_dev_token_acquirer() and
_create_obo_token_acquirer() TokenAcquirer factories; _attach_per_audience_tokens()
now accepts a TokenAcquirer to decouple token strategy from header attachment
- Strip existing Bearer prefix (case-insensitive) from BEARER_TOKEN* env vars in
dev acquirer to prevent doubled Authorization headers
- Replace manual MCPServerConfig reconstruction with dataclasses.replace() in
_attach_per_audience_tokens() so future fields are carried forward automatically
- Merge _parse_manifest_server_config() and _parse_gateway_server_config() into
single _parse_server_config() (shared JSON schema between both sources)
- utility.py: add is_development_environment() with 4-level env var resolution
(PYTHON_ENVIRONMENT > ENVIRONMENT > ASPNETCORE_ENVIRONMENT > DOTNET_ENVIRONMENT);
normalize audience to lowercase in resolve_token_scope_for_server() to ensure
consistent V1/V2 classification regardless of GUID casing
- OpenAI, Semantic Kernel, Google ADK, Agent Framework extensions: pass auth context
to list_tool_servers(), skip token exchange in dev mode, add auth fallback header
when no per-server token is present; fix typing.Any usages
- CHANGELOG: correct stale method names (_attach_dev_tokens -> _create_dev_token_acquirer,
_parse_*_server_config -> _parse_server_config) and env var naming
(BEARER_TOKEN_<SERVER_UNIQUE_NAME> -> BEARER_TOKEN_<MCP_SERVER_NAME_UPPER>)
- Tests: add coverage for Bearer prefix stripping (4 casing variants), raw token
passthrough, per-server env var stripping; fix test fixtures for merged parse
method and json() mock pattern
* Migrate agent-framework to GA 1.0.1; revert google-adk to 1.14.1
- Replace agent-framework-azure-ai (pre-release only) with agent-framework >= 1.0.0
in root pyproject.toml constraint-dependencies and agentframework extension package;
agent-framework-core is now pinned to >= 1.0.0 as a separate explicit constraint
- agent-framework 1.0.1 (GA) bundles Azure OpenAI support directly in OpenAIChatClient
via credential/azure_endpoint params; AzureOpenAIChatClient no longer exists
- Update mcp_tool_registration_service.py (agentframework extension):
- Import HistoryProvider (renamed from BaseHistoryProvider in GA)
- Replace Union[OpenAIChatClient, AzureOpenAIChatClient] with OpenAIChatClient
- Remove agent_framework.azure import; remove unused Union import
- Update test fixtures and docstrings to reflect renamed types
- Revert google-adk constraint to >= 1.0.0 (from >= 1.28.1):
google-adk >= 1.28.1 pins opentelemetry-api < 1.39.0 while
agent-framework-core >= 1.0.0 requires opentelemetry-api >= 1.39.0;
no compatible intersection exists. CVE-2026-4810 (GHSA-rg7c-g689-fr3x)
affects ADK Web server mode only; this SDK uses google-adk purely as a library
and does not expose ADK Web, so the vulnerability is not applicable.
* Fix ruff formatting in semantickernel mcp_tool_registration_service
Collapse multi-line logger.info() call to single line to satisfy
ruff format --check (line fits within 100-char limit).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Remove cross-platform references from comments and docstrings
- mcp_tool_server_configuration_service.py: replace 'mirrors Node.js behaviour'
and 'aligns with Node.js' with self-contained descriptions
- utility.py: rephrase is_development_environment() docstring to describe env var
precedence without mentioning .NET (ASPNETCORE_ENVIRONMENT and DOTNET_ENVIRONMENT
variable names are kept, only the platform labels are removed)
- test_mcp_server_configuration.py: remove reference to non-existent
MCP_PLATFORM_APP_ID env var in test section header and docstring; replace with
accurate guidance pointing to MCP_PLATFORM_AUTHENTICATION_SCOPE /
MCP_PLATFORM_ENDPOINT as the actual configurable inputs
* Add conftest.py to guard agent_framework imports in CI unit tests
In some CI environments (Linux Python 3.12) agent_framework loads but
its top-level namespace is missing RawAgent/MCPStreamableHTTPTool due to
a partial circular-import during pytest collection. The new conftest.py
is loaded by pytest before test files in this directory tree are imported,
and adds MagicMock stubs for any absent names so the module-level
`from agent_framework import ...` in the production service succeeds.
* Strip Bearer prefix in fallback auth header across all three extensions
The agentframework, semantickernel, and openai extensions unconditionally
prepended BEARER_PREFIX to auth_token in the fallback Authorization
header, producing "Bearer Bearer <token>" when callers already included
the prefix. Align with the azureaifoundry extension by applying the
same case-insensitive startswith guard before prepending the prefix.
* Fix CI import failures and missing is_dev guard
agent_framework.openai causes a circular-import chain under Python 3.12
on Linux: openai.__getattr__ lazily imports agent_framework_openai, which
eventually does `from . import __version__` on the still-initialising
agent_framework package. Move OpenAIChatClient under TYPE_CHECKING so the
import is never executed at runtime.
Also add the missing is_development_environment() guard to the Azure AI
Foundry extension's add_tool_servers_to_agent, matching the pattern used
by the other three extensions: dev mode skips token exchange and uses ""
as the agentic_app_id for manifest-based discovery.
* Add dev-mode warning for V2 servers using shared token, add legacy-path tests
_create_dev_token_acquirer now emits a WARNING when BEARER_TOKEN is the
only token available but the server requires a different audience scope
(V2 server). The warning names the per-server env var the caller should
set to avoid a 401.
Also adds two unit tests that verify the existing legacy production-path
guard: a hard error is raised when list_tool_servers is called without
auth context and V2 servers are discovered, and the call succeeds when
only V1 servers are present.
* Fix Bearer double-prefix in googleadk auth fallback
googleadk unconditionally prepended 'Bearer' in the shared-token
fallback path, producing 'Bearer Bearer <token>' when the caller
already included the prefix. Apply the same guard used in the other
three extensions.
---------
Co-authored-by: pmohapatra <biswapm@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Bumps [uv](https://github.com/astral-sh/uv) from 0.11.2 to 0.11.6. - [Release notes](https://github.com/astral-sh/uv/releases) - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md) - [Commits](astral-sh/uv@0.11.2...0.11.6) --- updated-dependencies: - dependency-name: uv dependency-version: 0.11.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
2678c42 to
63ab7f5
Compare
Contributor
Author
|
Dependabot can't resolve your Python dependency files. Because of this, Dependabot cannot update this pull request. |
1 similar comment
Contributor
Author
|
Dependabot can't resolve your Python dependency files. Because of this, Dependabot cannot update this pull request. |
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 free
to 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.
Bumps uv from 0.11.2 to 0.11.6.
Release notes
Sourced from uv's releases.
... (truncated)
Changelog
Sourced from uv's changelog.
... (truncated)
Commits
6595080Bump version to 0.11.6 (#18948)7983c7aValidate and heal RECORD during installation (#18943)b38439bAvoiduv cache cleanerrors due to Win32 path normalization (#18856)a0e461aDo not remove files outside the venv on uninstall (#18942)95eaa68Bump version to 0.11.5 (#18930)f6d67d5Improve certificate loading error messages (#18924)39b83c3Addexclude-newerto[[tool.uv.index]](#18839)7924ba5uv audit: add context/warnings for ignored vulnerabilities (#18905)a352ce0Remove the legacy PIP_COMPATIBILITY.md redirect file (#18928)33b6338Normalize persisted fork markers before lock equality checks (#18612)