feat(mcp): add mcp connect and disconnect commands#178
Conversation
WalkthroughThis PR adds MCP connect and disconnect CLI commands, shared MCP config helpers, an OSS API for MCP status updates, tests for config and command flows, a README section for MCP Connection, and a default ChangesMCP CLI commands
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Thanks for the PR, @sarthakNITT! A quick note on our workflow: we ask contributors to open an issue first, get it assigned, then submit a PR that links it (e.g. "Closes #123"). This PR isn't linked to any issue. It'll still be reviewed, but please open an issue and claim it (comment that you'd like it assigned to you) so the work is tracked. |
There was a problem hiding this comment.
Code Review — feat(mcp): add mcp connect and disconnect commands
The overall structure is clean and the happy-path logic is sound. Three issues need resolution before merge.
🔴 Critical
1. Stray .antigravity/mcp.json committed to the CLI repository
File: .antigravity/mcp.json
{
"mcpServers": {}
}This file is almost certainly a leftover from local testing — the author ran connect antigravity inside the CLI's own source directory. It should not be committed:
- It will be bundled into the npm package and land in every consumer's
node_modules/@insforge/cli/.antigravity/mcp.json, an unexpected side-effect. - If a developer ever runs
disconnect(bare/all) from the CLI source directory, this committed file will be silently modified, producing a dirty working tree. .antigravity/should be added to.gitignorealongside the other provider config directories (.cursor/,.mcp.json, etc.).
Fix: delete .antigravity/mcp.json, add .antigravity/ to .gitignore.
🟠 Important
2. Bare disconnect (all providers) aborts on the first malformed config, leaving partial state
File: src/commands/mcp/disconnect.ts, line 22
const results = providers.map((provider) => disconnectMcpProvider(provider));
await updateMcpConnectionStatus('disconnected');Array.prototype.map is synchronous and throws immediately when disconnectMcpProvider raises a CLIError (which it does when a config file exists but contains invalid JSON). If .cline/mcp.json is malformed, providers listed after cline (roo, codex, antigravity) are never touched and updateMcpConnectionStatus is never called. The command surfaces an error, leaving local and backend state in an inconsistent, partially-cleaned-up condition.
Fix: wrap each call in a per-provider try/catch (collect errors, continue), report them in aggregate, and only call updateMcpConnectionStatus after the full sweep. Or at minimum document and accept the behaviour.
3. connectMcpProvider always rewrites the file, even when changed === false
File: src/lib/mcp-config.ts, lines 68–71
const changed = JSON.stringify(existingServers[MCP_SERVER_NAME]) !== JSON.stringify(server);
config.mcpServers = { ...existingServers, [MCP_SERVER_NAME]: server };
writeMcpJson(path, config); // ← unconditionalwriteMcpJson is called regardless of changed. A no-op connect still modifies the file's mtime, which can trigger IDE file-watchers (notably Claude Code, which watches .mcp.json). The changed flag is already computed — gating the write on it is a one-liner fix:
if (changed) {
config.mcpServers = { ...existingServers, [MCP_SERVER_NAME]: server };
writeMcpJson(path, config);
}🟡 Minor
4. JSON.stringify change detection is key-order sensitive
File: src/lib/mcp-config.ts, line 64
const changed = JSON.stringify(existingServers[MCP_SERVER_NAME]) !== JSON.stringify(server);If an existing insforge entry was written by an external tool with keys in a different order (e.g., x-api-key before Authorization), this evaluates to true and triggers a rewrite even though the values are identical. Use a field-by-field comparison or stable serialisation (sort keys) for reliability.
🔵 Cleanup
5. ProviderConfig interface wraps a single string field
File: src/lib/mcp-config.ts, lines 23–25
interface ProviderConfig {
path: string;
}
const PROVIDER_CONFIGS: Record<McpProvider, ProviderConfig> = { ... };
// always accessed as PROVIDER_CONFIGS[provider].pathThe interface adds an indirection layer with no current benefit. Record<McpProvider, string> is simpler and just as clear; the existing getMcpConfigPath helper already encapsulates all access.
Two items are required before merge: the committed stray file (1) and the partial-disconnect correctness issue (2). Issue (3) is a meaningful side-effect fix and should also be addressed. (4) and (5) can be taken in a follow-up if preferred.
| const result = connectMcpProvider(provider, project); | ||
| await updateMcpConnectionStatus('connected'); |
There was a problem hiding this comment.
Local file written but command reports failure on backend error
connectMcpProvider writes the config file on line 22 before updateMcpConnectionStatus is called on line 23. If ossFetch throws (network error, older self-hosted backend without the /api/usage/mcp/status endpoint, etc.), handleError reports an error to the user even though the local config file was already successfully modified. The user sees a failure, is left confused about whether the connect actually took effect, and may re-run the command unnecessarily.
The same race exists in disconnect.ts at the equivalent lines. Consider wrapping updateMcpConnectionStatus in a try/catch that logs a warning but doesn't fail the command, since the local-file mutation is the core user-visible outcome.
| const changed = JSON.stringify(existingServers[MCP_SERVER_NAME]) !== JSON.stringify(server); | ||
|
|
||
| config.mcpServers = { | ||
| ...existingServers, | ||
| [MCP_SERVER_NAME]: server, | ||
| }; | ||
| writeMcpJson(path, config); |
There was a problem hiding this comment.
File is always written even when the entry is unchanged
changed is computed on line 67 to detect whether the InsForge entry differs from the existing one, but writeMcpJson is called unconditionally on line 73 regardless of the result. When the entry is already up to date the file is still rewritten, changing its mtime and potentially triggering editor reloads or hot-reload loops in dev environments. The write should be guarded by if (changed).
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| export async function updateMcpConnectionStatus(status: McpConnectionStatus): Promise<void> { | ||
| await ossFetch('/api/usage/mcp/status', { | ||
| method: 'POST', | ||
| body: JSON.stringify({ status }), | ||
| }); |
There was a problem hiding this comment.
No friendly 404 handler for the new MCP status endpoint
ossFetch has specific friendly messages for 404s on /api/compute, /api/payments, /api/database/migrations, /api/ai, and /api/memory paths (lines 153–172), but nothing for /api/usage/mcp/status. Self-hosted instances running an older backend that doesn't include this endpoint will get a generic OSS request failed: 404 error, which gives the user no actionable guidance. A path-specific 404 message (similar to the others) would significantly improve the experience for self-hosted users.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/commands/mcp/disconnect.ts`:
- Around line 21-23: Avoid clearing the shared MCP status during a
single-provider disconnect in disconnectMcpProvider handling. Update the logic
around the providers map and updateMcpConnectionStatus so it only sets
disconnected when all MCP providers have been removed, and keep the shared
status unchanged when disconnectMcpProvider is called for just one provider
while others still remain connected.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: efb04659-2936-40be-83d9-a05b2756bafa
📒 Files selected for processing (10)
.antigravity/mcp.jsonREADME.mdsrc/commands/mcp/connect.tssrc/commands/mcp/disconnect.tssrc/commands/mcp/index.tssrc/commands/mcp/mcp.test.tssrc/index.tssrc/lib/api/oss.tssrc/lib/mcp-config.test.tssrc/lib/mcp-config.ts
| const providers = providerArg ? [parseMcpProvider(providerArg)] : MCP_PROVIDERS; | ||
| const results = providers.map((provider) => disconnectMcpProvider(provider)); | ||
| await updateMcpConnectionStatus('disconnected'); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map relevant files first
git ls-files 'src/commands/mcp/*' 'src/*mcp*' 'src/**/*mcp*' | sed -n '1,200p'
echo
echo '--- outline src/commands/mcp/disconnect.ts ---'
ast-grep outline src/commands/mcp/disconnect.ts --view expanded || true
echo
echo '--- search for updateMcpConnectionStatus and disconnectMcpProvider ---'
rg -n "updateMcpConnectionStatus|disconnectMcpProvider|MCP_PROVIDERS|parseMcpProvider" srcRepository: InsForge/CLI
Length of output: 3023
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the target file and related helpers with line numbers
for f in src/commands/mcp/disconnect.ts; do
echo "=== $f ==="
wc -l "$f"
cat -n "$f"
echo
done
echo "=== candidate files for connection status helpers ==="
rg -n "function updateMcpConnectionStatus|const updateMcpConnectionStatus|export .*updateMcpConnectionStatus|disconnectMcpProvider" src -A 4 -B 4Repository: InsForge/CLI
Length of output: 7738
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check whether connection status is maintained per provider or as a single backend value
rg -n "connection status|connected|disconnected|MCP_PROVIDERS|insforge" src -A 3 -B 3
echo
echo '--- any aggregated status logic ---'
rg -n "some\\(|every\\(|filter\\(|length === 0|provider.*status|status.*provider" src/commands src -A 3 -B 3Repository: InsForge/CLI
Length of output: 50369
Avoid clearing the shared MCP status on single-provider disconnect.
src/commands/mcp/disconnect.ts:21-23 still posts disconnected when only one provider is removed. If this status is meant to reflect whether any MCP provider remains connected, update it only after the last provider entry is cleared; otherwise it reports disconnected while other providers still have insforge configured.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/commands/mcp/disconnect.ts` around lines 21 - 23, Avoid clearing the
shared MCP status during a single-provider disconnect in disconnectMcpProvider
handling. Update the logic around the providers map and
updateMcpConnectionStatus so it only sets disconnected when all MCP providers
have been removed, and keep the shared status unchanged when
disconnectMcpProvider is called for just one provider while others still remain
connected.
There was a problem hiding this comment.
8 issues found across 10 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/lib/mcp-config.ts">
<violation number="1" location="src/lib/mcp-config.ts:73">
P2: The `writeMcpJson` call is unconditional even though `changed` is computed to detect whether the entry differs. When the InsForge entry is already up to date, this unnecessarily rewrites the file, changing its mtime and potentially triggering editor file-watcher reloads or hot-reload loops. Guard the write with `if (changed)` since the result already correctly reflects whether a modification occurred.</violation>
<violation number="2" location="src/lib/mcp-config.ts:135">
P1: Config files containing API keys may retain overly broad permissions when they already exist, because `writeFileSync` mode only applies on file creation.</violation>
</file>
<file name=".antigravity/mcp.json">
<violation number="1" location=".antigravity/mcp.json:1">
P1: Provider MCP config file `.antigravity/mcp.json` is committed in-repo and will be mutated by `connect` with sensitive API credentials, creating accidental commit risk.</violation>
</file>
<file name="src/commands/mcp/disconnect.ts">
<violation number="1" location="src/commands/mcp/disconnect.ts:22">
P2: Bulk disconnect is not fault-tolerant: a single malformed or unreadable provider config file aborts the entire cleanup and leaves remaining providers untouched. Each provider operation should be isolated in a try/catch so that one bad config doesn't prevent cleanup of the others.</violation>
</file>
<file name="src/lib/api/oss.ts">
<violation number="1" location="src/lib/api/oss.ts:55">
P2: Missing backward-compatibility / 404 handling for the new /api/usage/mcp/status endpoint in ossFetch. On older or self-hosted backends that do not yet implement this route, connect/disconnect flows will surface a generic 404 error instead of a clear feature-unavailable message (or graceful fallback), and the local config will have already been updated before the failure.</violation>
</file>
<file name="src/lib/mcp-config.test.ts">
<violation number="1" location="src/lib/mcp-config.test.ts:60">
P2: Missing test for disconnectMcpProvider edge case when no prior connection exists</violation>
<violation number="2" location="src/lib/mcp-config.test.ts:64">
P2: Disconnect test does not verify that non-insforge MCP entries survive disconnection</violation>
</file>
<file name="src/commands/mcp/connect.ts">
<violation number="1" location="src/commands/mcp/connect.ts:22">
P1: Non-atomic connect flow leaves local MCP config and backend status inconsistent when backend update fails</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| @@ -0,0 +1,3 @@ | |||
| { | |||
There was a problem hiding this comment.
P1: Provider MCP config file .antigravity/mcp.json is committed in-repo and will be mutated by connect with sensitive API credentials, creating accidental commit risk.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .antigravity/mcp.json:
<comment>Provider MCP config file `.antigravity/mcp.json` is committed in-repo and will be mutated by `connect` with sensitive API credentials, creating accidental commit risk.</comment>
<file context>
@@ -0,0 +1,3 @@
+{
+ "mcpServers": {}
+}
</file context>
|
|
||
| function writeMcpJson(path: string, config: JsonObject): void { | ||
| mkdirSync(dirname(path), { recursive: true }); | ||
| writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`, { mode: 0o600 }); |
There was a problem hiding this comment.
P1: Config files containing API keys may retain overly broad permissions when they already exist, because writeFileSync mode only applies on file creation.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/mcp-config.ts, line 135:
<comment>Config files containing API keys may retain overly broad permissions when they already exist, because `writeFileSync` mode only applies on file creation.</comment>
<file context>
@@ -0,0 +1,140 @@
+
+function writeMcpJson(path: string, config: JsonObject): void {
+ mkdirSync(dirname(path), { recursive: true });
+ writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`, { mode: 0o600 });
+}
+
</file context>
| if (!project) throw new ProjectNotLinkedError(); | ||
|
|
||
| const provider = parseMcpProvider(providerArg ?? 'cursor'); | ||
| const result = connectMcpProvider(provider, project); |
There was a problem hiding this comment.
P1: Non-atomic connect flow leaves local MCP config and backend status inconsistent when backend update fails
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/mcp/connect.ts, line 22:
<comment>Non-atomic connect flow leaves local MCP config and backend status inconsistent when backend update fails</comment>
<file context>
@@ -0,0 +1,55 @@
+ if (!project) throw new ProjectNotLinkedError();
+
+ const provider = parseMcpProvider(providerArg ?? 'cursor');
+ const result = connectMcpProvider(provider, project);
+ await updateMcpConnectionStatus('connected');
+ captureEvent(project.project_id, 'cli_mcp_connect', {
</file context>
| ...existingServers, | ||
| [MCP_SERVER_NAME]: server, | ||
| }; | ||
| writeMcpJson(path, config); |
There was a problem hiding this comment.
P2: The writeMcpJson call is unconditional even though changed is computed to detect whether the entry differs. When the InsForge entry is already up to date, this unnecessarily rewrites the file, changing its mtime and potentially triggering editor file-watcher reloads or hot-reload loops. Guard the write with if (changed) since the result already correctly reflects whether a modification occurred.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/mcp-config.ts, line 73:
<comment>The `writeMcpJson` call is unconditional even though `changed` is computed to detect whether the entry differs. When the InsForge entry is already up to date, this unnecessarily rewrites the file, changing its mtime and potentially triggering editor file-watcher reloads or hot-reload loops. Guard the write with `if (changed)` since the result already correctly reflects whether a modification occurred.</comment>
<file context>
@@ -0,0 +1,140 @@
+ ...existingServers,
+ [MCP_SERVER_NAME]: server,
+ };
+ writeMcpJson(path, config);
+
+ return {
</file context>
| if (!project) throw new ProjectNotLinkedError(); | ||
|
|
||
| const providers = providerArg ? [parseMcpProvider(providerArg)] : MCP_PROVIDERS; | ||
| const results = providers.map((provider) => disconnectMcpProvider(provider)); |
There was a problem hiding this comment.
P2: Bulk disconnect is not fault-tolerant: a single malformed or unreadable provider config file aborts the entire cleanup and leaves remaining providers untouched. Each provider operation should be isolated in a try/catch so that one bad config doesn't prevent cleanup of the others.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/mcp/disconnect.ts, line 22:
<comment>Bulk disconnect is not fault-tolerant: a single malformed or unreadable provider config file aborts the entire cleanup and leaves remaining providers untouched. Each provider operation should be isolated in a try/catch so that one bad config doesn't prevent cleanup of the others.</comment>
<file context>
@@ -0,0 +1,69 @@
+ if (!project) throw new ProjectNotLinkedError();
+
+ const providers = providerArg ? [parseMcpProvider(providerArg)] : MCP_PROVIDERS;
+ const results = providers.map((provider) => disconnectMcpProvider(provider));
+ await updateMcpConnectionStatus('disconnected');
+ const changed = results.some((result) => result.changed);
</file context>
|
|
||
| export type McpConnectionStatus = 'connected' | 'disconnected'; | ||
|
|
||
| export async function updateMcpConnectionStatus(status: McpConnectionStatus): Promise<void> { |
There was a problem hiding this comment.
P2: Missing backward-compatibility / 404 handling for the new /api/usage/mcp/status endpoint in ossFetch. On older or self-hosted backends that do not yet implement this route, connect/disconnect flows will surface a generic 404 error instead of a clear feature-unavailable message (or graceful fallback), and the local config will have already been updated before the failure.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/api/oss.ts, line 55:
<comment>Missing backward-compatibility / 404 handling for the new /api/usage/mcp/status endpoint in ossFetch. On older or self-hosted backends that do not yet implement this route, connect/disconnect flows will surface a generic 404 error instead of a clear feature-unavailable message (or graceful fallback), and the local config will have already been updated before the failure.</comment>
<file context>
@@ -50,6 +50,15 @@ export async function getJwtSecret(): Promise<string | null> {
+export type McpConnectionStatus = 'connected' | 'disconnected';
+
+export async function updateMcpConnectionStatus(status: McpConnectionStatus): Promise<void> {
+ await ossFetch('/api/usage/mcp/status', {
+ method: 'POST',
</file context>
| }); | ||
| }); | ||
|
|
||
| it('removes only the insforge MCP server', () => { |
There was a problem hiding this comment.
P2: Missing test for disconnectMcpProvider edge case when no prior connection exists
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/mcp-config.test.ts, line 60:
<comment>Missing test for disconnectMcpProvider edge case when no prior connection exists</comment>
<file context>
@@ -0,0 +1,74 @@
+ });
+ });
+
+ it('removes only the insforge MCP server', () => {
+ const cwd = tempDir();
+ connectMcpProvider('claude-code', project, cwd);
</file context>
| const cwd = tempDir(); | ||
| connectMcpProvider('claude-code', project, cwd); | ||
|
|
||
| const result = disconnectMcpProvider('claude-code', cwd); |
There was a problem hiding this comment.
P2: Disconnect test does not verify that non-insforge MCP entries survive disconnection
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/mcp-config.test.ts, line 64:
<comment>Disconnect test does not verify that non-insforge MCP entries survive disconnection</comment>
<file context>
@@ -0,0 +1,74 @@
+ const cwd = tempDir();
+ connectMcpProvider('claude-code', project, cwd);
+
+ const result = disconnectMcpProvider('claude-code', cwd);
+ const config = JSON.parse(readFileSync(getMcpConfigPath('claude-code', cwd), 'utf-8'));
+
</file context>
|
@sarthakNITT Why do you think it's necessary to support mcp connection within CLI? In project's Install page, we've provided the different paths for CLI and MCP. |
|
@jwfing Currently
The agent verification step (sending the prompt to confirm the agent is working) remains as a separate step, connect handles the config + status, verification confirms the agent is functioning correctly. These are two different things. Also planning to make both commands accept |
There was a problem hiding this comment.
1 issue found across 5 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/lib/api/oss.ts">
<violation number="1" location="src/lib/api/oss.ts:60">
P1: The opts path sends the Bearer API key to an arbitrary caller-provided apiBaseUrl without URL validation or domain checks. Callers (connect.ts and disconnect.ts) source apiBaseUrl from raw CLI options, so a malicious or mistyped URL can receive the secret API key, enabling credential exfiltration.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| opts?: { apiKey: string; apiBaseUrl: string } | ||
| ): Promise<void> { | ||
| if (opts) { | ||
| const res = await fetch(`${opts.apiBaseUrl.replace(/\/$/, '')}/api/usage/mcp/status`, { |
There was a problem hiding this comment.
P1: The opts path sends the Bearer API key to an arbitrary caller-provided apiBaseUrl without URL validation or domain checks. Callers (connect.ts and disconnect.ts) source apiBaseUrl from raw CLI options, so a malicious or mistyped URL can receive the secret API key, enabling credential exfiltration.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/api/oss.ts, line 60:
<comment>The opts path sends the Bearer API key to an arbitrary caller-provided apiBaseUrl without URL validation or domain checks. Callers (connect.ts and disconnect.ts) source apiBaseUrl from raw CLI options, so a malicious or mistyped URL can receive the secret API key, enabling credential exfiltration.</comment>
<file context>
@@ -52,7 +52,25 @@ export async function getJwtSecret(): Promise<string | null> {
+ opts?: { apiKey: string; apiBaseUrl: string }
+): Promise<void> {
+ if (opts) {
+ const res = await fetch(`${opts.apiBaseUrl.replace(/\/$/, '')}/api/usage/mcp/status`, {
+ method: 'POST',
+ headers: {
</file context>
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
|
@sarthakNITT could you please upload an screenshot or video for testing this feature? |
|
@jwfing Here the screen recording of behaviour. Screen.Recording.2026-06-27.at.12.04.31.AM.movThis pr fix - Users can connect and disconnect by just one terminal command. After running disconnect command it removes the insforge mcp and also updates the dashboard in real time. Works for both cli and GUI users. Screen.Recording.2026-06-27.at.12.14.25.AM.movClarification for your error - The Since InsForge/InsForge#1581 PR isn't merged yet, running these commands against the original OSS codebase returns 404 because the route doesn't exist there. Once both PRs are merged, it will work end-to-end. These CLI commands are also not yet published to npm, so they can't be run with the insforge prefix directly, they need to be run via the local build path |
|
@sarthakNITT Thanks for the explaination. If someone connected with multi agents(for example, claude-code on machine A, codex on machine B), then he disconnected with claude-code, what's the final status? |
|
The connection status is designed to track onboarding progress, not the agent's actual runtime state. So even if it shows "connected" or "disconnected," it doesn't necessarily mean the agent itself is up or down. But I am open to discuss more. |
|
@jwfing I think this opens up an opportunity to redesign the dashboard a bit. Instead of only showing a binary “Connected” state, it could serve as a real-time overview of what’s happening in Insforge - active connections, number of connected agents, runtime status, recent activity, etc. That would give users a single place to verify what they’re doing and significantly improve the overall UX. If this direction sounds good, I’d be happy to work on redesigning the dashboard and take up this issue. |
|
@sarthakNITT Thank your for contributing this PR, we discussed internally and didn't think it's necessary to sync real-time status of multiple agents. I am wondering what is the painpoint you had that causes you to write this PR... if it sounds reasonable we can continue to this solution. |
|
@jwfing Even if the status is currently used for onboarding, a dashboard that permanently shows "Connected" after a user has manually disconnected feels like a bug. It leaves users confused about whether InsForge is still active or has access to their local environment. To answer your question on the multi-agent scenario: the backend status endpoint can easily track status per agent (e.g., claude-code: disconnected, codex: connected). The dashboard can then display exactly which agents are currently active. This gives users clear visibility, avoids stale UI states, and ensures they know exactly when InsForge is active or inactive on their system. Basically my pain point was having no instructions on how to disconnect, and even after doing it manually, the dashboard still showed 'Connected' leaving me confused if the disconnection actually succeeded. Let me know if it sounds like an important behavior to support. |
Adds two new top-level CLI commands
connectanddisconnectfor managing the InsForge MCP server entry in local AI coding agent config files.reference - InsForge/InsForge#1581
Why:
Previously, users had to manually edit config files
(e.g. .cursor/mcp.json)to wire up InsForge MCP. These commands automate that entirely after a project is linked withnpx @insforge/cli link.Changes
New files:
src/commands/mcp/connect.ts- connect [provider] command: writes the InsForge MCP server entry into the provider's config file and marks the backend status as connectedsrc/commands/mcp/disconnect.ts- disconnect [provider] command: removes the InsForge MCP entry from the provider's config file and marks backend status as disconnected. Without a provider arg, cleans up all known config filessrc/lib/mcp-config.ts- core logic for reading/writing provider MCP config files, building the MCP server config from linked project credentialssrc/lib/mcp-config.test.ts- unit tests for mcp-config helpersModified:
src/index.ts- registers the two new commandssrc/lib/api/oss.ts- addsupdateMcpConnectionStatus()to callPOST /api/usage/mcp/statuson the linked backendREADME.md- expands the MCP Connection section with full command reference, provider table, and config file pathsSupported providers - cursor, claude-code, windsurf, cline, roo, codex, antigravity.
Usage:
npx @insforge/cli connect cursornpx @insforge/cli disconnect cursornpx @insforge/cli disconnect# removes from all known configsSummary by cubic
Adds
connectanddisconnectCLI commands to auto-configure the InsForge MCP server in local agent configs and keep backend connection status in sync. You can also run them without a linked project by passing an API key and base URL.New Features
npx @insforge/cli connect [provider]anddisconnect [provider]manage only theinsforgeMCP entry (default provider:cursor).--api-keyand--api-base-url; otherwise reads.insforge/project.json.updateMcpConnectionStatus('connected'|'disconnected'), using provided creds when passed.--jsonoutput; config files are written with 0600 perms.claude), windsurf, cline, roo, codex, antigravity; paths handled insrc/lib/mcp-config.ts.Migration
npx @insforge/cli linkor use--api-keyand--api-base-url.npx @insforge/cli connect cursor,npx @insforge/cli disconnect cursor, ornpx @insforge/cli disconnectto remove from all supported configs.Written for commit 254221d. Summary will update on new commits.
Note
Add
mcp connectandmcp disconnectCLI commandsconnect [provider]command that writes or updates aninsforgeMCP server entry (withAuthorizationandx-api-keyheaders) in the target provider's local config file, then marks backend MCP status as connected.disconnect [provider]command that removes theinsforgeentry from one or all supported provider config files and marks backend MCP status as disconnected.cursor,claude-code,windsurf,cline,roo,codex,antigravity) with alias resolution (e.g.claude→claude-code); config paths are resolved per-provider relative to cwd.--api-keyand--api-base-urlflags for use without a linked project, and emit JSON or human-readable output including the config path and whether the file was changed.updateMcpConnectionStatusin oss.ts to POST connection status updates to/api/usage/mcp/status.Macroscope summarized 254221d.
Summary by CodeRabbit
New Features
Bug Fixes
Tests