Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 30 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Now when your agent needs deep codebase analysis, large-scale refactoring, or co

- **4-Agent Swarm** — Grok 4.20 coordinates multiple agents for deeper analysis
- **Massive Context** — ~2M token window, handles entire codebases
- **Native MCP Server** — Grok appears as a first-class tool in Claude Code
- **Multi-Turn Sessions** — Stateful conversations with Grok across multiple calls
- **5 Modes** — Analyze, Refactor, Code, Reason, Orchestrate
- **Tool Passthrough** — Pass OpenAI-format tool schemas for function calling
- **File Writing** — Write annotated code blocks directly to disk
Expand Down Expand Up @@ -258,26 +260,36 @@ claude mcp add morphllm

## Architecture

### Claude Code (MCP — Preferred)

```
Claude Code
│ native MCP tool calls
grok_server.py (MCP stdio server)
│ manages sessions, dispatches tools
grok_bridge.py (Python/OpenAI SDK)
OpenRouter API → xAI Grok 4.20 Multi-Agent
```

MCP tools: `grok_query`, `grok_session_start`, `grok_session_continue`, `grok_agent`

### OpenClaw (Plugin)

```
OpenClaw Agent / Claude Code
grok_swarm tool / skill
index.js (Node wrapper)
OpenClaw Agent
│ tool call
index.ts (OpenClaw plugin)
│ spawns subprocess
grok_bridge.py (Python/OpenAI SDK)
OpenRouter API
xAI Grok 4.20 Multi-Agent Beta
Response
OpenRouter API → xAI Grok 4.20 Multi-Agent
```

---
Expand Down
45 changes: 45 additions & 0 deletions bin/grok-swarm-mcp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env node
/**
* Cross-platform wrapper for the Grok Swarm MCP server.
* Spawns python3 (or python on Windows) to run grok_server.py,
* forwarding stdin/stdout for the MCP stdio transport.
*/
const { spawn } = require('child_process');
const path = require('path');

const serverScript = path.join(__dirname, '..', 'src', 'mcp', 'grok_server.py');

// Try python3 first, fall back to python (common on Windows)
const pythonCandidates = process.platform === 'win32'
? ['python3', 'python']
: ['python3'];

function trySpawn(candidates) {
const cmd = candidates[0];
if (!cmd) {
process.stderr.write(
'ERROR: Python 3 not found. Install Python 3.8+ and ensure python3 (or python) is on PATH.\n'
);
process.exit(1);
}

const child = spawn(cmd, [serverScript], {
stdio: ['inherit', 'inherit', 'inherit'],
});

child.on('error', (err) => {
if (err.code === 'ENOENT' && candidates.length > 1) {
// python3 not found, try next candidate
trySpawn(candidates.slice(1));
} else {
process.stderr.write(`ERROR: Failed to start MCP server: ${err.message}\n`);
process.exit(1);
}
});

child.on('exit', (code) => {
process.exit(code || 0);
});
}

trySpawn(pythonCandidates);
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
],
"main": "dist/index.js",
"bin": {
"grok-swarm": "dist/index.js"
"grok-swarm": "dist/index.js",
"grok-swarm-mcp": "bin/grok-swarm-mcp.js"
},
"files": [
"bin/",
"dist/",
"src/",
"README.md",
Expand Down
19 changes: 17 additions & 2 deletions platforms/claude/.claude-plugin/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ if [ -f "$OAUTH_SCRIPT" ]; then
echo
if python3 "$OAUTH_SCRIPT"; then
log "Setup complete!"
echo
echo "Run '/grok-swarm:analyze Find bugs in this codebase' to get started."
else
error "OAuth setup failed. Set OPENROUTER_API_KEY env var as a fallback."
exit 1
Expand All @@ -65,3 +63,20 @@ else
echo " Get a key at: https://openrouter.ai/keys"
exit 1
fi

# Register MCP server for native tool integration
MCP_SERVER="${PLUGIN_ROOT}/src/mcp/grok_server.py"
if [ -f "$MCP_SERVER" ] && command -v claude >/dev/null 2>&1; then
echo
log "Registering Grok Swarm MCP server..."
if claude mcp add grok-swarm -- python3 "$MCP_SERVER" 2>/dev/null; then
log "MCP server registered — grok_query, grok_session_start/continue, grok_agent tools available"
else
warn "MCP registration failed (non-fatal). Register manually:"
warn " claude mcp add grok-swarm -- python3 $MCP_SERVER"
fi
fi

echo
echo "Run '/grok-swarm:analyze Find bugs in this codebase' to get started."
echo "Or use the native MCP tools: grok_query, grok_session_start, grok_session_continue"
86 changes: 86 additions & 0 deletions platforms/claude/commands/set-key.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
name: set-key
description: Manually save an OpenRouter API key to config. Last-resort fallback when OAuth fails. WARNING - key will be visible in conversation context.
argument-hint: YOUR_API_KEY
allowed-tools:
- Bash
---

# Set Grok Swarm API Key (Manual Fallback)

**Use this only when the OAuth flow (`/grok-swarm:setup`) has failed repeatedly.**

## Step 1 — Display security warning

Before doing anything else, output this warning verbatim to the user:

---

> **WARNING: Security Risk**
>
> You are about to paste your OpenRouter API key directly into this conversation.
> This means your API key **will be visible in the LLM context window** and may be
> stored in conversation logs.
>
> **Only proceed if you understand and accept these risks.** The recommended method
> is `/grok-swarm:setup` which uses OAuth so your key never enters the conversation.
>
> Type **yes** to confirm you accept this risk, or anything else to cancel.

---

Wait for the user's response. If they do not reply with exactly `yes` (case-insensitive), stop here and remind them to use `/grok-swarm:setup` instead.

## Step 2 — Validate the key argument

The API key is the argument passed to this command (e.g. `/grok-swarm:set-key sk-or-v1-...`).

If no argument was provided, ask the user to re-run with their key:
```
/grok-swarm:set-key YOUR_API_KEY_HERE
```
Do not ask them to type the key in a follow-up message.

## Step 3 — Save the key

Run (pass the key via environment variable so it is never interpolated into shell or Python source):
```bash
mkdir -p ~/.config/grok-swarm
GROK_SET_KEY="<the key argument>" python3 -c "
import json, os
from pathlib import Path

api_key = os.environ['GROK_SET_KEY']
config_file = Path.home() / '.config' / 'grok-swarm' / 'config.json'
existing = {}
if config_file.exists():
try:
existing = json.loads(config_file.read_text())
except Exception:
pass
existing['api_key'] = api_key
json_bytes = (json.dumps(existing, indent=2) + '\n').encode()
tmp = str(config_file.parent / f'.config.json.tmp.{os.getpid()}')
fd = os.open(tmp, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
try:
os.write(fd, json_bytes)
os.fsync(fd)
finally:
os.close(fd)
os.replace(tmp, str(config_file))
print('saved')
"
```

## Step 4 — Confirm success

Tell the user:
- Key saved to `~/.config/grok-swarm/config.json` (permissions: 600)
- Show only the first 8 characters: `sk-or-v1-...` → `sk-or-v1-` + `[redacted]`
- Suggest running `/grok-swarm:analyze Hello world` to verify the key works

## Notes

- This command exists as a last resort. Always prefer `/grok-swarm:setup` (OAuth flow).
- The key is saved with file permissions 600 (owner read/write only).
- If you need to rotate the key later, run this command again or re-run `/grok-swarm:setup`.
17 changes: 12 additions & 5 deletions platforms/claude/commands/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,20 @@ else
OAUTH_PATH="$(find /usr /usr/local ~/.local -name 'oauth_setup.py' 2>/dev/null | head -1)"
[ -n "$OAUTH_PATH" ] && PLUGIN_ROOT="$(cd "$(dirname "$OAUTH_PATH")/../.." 2>/dev/null && pwd)"
fi
timeout 240s python3 "$PLUGIN_ROOT/src/bridge/oauth_setup.py"
# timeout is not available on macOS without Homebrew coreutils (gtimeout).
# The script has an internal 180s timeout, so the outer wrapper is best-effort only.
TIMEOUT_CMD=$(command -v gtimeout 2>/dev/null || command -v timeout 2>/dev/null || true)
if [ -n "$TIMEOUT_CMD" ]; then
"$TIMEOUT_CMD" 240s python3 "$PLUGIN_ROOT/src/bridge/oauth_setup.py"
else
python3 "$PLUGIN_ROOT/src/bridge/oauth_setup.py"
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.
```

**Note**: The `timeout 240s` wrapper ensures the command terminates if the OAuth
flow exceeds 240 seconds. The script itself has an internal OAUTH_TIMEOUT_SECS
(180s) for the callback phase plus roughly 30s for token exchange, so the 240s
outer limit provides a safe margin.
**Note**: The wrapper tries `gtimeout` (macOS/Homebrew), then `timeout` (Linux)
to enforce a 240s outer limit. If neither is available (e.g. stock macOS), the
script runs without an outer wrapper — its internal `OAUTH_TIMEOUT_SECS` (180s)
for the callback phase plus ~30s for token exchange still prevents hangs.

The script will:
1. Print an authorization URL
Expand Down
21 changes: 21 additions & 0 deletions platforms/claude/skills/grok-swarm/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,27 @@ This stores your API key in `~/.claude/grok-swarm.local.md` (plugin settings pat
/grok-swarm:reason Compare microservices vs monolith for this project
```

## MCP Tools (Native Integration)

When installed via the plugin system or `claude mcp add`, Grok Swarm registers as a native MCP server. These tools are available directly — no slash commands needed:

| Tool | Description |
|------|-------------|
| `grok_query` | Stateless single call — analyze, refactor, code, or reason |
| `grok_session_start` | Begin a multi-turn conversation with Grok |
| `grok_session_continue` | Continue an existing session (Grok remembers history) |
| `grok_agent` | Run the autonomous agent loop (discover → modify → verify) |

### Multi-Turn Sessions

```
grok_session_start(mode="analyze", files=["src/auth.py"])
→ { session_id: "abc123" }

grok_session_continue(session_id="abc123", message="What about password hashing?")
→ Grok remembers the previous analysis
```

## First-Time Setup

Grok Swarm uses a PKCE OAuth flow to obtain your OpenRouter API key. **Your key never passes through the LLM context window.**
Expand Down
Loading