mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 05:29:44 +02:00
feat: Add Antigravity to the MCP client connection dialog (#40879)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com> Co-authored-by: Svetoslav Dekov <svetoslav.dekov@n8n.io> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
27b43de85f
commit
f0a38cfe58
|
|
@ -3649,6 +3649,7 @@
|
|||
"settings.mcp.connectDialog.install.description": "Run this command to add n8n to {client} (it must already be installed)",
|
||||
"settings.mcp.connectDialog.configure.title": "Configure",
|
||||
"settings.mcp.connectDialog.configure.description": "Add this to your config file to connect to n8n",
|
||||
"settings.mcp.connectDialog.configure.antigravity.description": "Add this mcpServers entry to ~/.gemini/config/mcp_config.json. The Antigravity IDE, desktop app, and CLI (agy) share this file.",
|
||||
"settings.mcp.connectDialog.configure.titleAlt": "Or configure manually",
|
||||
"settings.mcp.connectDialog.configure.descriptionAlt": "Prefer not to run the command? Add this to your config file instead",
|
||||
"settings.mcp.connectDialog.authenticate.title": "Authenticate",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.7 KiB |
|
|
@ -69,6 +69,30 @@ describe('McpConnectClientDialog', () => {
|
|||
expect(body().queryByText('Authenticate')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show the shared Antigravity config file and entry', async () => {
|
||||
renderComponent({ pinia });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(body().getByTestId('mcp-connect-client-picker-trigger')).toBeInTheDocument();
|
||||
});
|
||||
await userEvent.click(body().getByTestId('mcp-connect-client-picker-trigger'));
|
||||
const menuLabel = await body().findByText('Antigravity');
|
||||
expect(
|
||||
menuLabel.closest('[role="menuitem"]')?.querySelector('svg.brand-icon'),
|
||||
).toBeInTheDocument();
|
||||
await userEvent.click(menuLabel);
|
||||
|
||||
expect(
|
||||
body().getByTestId('mcp-connect-client-picker-trigger').querySelector('svg.brand-icon'),
|
||||
).toBeInTheDocument();
|
||||
expect(body().getByText(/~\/\.gemini\/config\/mcp_config\.json/)).toHaveTextContent(
|
||||
'IDE, desktop app, and CLI (agy) share this file',
|
||||
);
|
||||
expect(body().getByTestId('mcp-config-snippet')).toHaveTextContent('mcpServers');
|
||||
expect(body().getByTestId('mcp-config-snippet')).toHaveTextContent('serverUrl');
|
||||
expect(body().queryByTestId('mcp-connect-one-click')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show only the server URL (no one-click) for web clients without a connector URL', async () => {
|
||||
renderComponent({ pinia });
|
||||
|
||||
|
|
|
|||
|
|
@ -354,7 +354,11 @@ const serverUrlDescription = computed(() =>
|
|||
layout="vertical"
|
||||
:show-divider="false"
|
||||
:title="i18n.baseText('settings.mcp.connectDialog.configure.title')"
|
||||
:description="i18n.baseText('settings.mcp.connectDialog.configure.description')"
|
||||
:description="
|
||||
activeClient.id === 'antigravity'
|
||||
? i18n.baseText('settings.mcp.connectDialog.configure.antigravity.description')
|
||||
: i18n.baseText('settings.mcp.connectDialog.configure.description')
|
||||
"
|
||||
>
|
||||
<template #action>
|
||||
<McpConfigSnippet
|
||||
|
|
|
|||
|
|
@ -11,10 +11,20 @@ describe('getMcpClientCatalog', () => {
|
|||
expect(catalog.map((group) => group.clients.map((client) => client.id))).toEqual([
|
||||
['claude-code', 'codex', 'gemini-cli'],
|
||||
['claude-ai', 'chatgpt', 'mistral-vibe'],
|
||||
['cursor', 'vscode', 'windsurf'],
|
||||
['antigravity', 'cursor', 'vscode', 'windsurf'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('should give Antigravity an HTTP server entry and keep Gemini CLI available', () => {
|
||||
const antigravity = clients.find((client) => client.id === 'antigravity');
|
||||
expect(JSON.parse(antigravity!.configSnippet!)).toEqual({
|
||||
mcpServers: { n8n: { serverUrl: SERVER_URL } },
|
||||
});
|
||||
expect(clients.find((client) => client.id === 'gemini-cli')?.installCommand).toContain(
|
||||
'gemini mcp add',
|
||||
);
|
||||
});
|
||||
|
||||
it('should embed the server URL in every install command and config snippet', () => {
|
||||
for (const client of clients) {
|
||||
if (client.installCommand) expect(client.installCommand).toContain(SERVER_URL);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import type { Component } from 'vue';
|
||||
|
||||
import AntigravityIcon from './assets/client-icons/antigravity.svg?component';
|
||||
import ClaudeIcon from './assets/client-icons/claude.svg?component';
|
||||
import CodexIcon from './assets/client-icons/codex.svg?component';
|
||||
import CursorIcon from './assets/client-icons/cursor.svg?component';
|
||||
|
|
@ -80,7 +81,7 @@ url = "${serverUrl}"`;
|
|||
}
|
||||
}
|
||||
}`;
|
||||
const windsurfSnippet = `{\n "mcpServers": {\n "n8n": {\n "serverUrl": "${serverUrl}"\n }\n }\n}`;
|
||||
const serverUrlSnippet = `{\n "mcpServers": {\n "n8n": {\n "serverUrl": "${serverUrl}"\n }\n }\n}`;
|
||||
|
||||
// One-click deep links, exactly as each editor expects: Cursor takes base64 of
|
||||
// `{"url": …}` in a `config` query param, VS Code a URL-encoded JSON object.
|
||||
|
|
@ -154,6 +155,13 @@ url = "${serverUrl}"`;
|
|||
{
|
||||
id: 'ide',
|
||||
clients: [
|
||||
{
|
||||
id: 'antigravity',
|
||||
name: 'Antigravity',
|
||||
category: 'ide',
|
||||
icon: AntigravityIcon,
|
||||
configSnippet: serverUrlSnippet,
|
||||
},
|
||||
{
|
||||
id: 'cursor',
|
||||
name: 'Cursor',
|
||||
|
|
@ -175,7 +183,7 @@ url = "${serverUrl}"`;
|
|||
name: 'Windsurf',
|
||||
category: 'ide',
|
||||
icon: null,
|
||||
configSnippet: windsurfSnippet,
|
||||
configSnippet: serverUrlSnippet,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user