Skip to content

[draft] Implement MCP connection gating#260

Draft
gwharris7 wants to merge 15 commits into
mainfrom
gwharris7/mcp-connection-gating
Draft

[draft] Implement MCP connection gating#260
gwharris7 wants to merge 15 commits into
mainfrom
gwharris7/mcp-connection-gating

Conversation

@gwharris7

Copy link
Copy Markdown
Contributor

This pull request introduces connection-readiness gating to the MCP tooling layer, ensuring that MCP servers are only used when all required downstream connections are established. If connections are missing, a new McpConnectionsRequiredError is raised, allowing the agent to prompt the user to complete setup before proceeding. The changes also extend the MCP server configuration model with new connection-related fields and update the gateway response parsing logic to handle connection metadata. Comprehensive documentation and unit tests for the new error are included.

Connection readiness enforcement:

  • Added connection-readiness gating to McpToolServerConfigurationService.list_tool_servers(). When the tooling gateway reports an aggregate connectivityStatus of "Pending", the method raises McpConnectionsRequiredError with details for user prompting. Dev-mode and legacy gateway responses are not gated. [1] [2] [3]

New exception and model updates:

  • Introduced McpConnectionsRequiredError exception (exported from microsoft_agents_a365.tooling) with missing_connections_url, connectivity_status, and server_names attributes, and added corresponding unit tests. [1] [2] [3] [4] [5]
  • Extended MCPServerConfig with id, all_connections_url, missing_connections_url, and connectivity_status fields, parsed from the per-server gateway payload. [1] [2] [3]

Gateway response handling:

  • Added internal McpDiscoveryResult dataclass; _parse_gateway_response() and _load_servers_from_gateway() now return this to carry aggregate connection metadata alongside the server list, while public API remains unchanged. [1] [2] [3] [4] [5] [6] [7] [8] [9]

Documentation:

  • Updated design documentation to describe connection gating, error handling, and usage of the new exception in agent turn handlers.

Testing and imports:

  • Added imports and test coverage for McpConnectionsRequiredError in relevant test modules. [1] [2]

gwharris7 and others added 13 commits June 8, 2026 12:34
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add parsing of four new per-server connection fields from JSON:
- id: Server identifier (GUID)
- allConnectionsUrl: Connection info endpoint
- missingConnectionsUrl: Missing connections endpoint
- connectivityStatus: Current connectivity status

Fields are extracted from camelCase JSON keys and stored as optional
string attributes on MCPServerConfig. When absent (manifest elements),
all four fields default to None for backward compatibility.

Closes Task 3: Parse per-server connection fields in _parse_server_config

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Result

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…edError

The user-facing connection error now carries only missing_connections_url,
connectivity_status, and server_names. The aggregate allConnectionsUrl is no
longer surfaced on the exception (still parsed onto MCPServerConfig).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

gwharris7 and others added 2 commits June 15, 2026 14:02
Move connection-readiness gating out of the core tooling package and into the
Agent Framework extension. Core now only parses the per-server schema fields
(connectivityStatus, allConnectionsUrl, missingConnectionsUrl) onto each
MCPServerConfig and never gates or raises.

Core:
- Remove the internal McpDiscoveryResult dataclass, the deprecated
  _enforce_connection_readiness method, and the _CONNECTIVITY_READY constant.
- _parse_gateway_response/_load_servers_from_gateway return List[MCPServerConfig]
  again; response-level aggregate fields are ignored.
- Delete exceptions.py and drop McpConnectionsRequiredError from the public API.

Extension (agentframework):
- Own McpConnectionsRequiredError (all_connections_url, connectivity_status,
  server_names) and export it from the package root.
- Gate at registration time in add_tool_servers_to_agent: when any discovered
  server is Pending, raise before building the agent so the turn handler can
  prompt the user with all_connections_url. Replaces the per-server FunctionTool
  placeholder mechanism.

Raising at construction time (not inside a FunctionTool) is required because
Agent Framework's tool-call loop swallows exceptions raised inside a tool and
returns 'Error: Function failed.' to the model, which would drop the setup URL.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Switch the agentframework extension from blocking gating (raise
McpConnectionsRequiredError before building the agent when any server is Pending)
to non-blocking per-server gating:

- Ready servers (and legacy sources with no connectivityStatus) are wired as live
  MCPStreamableHTTPTool instances, unchanged.
- A Pending server is registered as a single placeholder FunctionTool named after
  the server (max_invocations=1). When the model invokes it, the placeholder
  RETURNS a static setup message including missing_connections_url (fallback
  all_connections_url) for the model to relay. The agent is always built and Ready
  tools stay usable; the user is only prompted about connections if their request
  actually needs the Pending server.

The placeholder returns the message rather than raising it: Agent Framework
swallows exceptions raised inside a tool and converts UserInputRequiredException
into tool-result content, so neither reaches the turn handler. Returning the text
is the only way to surface the URL through the model.

McpConnectionsRequiredError stays exported for developers who want custom blocking
gating; it now carries missing_connections_url, connectivity_status, server_names,
and shares the new format_mcp_connections_required_message helper with the
placeholder so the message wording has a single source of truth.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant