Skip to content

## register-external-mcp-server reports "registered successfully" but the registration is not correct: declared tools are never verified, the result is not observable from the CLI, and the backing apps fail to load in the admin center #462

Description

Description

a365 develop-mcp register-external-mcp-server prints

MCP server 'ext_Foo' has been registered successfully.
Please ask your tenant admin to approve MCP server 'ext_Foo'.

…but "successfully" overstates what actually happened. The command's idea of a correct
registration diverges from reality in three ways:

  1. Declared tools are never validated against the live server. The CLI prints
    WARNING: Tool names must exactly match the names exposed by the remote MCP server
    but does not call the endpoint's tools/list to check — so a registration with wrong
    tool names is reported as fully successful and only fails silently at invocation time.
  2. The result is not observable through the CLI. There is no
    register … --verify / get-server and develop-mcp list-servers does not return
    externally-registered NoAuth servers, so there is no CLI way to confirm the registration
    landed or read its approval/consent state.
  3. A reported-success registration can be broken in the portal. Immediately after the
    success message, the M365 admin center shows
    We couldn't load the apps backing this MCP server. Try again later.
    for the just-registered server, even though the three backing Entra apps exist and are
    healthy (verified via Graph). The CLI returns success before the registration is actually
    consistent/usable end-to-end.

Environment

CLI Microsoft.Agents.A365.DevTools.Cli 1.1.214+90c444832f (also 1.1.206+091d51d7db)
OS / shell Windows 11 26200 / PowerShell 7
Auth type NoAuth, remote streamable-HTTP server (https://mcp.context7.com/mcp)
Tenant Frontier Preview Program; Agent 365 SP ea9ffc3e-************-234d7c7565c1 provisioned & enabled
Approver signed-in user holds AI Administrator (role template d2562ede-74db-457e-a7b6-544e236ebb61)
Date 2026-06-16

Reproduction

  1. Register any reachable NoAuth streamable-HTTP server, e.g.:
    a365 develop-mcp register-external-mcp-server -f registration.json
    # registration.json: serverName ext_Foo, authType NoAuth, serverUrl https://…/mcp,
    #                     tools [{name: "resolve-library-id"}, {name: "query-docs"}]
    CLI prints … has been registered successfully.
  2. Try to confirm it from the CLI:
    a365 develop-mcp list-servers -e <any-dataverse-env-id>
    # → only the built-in msdyn_DataverseMCPServer / msdyn_DataversePreviewMCPServer.
    #   ext_Foo is absent in every environment.
  3. Open the M365 admin center → Agents → Tools for the new server:
    We couldn't load the apps backing this MCP server. Try again later.
    
  4. Confirm out-of-band (Graph) that the backing apps DO exist and are correct:
    az ad app list --filter "startswith(displayName,'ext_Foo')" \
      --query "[].{name:displayName,appId:appId,uris:identifierUris}" -o table
    # ext_Foo-A365Proxy        <guid>   []
    # ext_Foo-PublicClients    <guid>   []
    # ext_Foo - BYO            <guid>   ['https://agent365.svc.cloud.microsoft/agents/servers/ext_Foo/tenants/<tid>']
    So the apps are present; the portal simply can't bind them yet, while the CLI already
    declared success.

Tool-name validation gap (concrete)

The live Context7 endpoint exposes resolve-library-id and query-docs (its hosted
build renamed the older get-library-docs → query-docs). A registration listing
get-library-docs is accepted and reported successful by the CLI, and would fail only at
runtime. The CLI already needs the serverUrl; it could perform an MCP initialize +
tools/list and diff the declared names, turning a silent runtime failure into a
registration-time error.

A minimal client-side check (what the CLI could do internally):

sid=$(curl -s -D - -o /dev/null -X POST "$serverUrl" \
  -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"a365","version":"1"}}}' \
  | grep -i "^mcp-session-id:" | awk -F': ' '{print $2}' | tr -d '\r')
curl -s -X POST "$serverUrl" -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" -H "Mcp-Session-Id: $sid" \
  -d '{"jsonrpc":"2.0","method":"notifications/initialized"}' >/dev/null
curl -s -X POST "$serverUrl" -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" -H "Mcp-Session-Id: $sid" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | sed 's/^data: //'

Expected behavior

  • Treat tool-name verification as part of registration (at least an opt-in
    --verify-tools that runs tools/list and diffs declared vs. exposed names; for NoAuth
    it requires nothing extra).
  • Don't report registered successfully until the registration is queryable/consistent;
    or print an explicit "propagation can take up to ~30 min; the admin center may show
    'couldn't load the apps backing this MCP server' until then" note instead of unqualified success.
  • Provide a CLI way to read back an external registration and its approval/consent state
    (e.g. develop-mcp get-server --name ext_Foo), since list-servers only returns
    Dataverse-published servers today.

Notes / out-of-band verification used

  • Pending consent is observable only via Graph, not the CLI:
    az ad app permission list-grants --id <ext_Foo - BYO appId> → 0 grants = not yet approved.
  • register-external-mcp-server requires a public streamable-HTTP/SSE endpoint;

SDK Version

1.1.214+90c444832f

Language/Runtime

.NET 10

OS

Windows 11

How to Reproduce

Register any reachable NoAuth streamable-HTTP server, e.g.:

a365 develop-mcp register-external-mcp-server -f registration.json
# registration.json: serverName ext_Foo, authType NoAuth, serverUrl https://…/mcp,
#                     tools [{name: "resolve-library-id"}, {name: "query-docs"}]

CLI prints … has been registered successfully.
2. Try to confirm it from the CLI:

a365 develop-mcp list-servers -e <any-dataverse-env-id>
# → only the built-in msdyn_DataverseMCPServer / msdyn_DataversePreviewMCPServer.
#   ext_Foo is absent in every environment.
  1. Open the M365 admin center → Agents → Tools for the new server:
    We couldn't load the apps backing this MCP server. Try again later.
    
  2. Confirm out-of-band (Graph) that the backing apps DO exist and are correct:
    az ad app list --filter "startswith(displayName,'ext_Foo')" \
      --query "[].{name:displayName,appId:appId,uris:identifierUris}" -o table
    # ext_Foo-A365Proxy        <guid>   []
    # ext_Foo-PublicClients    <guid>   []
    # ext_Foo - BYO            <guid>   ['https://agent365.svc.cloud.microsoft/agents/servers/ext_Foo/tenants/<tid>']
    So the apps are present; the portal simply can't bind them yet, while the CLI already
    declared success.

Output

No response

Screenshots

Image

Code of Conduct

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

P1Very high prioritybugSomething isn't workingescalatedIssue has breached SLA and been escalatedsecuritySecurity-related issue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions