Skip to content

Add Azure Connector Namespaces canvas extension 🤖🤖🤖#2250

Open
alexyaang wants to merge 12 commits into
github:mainfrom
alexyaang:add-connector-namespaces
Open

Add Azure Connector Namespaces canvas extension 🤖🤖🤖#2250
alexyaang wants to merge 12 commits into
github:mainfrom
alexyaang:add-connector-namespaces

Conversation

@alexyaang

@alexyaang alexyaang commented Jul 9, 2026

Copy link
Copy Markdown
Member

Pull Request Checklist

  • I have read and followed the CONTRIBUTING.md guidelines.
  • I have read and followed the Guidance for submissions involving paid services.
  • My contribution adds a new instruction, prompt, agent, skill, workflow, or canvas extension file in the correct directory.
  • The file follows the required naming convention.
  • The content is clearly structured and follows the example format.
  • I have tested my instructions, prompt, agent, skill, workflow, or canvas extension with GitHub Copilot.
  • I have run npm start and verified that README.md is up to date.
  • I am targeting the main branch for this pull request.

Description

Adds an Azure Connector Namespaces canvas extension for browsing namespace MCP servers, connecting them to GitHub Copilot, disconnecting local registrations, and opening installed connectors in the Connector Namespace playground.

The extension also exposes the native connector_namespaces_open_playground tool so Copilot can open a named installed connector directly.


Screenshots

Connector catalog

Connector Namespace catalog showing Microsoft MCP connectors

Connected MCP controls

Connected MCP with playground and disconnect controls


Type of Contribution

  • New instruction file.
  • New prompt file.
  • New agent file.
  • New plugin.
  • New skill file.
  • New agentic workflow.
  • New canvas extension.
  • Update to existing instruction, prompt, agent, plugin, skill, workflow, or canvas extension.
  • Other (please specify):

Additional Notes

Requires an Azure subscription with Connector Namespace resources. Tested with 60 focused extension tests, the standalone preview, the live canvas, and npm start.

I am a Microsoft employee.


By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.

yangalex1 and others added 2 commits June 26, 2026 14:38
A Copilot CLI canvas extension for browsing and adding MCP connectors
from an Azure Connector Namespace into a Copilot session. Sign-in is
dependency-free (OAuth 2.0 auth-code + PKCE via the Azure CLI public
client, loopback redirect); network access is restricted to the public
Azure Resource Manager endpoint. MIT licensed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@alexyaang alexyaang requested a review from aaronpowell as a code owner July 9, 2026 01:27
Copilot AI review requested due to automatic review settings July 9, 2026 01:27
@github-actions github-actions Bot added canvas-extension PR touches canvas extensions new-submission PR adds at least one new contribution labels Jul 9, 2026
@alexyaang alexyaang marked this pull request as draft July 9, 2026 01:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new Copilot CLI canvas extension, connector-namespaces, for browsing and connecting Azure “Connector Namespace” MCP connectors, plus companion test/preview harnesses to validate the UX and the end-to-end MCP handshake through the real unwrap proxy.

Changes:

  • Adds the connector-namespaces canvas extension (ARM auth, catalog fetch, install/reauth flows, loopback UI server, MCP unwrap proxy, state persistence).
  • Adds deterministic regression tests and a standalone preview server to guard recurring UI regressions.
  • Adds a standalone MCP smoke-test harness to exercise the real proxy path end-to-end (connect → initialize → tools/list → safe tools/call).
Show a summary per file
File Description
extensions/connector-namespaces/test/smoke.mjs Standalone orchestrator to install/connect/probe Microsoft MCP servers and write reports.
extensions/connector-namespaces/test/safe-tools.mjs Heuristic + curated selection of safe read-only tools for automated tools/call.
extensions/connector-namespaces/test/README.md Usage docs for the smoke-test harness and its consent model.
extensions/connector-namespaces/test/mcp-probe.mjs Spawns the real unwrap proxy and drives initialize/tools/list/tools/call over stdio.
extensions/connector-namespaces/state.mjs Persists selected gateway config; tracks session-added connectors.
extensions/connector-namespaces/server.test.mjs Node tests covering CSRF/cross-site gating logic for POST /api/*.
extensions/connector-namespaces/server.mjs Loopback HTTP server providing UI + API routes for the canvas.
extensions/connector-namespaces/renderer.test.mjs Regression tests ensuring spinners aren’t frozen and banner dismiss remains effective.
extensions/connector-namespaces/README.md Extension documentation (prereqs, install, usage, security notes).
extensions/connector-namespaces/preview/shots.mjs Optional agent-browser script to capture visual evidence screenshots.
extensions/connector-namespaces/preview/server.mjs Standalone preview server that stubs /api/* endpoints for deterministic UI states.
extensions/connector-namespaces/preview/README.md Docs for running the preview server and optional screenshot capture.
extensions/connector-namespaces/preview/fixtures.mjs Deterministic fixtures for preview server responses and catalog tiles.
extensions/connector-namespaces/preview/.gitignore Ignores generated preview screenshots.
extensions/connector-namespaces/package.json Declares the extension’s Node module metadata and Copilot SDK dependency.
extensions/connector-namespaces/mcp-unwrap-proxy.mjs Stdio↔HTTP proxy that unwraps Logic Apps $content SSE envelopes into JSON-RPC lines.
extensions/connector-namespaces/LICENSE MIT license for the extension content.
extensions/connector-namespaces/install.test.mjs Unit tests guarding deterministic installed-state selection and safety invariants.
extensions/connector-namespaces/install.reauth.test.mjs Tests ensuring reauth re-consents the existing connection without minting new resources.
extensions/connector-namespaces/install.mjs Core install/reauth flows, ARM helpers, MCP config writer, and installed-state derivation.
extensions/connector-namespaces/extension.mjs Canvas entry point wiring session, actions, and loopback server lifecycle.
extensions/connector-namespaces/createPage.mjs HTML/JS renderer for “Create connector namespace” provisioning wizard page.
extensions/connector-namespaces/copilot-extension.json Minimal extension metadata file (name/version).
extensions/connector-namespaces/categories.mjs Frozen enum defining catalog routing categories (Microsoft vs Partners).
extensions/connector-namespaces/catalog.mjs Fetches managed APIs and filters/categorizes MCP servers for the catalog UI.
extensions/connector-namespaces/canvas.json Canvas metadata (id/name/description/author/screenshots).
extensions/connector-namespaces/armClient.mjs Interactive Azure sign-in + ARM client helpers (paging, host guards, provisioning helpers).

Review details

  • Files reviewed: 28/29 changed files
  • Comments generated: 5
  • Review effort level: Low

Comment thread extensions/connector-namespaces/install.mjs Outdated
Comment thread extensions/connector-namespaces/test/smoke.mjs Outdated
Comment thread extensions/connector-namespaces/README.md Outdated
Comment thread extensions/connector-namespaces/server.mjs Outdated
Comment thread extensions/connector-namespaces/renderer.test.mjs Outdated
yangalex1 and others added 7 commits July 8, 2026 18:52
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf
@alexyaang alexyaang changed the title Add connector namespaces Add Azure Connector Namespaces canvas extension 🤖🤖🤖 Jul 15, 2026
@alexyaang alexyaang marked this pull request as ready for review July 15, 2026 03:20
Copilot AI review requested due to automatic review settings July 15, 2026 03:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 31/32 changed files
  • Comments generated: 24
  • Review effort level: Medium

Comment thread extensions/connector-namespaces/armClient.mjs Outdated
Comment thread extensions/connector-namespaces/armClient.mjs Outdated
Comment thread extensions/connector-namespaces/install.mjs Outdated
Comment thread extensions/connector-namespaces/install.mjs Outdated
Comment thread extensions/connector-namespaces/install.mjs Outdated
Comment thread extensions/connector-namespaces/install.mjs
Comment thread extensions/connector-namespaces/README.md Outdated
Comment thread extensions/connector-namespaces/armClient.mjs
Comment thread extensions/connector-namespaces/renderer.mjs
Comment thread extensions/connector-namespaces/armClient.mjs
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf
Copilot AI review requested due to automatic review settings July 15, 2026 03:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 30/32 changed files
  • Comments generated: 26
  • Review effort level: Medium

Comment thread extensions/connector-namespaces/armClient.mjs Outdated
Comment thread extensions/connector-namespaces/install.mjs Outdated
Comment thread extensions/connector-namespaces/install.mjs Outdated
Comment thread extensions/connector-namespaces/armClient.mjs
Comment thread extensions/connector-namespaces/install.mjs
Comment thread extensions/connector-namespaces/mcp-unwrap-proxy.mjs Outdated
Comment thread extensions/connector-namespaces/extension.mjs Outdated
Comment thread extensions/connector-namespaces/createPage.mjs Outdated
Comment thread extensions/connector-namespaces/createPage.mjs
Comment thread extensions/connector-namespaces/server.mjs
@aaronpowell

Copy link
Copy Markdown
Contributor

There are quite a few CCR comments on the PR, and several of them are marked as HIGH - can you review them to either action on them (if relevant), or dismiss.

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

Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf
Copilot AI review requested due to automatic review settings July 15, 2026 04:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 32/34 changed files
  • Comments generated: 12
  • Review effort level: Medium

// auth-code + PKCE sign-in against it with no app registration of our own. AAD
// accepts any port on a loopback redirect for public clients, so there's no
// secret to ship and nothing for a teammate to configure.
const CLIENT_ID = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";

// In-memory state
const addedConnectors = new Map();
let sessionConfig = null;
Comment on lines +535 to +538
let result = await armWrite("PUT", url, body, { "If-None-Match": "*" });
let state = result?.properties?.provisioningState;
// ~3 min ceiling (60 * 3s). connectorGateways usually settle in seconds.
for (let i = 0; i < 60 && state && !TERMINAL_STATES.has(state); i++) {
Comment on lines +528 to +541
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
const address = server.address();
const port = typeof address === "object" && address ? address.port : 0;
entry.host = `127.0.0.1:${port}`;
entry.origin = `http://${entry.host}`;
entry.url = `${entry.origin}/`;
servers.set(instanceId, entry);
return entry;
})();
// Record the in-flight start synchronously so a concurrent open() for the
// same instance awaits this server instead of binding a second one and
// leaking the first.
starting.set(instanceId, p);
p.finally(() => { if (starting.get(instanceId) === p) starting.delete(instanceId); });
Comment on lines +424 to +426
for (const connectionName of connectionNames) {
await armDelete(`${gatewayId(config)}/connections/${armSegment(connectionName)}?api-version=${API_VERSION}`).catch(() => {});
}
Comment on lines +117 to +130
res.writeHead(200, { "Content-Type": "text/html" });
res.end(
"<html><body style=\"font-family:system-ui,sans-serif;padding:2rem\">" +
"<h2>Signed in to Azure</h2><p>You can close this tab and return to your terminal.</p>" +
"</body></html>",
);
if (!code || returnedState !== state) {
finish(reject, new Error("Azure sign-in was cancelled or returned an unexpected response."));
return;
}
exchangeCode(code, verifier, redirectUri).then(
(auth) => finish(resolve, auth),
(err) => finish(reject, err),
);
Comment on lines +358 to +359
<label>Subscription</label>
<select id="sub-select">
// server: { apiName, displayName, configName }
// tools: the array returned by tools/list
// → { tool, args, source } | null (null means "no safe tool, record SKIPPED")
export function pickSafeTool(server, tools) {
Comment on lines +1035 to +1037
if (cancelled && pendingConn) {
await fetch("/api/rollback-connection", { method: "POST", headers: {"Content-Type":"application/json"}, body: JSON.stringify({ connName: pendingConn }) }).catch(() => {});
}
Comment on lines +1096 to +1099
const finishUrl = data.configName ? "/api/finish-reauth" : "/api/finish-install";
const finishBody = data.configName
? { apiName, displayName, connName: data.connName, configName: data.configName, location: data.location, scope: installScope }
: { apiName, displayName, connName: data.connName, location: data.location, scope: installScope };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

canvas-extension PR touches canvas extensions new-submission PR adds at least one new contribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants