Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
469 linesCodeBlameRaw
1import type { Provider } from "./integrations";
2
3/**
4 * The connector catalog: every tool g1t connects to, or will, in one list.
5 * The workspace's Integrations page and your own Integrations settings are
6 * both drawn from it, so a new connector is added here, once.
7 *
8 * A connector is `available` when g1t can set it up today (its `href` is
9 * where), and `soon` while it is planned. `scopes` says who connects it:
10 *
11 * - `workspace`: an owner connects it once, for everyone in the workspace.
12 * - `personal`: each person connects their own account, and it follows them
13 * into every workspace they belong to (a calendar, a personal sign-in).
14 *
15 * A connector with both scopes can say something different for each, in
16 * `personal`: its own description, status, capabilities or setup page.
17 * `connectorView` resolves that into what one context shows.
18 *
19 * Paths in `href` are g1t's own pages. `:workspace` stands for the
20 * workspace's slug.
21 */
22
23export type ConnectorScope = "workspace" | "personal";
24export type ConnectorStatus = "available" | "soon";
25
26export type ConnectorCategory =
27 | "code"
28 | "issues"
29 | "chat"
30 | "calendar"
31 | "docs"
32 | "monitoring"
33 | "cloud"
34 | "ai"
35 | "data"
36 | "crm"
37 | "design"
38 | "security"
39 | "files";
40
41/** What a connector lets g1t do, as the small tags on its card. */
42export type ConnectorCapability =
43 | "Agents can read"
44 | "Agents can act"
45 | "Opens issues"
46 | "Writes back"
47 | "Imports repositories"
48 | "Mirrors repositories"
49 | "Signs you in"
50 | "Sends events"
51 | "Alerts into chat"
52 | "Sets your status"
53 | "Finds a time"
54 | "Runs models"
55 | "Deploys"
56 | "Syncs people";
57
58export type Connector = {
59 /** Stable and unique: used in links and requests. */
60 id: string;
61 name: string;
62 category: ConnectorCategory;
63 /** One plain line of what it does in g1t, for a workspace (or for you, when it is only personal). */
64 description: string;
65 scopes: ConnectorScope[];
66 status: ConnectorStatus;
67 /** Where an available connector is set up, for each scope it has. */
68 href?: Partial<Record<ConnectorScope, string>>;
69 capabilities?: ConnectorCapability[];
70 /** The integration provider behind it, whose connections show it as connected. */
71 provider?: Provider;
72 /** What differs when you connect it for yourself. */
73 personal?: { description?: string; status?: ConnectorStatus; capabilities?: ConnectorCapability[] };
74 /** More words search should find it by. */
75 keywords?: string[];
76 /**
77 * The remote MCP server behind it, when the tool publishes one: g1t
78 * connects to it (docs.g1t.sh/guides/customize/, "Connectors"), signs in
79 * the way it asks (`oauth`: the browser; `header`: a key an owner
80 * pastes; `none`), lists its tools, and gives them to agents.
81 */
82 mcp?: { url: string; auth: "oauth" | "header" | "none"; header?: string };
83};
84
85/** A connector as one context (a workspace, or you) shows it. */
86export type ConnectorView = {
87 id: string;
88 name: string;
89 category: ConnectorCategory;
90 description: string;
91 status: ConnectorStatus;
92 href: string | null;
93 capabilities: ConnectorCapability[];
94 provider: Provider | null;
95 keywords: string[];
96 /** The other scope it can also be connected in. */
97 alsoIn: ConnectorScope | null;
98 /** The MCP server behind it, when there is one. */
99 mcp: Connector["mcp"] | null;
100};
101
102/** The categories, in the order the directory lists them. */
103export const CONNECTOR_CATEGORIES: { id: ConnectorCategory; title: string }[] = [
104 { id: "code", title: "Code & CI" },
105 { id: "issues", title: "Issues & projects" },
106 { id: "chat", title: "Chat & meetings" },
107 { id: "calendar", title: "Calendar & email" },
108 { id: "docs", title: "Docs & knowledge" },
109 { id: "monitoring", title: "Monitoring & incidents" },
110 { id: "cloud", title: "Cloud & deploy" },
111 { id: "ai", title: "AI models" },
112 { id: "data", title: "Data & analytics" },
113 { id: "crm", title: "CRM & support" },
114 { id: "design", title: "Design" },
115 { id: "security", title: "Security & identity" },
116 { id: "files", title: "Files & storage" },
117];
118
119const W: ConnectorScope[] = ["workspace"];
120const P: ConnectorScope[] = ["personal"];
121const BOTH: ConnectorScope[] = ["workspace", "personal"];
122
123/** A model provider: set up on the workspace's model providers page. */
124function model(provider: Provider, name: string, description: string, keywords: string[] = []): Connector {
125 return {
126 id: provider.replace(/_/g, "-"),
127 name,
128 category: "ai",
129 description,
130 scopes: W,
131 status: "available",
132 href: { workspace: `/:workspace/-/integrations/models?add=${provider}#add` },
133 capabilities: ["Runs models"],
134 provider,
135 keywords: ["model", "llm", ...keywords],
136 };
137}
138
139/** Where an MCP-backed connector is connected: Customize's Connectors page, with the directory entry chosen. */
140export const MCP_CONNECT_PATH = "/:workspace/-/customize/connectors/new?directory=";
141
142/**
143 * A tool with a remote MCP server: available now, connected from Customize
144 * (an owner signs in or pastes a key), its tools then given to agents.
145 */
146function mcp(
147 id: string,
148 name: string,
149 category: ConnectorCategory,
150 description: string,
151 server: NonNullable<Connector["mcp"]>,
152 capabilities: ConnectorCapability[] = ["Agents can read", "Agents can act"],
153 keywords: string[] = [],
154): Connector {
155 return { id, name, category, description, scopes: W, status: "available", href: { workspace: `${MCP_CONNECT_PATH}${id}` }, capabilities, keywords: ["mcp", ...keywords], mcp: server };
156}
157
158/** A planned connector. */
159function soon(
160 id: string,
161 name: string,
162 category: ConnectorCategory,
163 scopes: ConnectorScope[],
164 description: string,
165 capabilities: ConnectorCapability[] = [],
166 personal?: Connector["personal"],
167): Connector {
168 return { id, name, category, description, scopes, status: "soon", capabilities, ...(personal ? { personal } : {}) };
169}
170
171export const CONNECTORS: Connector[] = [
172 // Code & CI -------------------------------------------------------------
173 {
174 id: "github",
175 name: "GitHub",
176 category: "code",
177 description: "Import repositories, or mirror them both ways while your team moves over.",
178 scopes: BOTH,
179 status: "available",
180 href: { workspace: "/new/github?workspace=:workspace", personal: "/settings/github" },
181 capabilities: ["Imports repositories", "Mirrors repositories"],
182 personal: {
183 description: "Sign in with your GitHub account, and reach the repositories you can see there to import them.",
184 capabilities: ["Signs you in", "Imports repositories"],
185 },
186 keywords: ["git", "import", "mirror", "sign in"],
187 },
188 mcp("github-mcp", "GitHub (MCP)", "code", "Agents read and act on repositories, issues and pull requests on GitHub, through GitHub's MCP server.", { url: "https://api.githubcopilot.com/mcp/", auth: "oauth" }, ["Agents can read", "Agents can act"], ["issues", "pull requests"]),
189 {
190 id: "webhooks",
191 name: "Webhooks",
192 category: "code",
193 description: "Every repository's events, sent to your own addresses as they happen, signed.",
194 scopes: W,
195 status: "available",
196 href: { workspace: "/:workspace/-/webhooks" },
197 capabilities: ["Sends events"],
198 keywords: ["http", "events", "outgoing"],
199 },
200 soon("gitlab", "GitLab", "code", BOTH, "Import projects and keep them mirrored, merge requests included.", ["Imports repositories", "Mirrors repositories"], {
201 description: "Sign in with GitLab, and reach your own projects to import them.",
202 capabilities: ["Signs you in", "Imports repositories"],
203 }),
204 soon("bitbucket", "Bitbucket", "code", BOTH, "Import repositories and keep them mirrored while you move.", ["Imports repositories", "Mirrors repositories"], {
205 description: "Reach your own Bitbucket repositories to import them.",
206 capabilities: ["Imports repositories"],
207 }),
208 soon("circleci", "CircleCI", "code", W, "Pipeline results as checks on pull requests, which agents read when a build fails.", ["Agents can read"]),
209 soon("buildkite", "Buildkite", "code", W, "Build results as checks on pull requests, with the failing step for agents to fix.", ["Agents can read"]),
210 soon("docker-hub", "Docker Hub", "code", W, "Push images your workflows build, and pull private base images.", ["Deploys"]),
211
212 // Issues & projects -----------------------------------------------------
213 {
214 id: "linear",
215 name: "Linear",
216 category: "issues",
217 description: "Agents read ENG-42 when work mentions it; import issues, and they hear back when the work lands.",
218 scopes: BOTH,
219 status: "available",
220 href: { workspace: "/:workspace/-/integrations/trackers?add=linear#add" },
221 capabilities: ["Agents can read", "Writes back"],
222 provider: "linear",
223 personal: {
224 description: "Issues assigned to you in Linear, in your g1t inbox beside everything else.",
225 status: "soon",
226 capabilities: ["Agents can read"],
227 },
228 keywords: ["tracker", "tickets"],
229 },
230 mcp("linear-mcp", "Linear (MCP)", "issues", "Agents search, create and update issues, projects and cycles in Linear, through Linear's MCP server.", { url: "https://mcp.linear.app/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["tracker", "issues"]),
231 {
232 id: "jira",
233 name: "Jira",
234 category: "issues",
235 description: "Agents read TECH-1234 when work mentions it; import tickets, and they hear back when the work lands.",
236 scopes: W,
237 status: "available",
238 href: { workspace: "/:workspace/-/integrations/trackers?add=jira#add" },
239 capabilities: ["Agents can read", "Writes back"],
240 provider: "jira",
241 keywords: ["atlassian", "tracker", "tickets"],
242 },
243 mcp("asana", "Asana", "issues", "Agents read, create and update tasks and projects in Asana, through Asana's MCP server.", { url: "https://mcp.asana.com/v2/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["tasks", "projects"]),
244 soon("shortcut", "Shortcut", "issues", W, "Stories agents read when work mentions them, updated when the work lands.", ["Agents can read", "Writes back"]),
245 soon("clickup", "ClickUp", "issues", W, "Tasks agents can read and import, kept in step with their pull requests.", ["Agents can read", "Writes back"]),
246 soon("trello", "Trello", "issues", W, "Cards become issues, and move along their board as the work does.", ["Opens issues", "Writes back"]),
247
248 // Chat & meetings -------------------------------------------------------
249 soon("slack", "Slack", "chat", BOTH, "Alerts and agent updates in the channels your team already reads, and agents to talk to there.", ["Alerts into chat", "Agents can act"], {
250 description: "Your status in g1t follows the one you set in Slack, and the other way round.",
251 capabilities: ["Sets your status"],
252 }),
253 soon("microsoft-teams", "Microsoft Teams", "chat", BOTH, "Alerts and agent updates posted to Teams channels, with agents to talk to there.", ["Alerts into chat", "Agents can act"], {
254 description: "Your status in g1t follows your Teams presence.",
255 capabilities: ["Sets your status"],
256 }),
257 soon("discord", "Discord", "chat", W, "Releases, alerts and agent updates posted to a Discord server.", ["Alerts into chat"]),
258 soon("zoom", "Zoom", "chat", BOTH, "Meeting notes and recordings agents can read when work refers to them.", ["Agents can read"], {
259 description: "Sets your status to On a call while you are in a Zoom meeting.",
260 capabilities: ["Sets your status"],
261 }),
262 soon("google-meet", "Google Meet", "chat", P, "Sets your status to On a call while you are in a meeting, and starts a call from any channel.", ["Sets your status"]),
263
264 // Calendar & email ------------------------------------------------------
265 soon("google-calendar", "Google Calendar", "calendar", P, "Sets your status to In a meeting while you are in one; agents can find a time that suits everyone.", ["Sets your status", "Finds a time"]),
266 soon("outlook-calendar", "Outlook Calendar", "calendar", P, "Sets your status to In a meeting while you are in one; agents can find a time that suits everyone.", ["Sets your status", "Finds a time"]),
267 soon("gmail", "Gmail", "calendar", P, "Forward a thread to an agent, or turn an email into an issue, from your own inbox.", ["Opens issues", "Agents can read"]),
268 soon("outlook-mail", "Outlook Mail", "calendar", P, "Forward a thread to an agent, or turn an email into an issue, from your own inbox.", ["Opens issues", "Agents can read"]),
269
270 // Docs & knowledge ------------------------------------------------------
271 mcp("notion", "Notion", "docs", "Agents search, read and write Notion pages and databases, through Notion's MCP server.", { url: "https://mcp.notion.com/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["pages", "wiki", "databases"]),
272 mcp("atlassian", "Atlassian (Jira and Confluence)", "docs", "Agents search and update Jira issues and Confluence pages, through Atlassian's MCP server.", { url: "https://mcp.atlassian.com/v1/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["jira", "confluence", "tickets", "wiki"]),
273 soon("google-docs", "Google Docs", "docs", BOTH, "Agents read the specs and plans linked from issues and chat.", ["Agents can read"], {
274 description: "Docs you share in chat open for agents as well as people.",
275 capabilities: ["Agents can read"],
276 }),
277 mcp("zapier", "Zapier", "data", "Agents run the actions you expose from Zapier, across thousands of apps, through Zapier's MCP server.", { url: "https://mcp.zapier.com/api/mcp/mcp", auth: "header", header: "Authorization" }, ["Agents can act"], ["automation", "apps"]),
278 mcp("webflow", "Webflow", "design", "Agents read and update sites, pages and CMS items in Webflow, through Webflow's MCP server.", { url: "https://mcp.webflow.com/sse", auth: "oauth" }, ["Agents can read", "Agents can act"], ["cms", "sites"]),
279 soon("coda", "Coda", "docs", W, "Agents read the docs and tables linked from issues and chat.", ["Agents can read"]),
280
281 // Monitoring & incidents ------------------------------------------------
282 {
283 id: "sentry",
284 name: "Sentry",
285 category: "monitoring",
286 description: "New errors open issues with the stack trace, and resolve in Sentry when the fix merges.",
287 scopes: W,
288 status: "available",
289 href: { workspace: "/:workspace/-/integrations/alerts?add=sentry#add" },
290 capabilities: ["Opens issues", "Agents can read", "Writes back"],
291 provider: "sentry",
292 keywords: ["errors", "alerts", "exceptions"],
293 },
294 {
295 id: "datadog",
296 name: "Datadog",
297 category: "monitoring",
298 description: "Monitors that trigger open issues, and recoveries are noted on them.",
299 scopes: W,
300 status: "available",
301 href: { workspace: "/:workspace/-/integrations/alerts?add=datadog#add" },
302 capabilities: ["Opens issues"],
303 provider: "datadog",
304 keywords: ["monitors", "alerts", "apm"],
305 },
306 {
307 id: "alerts-webhook",
308 name: "Alerts webhook",
309 category: "monitoring",
310 description: "Anything that can send signed JSON opens issues: your own scripts, or any monitoring tool.",
311 scopes: W,
312 status: "available",
313 href: { workspace: "/:workspace/-/integrations/alerts?add=webhook#add" },
314 capabilities: ["Opens issues"],
315 provider: "webhook",
316 keywords: ["incoming", "http", "alerts", "pagerduty", "grafana"],
317 },
318 mcp("sentry-mcp", "Sentry (MCP)", "monitoring", "Agents search issues, read stack traces and look up errors in Sentry, through Sentry's MCP server.", { url: "https://mcp.sentry.dev/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["errors", "issues"]),
319 soon("pagerduty", "PagerDuty", "monitoring", BOTH, "Incidents open issues an agent can start on, and resolve when the fix lands.", ["Opens issues", "Writes back"], {
320 description: "Sets your status to On call while you are on call.",
321 capabilities: ["Sets your status"],
322 }),
323 soon("opsgenie", "Opsgenie", "monitoring", W, "Alerts open issues, and close when the fix lands.", ["Opens issues", "Writes back"]),
324 soon("incident-io", "incident.io", "monitoring", W, "Incidents get a channel in g1t, with agents to dig through what changed.", ["Opens issues", "Alerts into chat"]),
325 soon("grafana", "Grafana", "monitoring", W, "Alert rules open issues, and agents read the dashboards they link to.", ["Opens issues", "Agents can read"]),
326 soon("new-relic", "New Relic", "monitoring", W, "Alerts open issues, with the traces agents need to find the cause.", ["Opens issues", "Agents can read"]),
327 soon("honeycomb", "Honeycomb", "monitoring", W, "Triggers open issues, and agents query traces while they work.", ["Opens issues", "Agents can read"]),
328 soon("better-stack", "Better Stack", "monitoring", W, "Uptime incidents and log alerts open issues.", ["Opens issues"]),
329
330 // Cloud & deploy --------------------------------------------------------
331 mcp("cloudflare", "Cloudflare", "cloud", "Agents read your Cloudflare account's Workers, storage and settings, and look things up in its docs, through Cloudflare's MCP servers.", { url: "https://bindings.mcp.cloudflare.com/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["workers", "r2", "d1", "dns"]),
332 mcp("cloudflare-docs", "Cloudflare docs", "docs", "Agents search Cloudflare's documentation while they work.", { url: "https://docs.mcp.cloudflare.com/mcp", auth: "none" }, ["Agents can read"], ["documentation"]),
333 soon("aws", "Amazon Web Services", "cloud", W, "Workflows and deployments reach AWS with short-lived credentials, no stored keys.", ["Deploys"]),
334 soon("google-cloud", "Google Cloud", "cloud", W, "Workflows and deployments reach Google Cloud with short-lived credentials.", ["Deploys"]),
335 soon("azure", "Microsoft Azure", "cloud", W, "Workflows and deployments reach Azure with short-lived credentials.", ["Deploys"]),
336 mcp("vercel", "Vercel", "cloud", "Agents read your Vercel projects, deployments and logs, through Vercel's MCP server.", { url: "https://mcp.vercel.com", auth: "oauth" }, ["Agents can read", "Agents can act"], ["deployments", "previews"]),
337 soon("netlify", "Netlify", "cloud", W, "Deploy previews as checks on pull requests.", ["Deploys", "Agents can read"]),
338 soon("fly-io", "Fly.io", "cloud", W, "Deploy apps from workflows, and roll back from the deployment's page.", ["Deploys"]),
339 soon("kubernetes", "Kubernetes", "cloud", W, "Roll out to your own clusters from workflows, with each rollout's status on g1t.", ["Deploys"]),
340
341 // AI models -------------------------------------------------------------
342 model("anthropic", "Anthropic", "Claude models on your own Anthropic account, billed there.", ["claude"]),
343 model("openai", "OpenAI", "GPT models on your own OpenAI account, billed there.", ["gpt"]),
344 model("gemini", "Google Gemini", "Gemini models on your own Google AI account, billed there.", ["google"]),
345 model("xai", "xAI", "Grok models on your own xAI account, billed there.", ["grok"]),
346 model("mistral", "Mistral", "Mistral models on your own account, billed there."),
347 model("deepseek", "DeepSeek", "DeepSeek models on your own account, billed there."),
348 model("azure_openai", "Azure OpenAI", "Your Azure OpenAI deployments, in your own subscription.", ["microsoft"]),
349 model("openrouter", "OpenRouter", "Many labs' models through one OpenRouter key."),
350 model("groq", "Groq", "Fast open models on your own Groq account."),
351 model("together", "Together AI", "Open models on your own Together AI account."),
352 model("fireworks", "Fireworks AI", "Open models on your own Fireworks AI account."),
353 model("cerebras", "Cerebras", "Fast open models on your own Cerebras account."),
354 model("anthropic_endpoint", "Anthropic-compatible endpoint", "Any server that speaks the Anthropic API, such as your own gateway.", ["self-hosted", "proxy"]),
355 model("openai_endpoint", "OpenAI-compatible endpoint", "Any server that speaks the OpenAI API, such as a model you host yourself.", ["self-hosted", "proxy", "ollama", "vllm"]),
356 {
357 id: "ai-gateway",
358 name: "AI Gateway",
359 category: "ai",
360 description: "Your own code's model requests through g1t, with the workspace's access tokens, logged and costed.",
361 scopes: W,
362 status: "available",
363 href: { workspace: "/:workspace/-/gateway" },
364 capabilities: ["Runs models"],
365 keywords: ["proxy", "api", "tokens"],
366 },
367 {
368 id: "mcp",
369 name: "MCP clients",
370 category: "ai",
371 description: "Your own agent, connected to g1t's MCP server, works in g1t as you.",
372 scopes: P,
373 status: "available",
374 href: { personal: "/settings/applications" },
375 capabilities: ["Agents can act"],
376 keywords: ["model context protocol", "agent", "applications", "oauth"],
377 },
378 soon("amazon-bedrock", "Amazon Bedrock", "ai", W, "Models in your own AWS account, billed there.", ["Runs models"]),
379 soon("vertex-ai", "Google Vertex AI", "ai", W, "Models in your own Google Cloud project, billed there.", ["Runs models"]),
380 mcp("hugging-face", "Hugging Face", "ai", "Agents search models, datasets, papers and Spaces on the Hub, through Hugging Face's MCP server.", { url: "https://huggingface.co/mcp", auth: "oauth" }, ["Agents can read"], ["models", "datasets", "hub"]),
381 mcp("context7", "Context7", "docs", "Agents read current documentation for the libraries a codebase uses, through Context7's MCP server.", { url: "https://mcp.context7.com/mcp", auth: "none" }, ["Agents can read"], ["documentation", "libraries"]),
382 mcp("microsoft-learn", "Microsoft Learn", "docs", "Agents search Microsoft's documentation for Azure, .NET and Windows, through Microsoft Learn's MCP server.", { url: "https://learn.microsoft.com/api/mcp", auth: "none" }, ["Agents can read"], ["azure", "dotnet", "documentation"]),
383 mcp("deepwiki", "DeepWiki", "docs", "Agents read generated documentation for public repositories, through DeepWiki's MCP server.", { url: "https://mcp.deepwiki.com/mcp", auth: "none" }, ["Agents can read"], ["repositories", "documentation"]),
384
385 // Data & analytics ------------------------------------------------------
386 soon("postgresql", "PostgreSQL", "data", W, "Agents read your schema, and run read-only queries while they investigate.", ["Agents can read"]),
387 soon("snowflake", "Snowflake", "data", W, "Agents answer questions from your warehouse with read-only queries.", ["Agents can read"]),
388 soon("bigquery", "BigQuery", "data", W, "Agents answer questions from your datasets with read-only queries.", ["Agents can read"]),
389 mcp("posthog", "PostHog", "data", "Agents read product analytics, feature flags and errors in PostHog, through PostHog's MCP server.", { url: "https://mcp.posthog.com/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["analytics", "feature flags"]),
390 mcp("supabase", "Supabase", "data", "Agents read your Supabase projects, schemas and logs, and run queries, through Supabase's MCP server.", { url: "https://mcp.supabase.com/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["postgres", "database"]),
391 mcp("neon", "Neon", "data", "Agents read and manage Neon Postgres projects and branches, through Neon's MCP server.", { url: "https://mcp.neon.tech/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["postgres", "database"]),
392 soon("amplitude", "Amplitude", "data", W, "Agents read the charts that work refers to.", ["Agents can read"]),
393 soon("segment", "Segment", "data", W, "Agents read your tracking plan, and check new events against it.", ["Agents can read"]),
394
395 // CRM & support ---------------------------------------------------------
396 soon("zendesk", "Zendesk", "crm", W, "Turn a ticket into an issue, and tell the customer when the fix ships.", ["Opens issues", "Writes back"]),
397 mcp("intercom", "Intercom", "crm", "Agents search conversations, contacts and companies in Intercom, through Intercom's MCP server.", { url: "https://mcp.intercom.com/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["support", "conversations", "customers"]),
398 mcp("hubspot", "HubSpot", "crm", "Agents read contacts, companies and deals in HubSpot, through HubSpot's MCP server.", { url: "https://mcp.hubspot.com/anthropic", auth: "oauth" }, ["Agents can read", "Agents can act"], ["crm", "contacts", "deals"]),
399 soon("salesforce", "Salesforce", "crm", W, "Agents read the account and case behind a request.", ["Agents can read"]),
400 mcp("stripe", "Stripe", "crm", "Agents read customers, payments and subscriptions, and look things up in Stripe's docs, through Stripe's MCP server.", { url: "https://mcp.stripe.com", auth: "oauth" }, ["Agents can read", "Agents can act"], ["payments", "billing", "customers"]),
401 mcp("paypal", "PayPal", "crm", "Agents read and manage orders, invoices and subscriptions, through PayPal's MCP server.", { url: "https://mcp.paypal.com/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["payments", "invoices"]),
402
403 // Design ----------------------------------------------------------------
404 mcp("figma", "Figma", "design", "Agents read designs, components and variables from your Figma files, and build to them, through Figma's MCP server.", { url: "https://mcp.figma.com/mcp", auth: "oauth" }, ["Agents can read"], ["design", "frames", "components"]),
405 mcp("canva", "Canva", "design", "Agents search, create and export Canva designs, through Canva's MCP server.", { url: "https://mcp.canva.com/mcp", auth: "oauth" }, ["Agents can read", "Agents can act"], ["design", "slides"]),
406 soon("miro", "Miro", "design", W, "Agents read the boards linked from issues and chat.", ["Agents can read"]),
407 soon("storybook", "Storybook", "design", W, "Each pull request's stories as a check, with what changed.", ["Agents can read"]),
408
409 // Security & identity ---------------------------------------------------
410 soon("okta", "Okta", "security", W, "Single sign-on, and people added and removed with your directory.", ["Signs you in", "Syncs people"]),
411 soon("entra-id", "Microsoft Entra ID", "security", W, "Single sign-on, and people added and removed with your directory.", ["Signs you in", "Syncs people"]),
412 soon("google-workspace", "Google Workspace", "security", BOTH, "Single sign-on, and people added and removed with your directory.", ["Signs you in", "Syncs people"], {
413 description: "Sign in to g1t with your Google account.",
414 capabilities: ["Signs you in"],
415 }),
416 soon("1password", "1Password", "security", W, "Secrets from a vault, read by workflows and deployments when they run.", ["Deploys"]),
417 soon("snyk", "Snyk", "security", W, "Findings open issues, and an agent opens the fix.", ["Opens issues"]),
418
419 // Files & storage -------------------------------------------------------
420 soon("google-drive", "Google Drive", "files", BOTH, "Agents read the files linked from issues and chat.", ["Agents can read"], {
421 description: "Attach files from your Drive in chat, without downloading them first.",
422 capabilities: ["Agents can read"],
423 }),
424 soon("dropbox", "Dropbox", "files", BOTH, "Agents read the files linked from issues and chat.", ["Agents can read"], {
425 description: "Attach files from your Dropbox in chat.",
426 capabilities: ["Agents can read"],
427 }),
428 soon("onedrive", "OneDrive and SharePoint", "files", BOTH, "Agents read the files linked from issues and chat.", ["Agents can read"], {
429 description: "Attach files from your OneDrive in chat.",
430 capabilities: ["Agents can read"],
431 }),
432 soon("box", "Box", "files", W, "Agents read the files linked from issues and chat.", ["Agents can read"]),
433];
434
435/** The connector by its id. */
436export function connectorById(id: string): Connector | undefined {
437 return CONNECTORS.find((connector) => connector.id === id);
438}
439
440/** A connector as `scope` shows it, or null when it cannot be connected there. */
441export function connectorView(connector: Connector, scope: ConnectorScope): ConnectorView | null {
442 if (!connector.scopes.includes(scope)) return null;
443 const own = scope === "personal" ? connector.personal : undefined;
444 const status = own?.status ?? connector.status;
445 const other: ConnectorScope = scope === "workspace" ? "personal" : "workspace";
446 return {
447 id: connector.id,
448 name: connector.name,
449 category: connector.category,
450 description: own?.description ?? connector.description,
451 status,
452 href: status === "available" ? (connector.href?.[scope] ?? null) : null,
453 capabilities: own?.capabilities ?? connector.capabilities ?? [],
454 provider: connector.provider ?? null,
455 keywords: connector.keywords ?? [],
456 alsoIn: connector.scopes.includes(other) ? other : null,
457 mcp: connector.mcp ?? null,
458 };
459}
460
461/** Every connector `scope` can show, in catalog order. */
462export function connectorsFor(scope: ConnectorScope): ConnectorView[] {
463 return CONNECTORS.map((connector) => connectorView(connector, scope)).filter((view): view is ConnectorView => view != null);
464}
465
466/** A setup path with its `:workspace` filled in. */
467export function connectorPath(path: string, workspace: string): string {
468 return path.replace(/:workspace\b/g, encodeURIComponent(workspace));
469}