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,70 @@
|
||||
// Catalog — fetches MCP connectors from the gateway.
|
||||
//
|
||||
// The gateway exposes ~1600 managed APIs (the full Logic Apps connector
|
||||
// catalog). MCP servers are a small subset (~43) and there is no `kind` or
|
||||
// capability flag that distinguishes them. The only reliable signal is the
|
||||
// string "mcp" appearing in the API's name OR its display name — and those are
|
||||
// genuinely independent signals: `workiqsharepoint` has no "mcp" in its name
|
||||
// (display name "Work IQ SharePoint MCP"), while `hginsightsmcp` has "mcp" in
|
||||
// its name but a display name of "HG Insights Connect". Matching either keeps
|
||||
// the full set without an allowlist that has to be hand-maintained.
|
||||
|
||||
import { listManagedApis } from "./armClient.mjs";
|
||||
import { CATEGORY } from "./categories.mjs";
|
||||
|
||||
function isMcpServer(api) {
|
||||
const name = api.name || "";
|
||||
const displayName = api.properties?.generalInformation?.displayName || "";
|
||||
return /mcp/i.test(name) || /mcp/i.test(displayName);
|
||||
}
|
||||
|
||||
// Microsoft first-party servers (a365*/d365*/workiq* names, or a Microsoft-
|
||||
// branded display name) group under "Microsoft"; everything else is a partner
|
||||
// server. Derived rather than hardcoded so new servers categorize themselves.
|
||||
function categoryFor(name, displayName) {
|
||||
const n = (name || "").toLowerCase();
|
||||
const d = (displayName || "").toLowerCase();
|
||||
const isMicrosoft =
|
||||
/^(a365|d365|workiq)/.test(n) ||
|
||||
d.startsWith("microsoft") ||
|
||||
d.startsWith("work iq") ||
|
||||
d.startsWith("dynamics 365");
|
||||
return isMicrosoft ? CATEGORY.microsoft : CATEGORY.partner;
|
||||
}
|
||||
|
||||
let cachedCatalog = null;
|
||||
let cacheKey = null;
|
||||
|
||||
export function invalidateCache() {
|
||||
cachedCatalog = null;
|
||||
cacheKey = null;
|
||||
}
|
||||
|
||||
export async function fetchCatalog(subscriptionId, resourceGroup, gatewayName) {
|
||||
const key = `${subscriptionId}/${resourceGroup}/${gatewayName}`;
|
||||
if (cachedCatalog && cacheKey === key) return cachedCatalog;
|
||||
|
||||
const apis = await listManagedApis(subscriptionId, resourceGroup, gatewayName);
|
||||
|
||||
const catalog = apis
|
||||
.filter(isMcpServer)
|
||||
.map((a) => {
|
||||
const props = a.properties || {};
|
||||
const general = props.generalInformation || {};
|
||||
const metadata = props.metadata || {};
|
||||
const displayName = general.displayName || a.name;
|
||||
return {
|
||||
id: a.name,
|
||||
apiName: a.name,
|
||||
displayName,
|
||||
description: general.description || "",
|
||||
iconUri: general.iconUri || "",
|
||||
brandColor: metadata.brandColor || "",
|
||||
category: categoryFor(a.name, displayName),
|
||||
};
|
||||
});
|
||||
|
||||
cachedCatalog = catalog;
|
||||
cacheKey = key;
|
||||
return catalog;
|
||||
}
|
||||
Reference in New Issue
Block a user