mirror of
https://github.com/github/awesome-copilot.git
synced 2026-07-17 11:23:27 +00:00
Add Azure Connector Namespaces canvas extension 🤖🤖🤖 (#2250)
* Add MCP Connectors (connector-namespaces) canvas extension 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> * Update Connector Namespaces canvas extension Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Harden Connector Namespaces canvas extension Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Sanitize connector icon brand colors Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Connector Namespace playground actions Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Replace sandbox skill with native tool Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Clarify connector disconnect action Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Color disconnect action red Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Add connector extension plugin manifest Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Address connector canvas review feedback Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Remove legacy connector canvas manifest Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Address remaining connector review feedback Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Harden connector review fixes Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Harden connector convergence Address the latest connector review batch across config persistence, executable trust, reauthentication, JSON-RPC transport, smoke safety, and accessibility. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Use native HTTP connector configs Persist Connector Namespace MCP servers as direct HTTPS entries with API-key headers, remove the stdio unwrap proxy, and exercise the native Streamable HTTP path in smoke coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf * Secure persisted connector state Create the Connector Namespace artifacts directory and saved gateway config with private permissions, and align the reduced-motion regression notes with the static fallback behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a986299f-86be-46c3-9562-cbf7d25174cf --------- Co-authored-by: Alex Yang <yangalex@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
// Canvas extension entry point — MCP Connectors browser.
|
||||
|
||||
import { joinSession, createCanvas } from "@github/copilot-sdk/extension";
|
||||
import { getServerConfig, startServer, stopServer } from "./server.mjs";
|
||||
import { getSavedConfig, loadSavedConfig, saveConfig } from "./state.mjs";
|
||||
import { fetchCatalog } from "./catalog.mjs";
|
||||
import { getInstalledState, openInBrowser, setWorkspaceRoot } from "./install.mjs";
|
||||
import { buildSandboxUrl, resolveSandboxConnector } from "./sandbox.mjs";
|
||||
|
||||
// Load any previously saved connector namespace config on startup
|
||||
loadSavedConfig();
|
||||
|
||||
async function openPlayground(server, instanceId) {
|
||||
const config = instanceId ? getServerConfig(instanceId) : getSavedConfig();
|
||||
if (!config) return { opened: false, reason: "no_namespace_configured" };
|
||||
const catalog = await fetchCatalog(config.subscriptionId, config.resourceGroup, config.gatewayName);
|
||||
const installedState = await getInstalledState(config);
|
||||
const resolved = resolveSandboxConnector(catalog, installedState, server);
|
||||
if (!resolved.connector) return { opened: false, ...resolved };
|
||||
const url = buildSandboxUrl(config, resolved.connector.id);
|
||||
await openInBrowser(url);
|
||||
return { opened: true, server: resolved.connector, url };
|
||||
}
|
||||
|
||||
const session = await joinSession({
|
||||
tools: [
|
||||
{
|
||||
name: "connector_namespaces_open_playground",
|
||||
description: "Open a named connector from My MCPs in the Azure Connector Namespace playground.",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
server: {
|
||||
type: "string",
|
||||
description: "Connector display name or server ID from My MCPs",
|
||||
},
|
||||
},
|
||||
required: ["server"],
|
||||
},
|
||||
handler: async ({ server }) => JSON.stringify(await openPlayground(server)),
|
||||
},
|
||||
],
|
||||
canvases: [
|
||||
createCanvas({
|
||||
id: "connector-namespaces",
|
||||
displayName: "MCP Connectors",
|
||||
description: "Browse, connect, and open MCP connectors in the Azure Connector Namespace Sandbox.",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
subscriptionId: { type: "string", description: "Azure subscription ID (optional \u2014 if omitted, uses saved config or shows picker)" },
|
||||
resourceGroup: { type: "string", description: "Resource group name" },
|
||||
gatewayName: { type: "string", description: "Connector namespace name" },
|
||||
},
|
||||
},
|
||||
actions: [
|
||||
{
|
||||
name: "open_sandbox",
|
||||
description: "Open a named connector from My MCPs in the Azure Connector Namespace Sandbox",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
server: {
|
||||
type: "string",
|
||||
description: "Connector display name or server ID from My MCPs",
|
||||
},
|
||||
},
|
||||
required: ["server"],
|
||||
},
|
||||
handler: async (ctx) => openPlayground(ctx.input.server, ctx.instanceId),
|
||||
},
|
||||
],
|
||||
open: async (ctx) => {
|
||||
let config;
|
||||
// If explicit input provided, use it and save for future
|
||||
if (ctx.input && ctx.input.subscriptionId && ctx.input.resourceGroup && ctx.input.gatewayName) {
|
||||
config = {
|
||||
subscriptionId: ctx.input.subscriptionId,
|
||||
resourceGroup: ctx.input.resourceGroup,
|
||||
gatewayName: ctx.input.gatewayName,
|
||||
};
|
||||
saveConfig(config);
|
||||
}
|
||||
// A saved config seeds a new panel only. Rehydrating an existing
|
||||
// panel keeps its active namespace even if another panel changed
|
||||
// the persisted default.
|
||||
const entry = await startServer(
|
||||
ctx.instanceId,
|
||||
config ? { config } : { defaultConfig: getSavedConfig() },
|
||||
);
|
||||
return { title: "MCP Connectors", url: entry.url };
|
||||
},
|
||||
onClose: async (ctx) => {
|
||||
await stopServer(ctx.instanceId);
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
// Tell the install pipeline where the workspace .mcp.json lives (if any).
|
||||
setWorkspaceRoot(session.workspacePath);
|
||||
Reference in New Issue
Block a user