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:
- 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.
- 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.
- 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
- 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.
- 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.
- Open the M365 admin center → Agents → Tools for the new server:
We couldn't load the apps backing this MCP server. Try again later.
- 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.
- Open the M365 admin center → Agents → Tools for the new server:
We couldn't load the apps backing this MCP server. Try again later.
- 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
Code of Conduct
Description
a365 develop-mcp register-external-mcp-serverprints…but "successfully" overstates what actually happened. The command's idea of a correct
registration diverges from reality in three ways:
WARNING: Tool names must exactly match the names exposed by the remote MCP serverbut does not call the endpoint's
tools/listto check — so a registration with wrongtool names is reported as fully successful and only fails silently at invocation time.
register … --verify/get-serveranddevelop-mcp list-serversdoes not returnexternally-registered NoAuth servers, so there is no CLI way to confirm the registration
landed or read its approval/consent state.
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
Microsoft.Agents.A365.DevTools.Cli1.1.214+90c444832f(also1.1.206+091d51d7db)https://mcp.context7.com/mcp)ea9ffc3e-************-234d7c7565c1provisioned & enabledd2562ede-74db-457e-a7b6-544e236ebb61)Reproduction
… has been registered successfully.declared success.
Tool-name validation gap (concrete)
The live Context7 endpoint exposes
resolve-library-idandquery-docs(its hostedbuild renamed the older
get-library-docs→query-docs). A registration listingget-library-docsis accepted and reported successful by the CLI, and would fail only atruntime. The CLI already needs the
serverUrl; it could perform an MCPinitialize+tools/listand diff the declared names, turning a silent runtime failure into aregistration-time error.
A minimal client-side check (what the CLI could do internally):
Expected behavior
--verify-toolsthat runstools/listand diffs declared vs. exposed names; for NoAuthit requires nothing extra).
registered successfullyuntil 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.
(e.g.
develop-mcp get-server --name ext_Foo), sincelist-serversonly returnsDataverse-published servers today.
Notes / out-of-band verification used
az ad app permission list-grants --id <ext_Foo - BYO appId>→0grants = not yet approved.register-external-mcp-serverrequires 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.:
CLI prints
… has been registered successfully.2. Try to confirm it from the CLI:
declared success.
Output
No response
Screenshots
Code of Conduct