Integrations
Groove connects your agents to external services — GitHub, Stripe, Gmail, Google Calendar, PostgreSQL, and more — through the Model Context Protocol (MCP). Any agent on any provider can use any integration.
The Problem
MCP integrations are powerful, but they only work natively with Claude Code. If you're running agents on Gemini, Codex, Ollama, or any local model, those agents can't read .mcp.json — they have no way to call MCP tools.
This means your Gemini agent can't create GitHub issues. Your Ollama agent can't query Postgres. Your Codex agent can't send emails. The integration ecosystem is locked to a single provider.
How Groove Solves It
Groove's daemon acts as an MCP client on behalf of your agents. It speaks JSON-RPC to MCP server processes over stdio, then exposes the results as simple HTTP endpoints that any agent can call — regardless of provider.
The flow:
- Install an integration in the GUI (Marketplace > Integrations tab) and provide credentials
- Attach it to an agent when spawning — e.g.,
integrations: ["github", "stripe"] - Groove handles the rest:
- For Claude Code agents: Groove writes
.mcp.jsonas usual — they use MCP natively - For all other providers: Groove injects playbook instructions into the agent's context with HTTP endpoints to call
- For Claude Code agents: Groove writes
When a non-Claude-Code agent needs to use an integration, it makes a simple HTTP POST to the daemon. The daemon starts the MCP server (if not already running), sends the JSON-RPC request, and returns the result as plain JSON.
Agent (any provider)
→ HTTP POST to daemon
→ daemon starts MCP server process (stdio)
→ JSON-RPC request over stdin
← JSON-RPC response over stdout
← plain JSON over HTTP
← resultAvailable Integrations
| Integration | Category | Auth Type | What It Does |
|---|---|---|---|
| GitHub | Developer | API Key | Repos, issues, PRs, code search, file operations |
| Stripe | Finance | API Key | Customers, payments, subscriptions, invoices |
| Gmail | Communication | Google OAuth | Send, read, search, draft emails |
| Google Calendar | Productivity | Google OAuth | Events, availability, scheduling |
| Google Drive | Productivity | Google OAuth | Search and read files |
| Google Docs | Productivity | Google OAuth | Read and edit documents |
| Google Sheets | Productivity | Google OAuth | Read and update spreadsheets |
| Google Slides | Productivity | Google OAuth | Read and edit presentations |
| Google Maps | Analytics | API Key | Geocoding, directions, place search |
| PostgreSQL | Database | Connection String | Query databases, inspect schemas, run SQL |
| Brave Search | Analytics | API Key | Web search and local search |
| Linear | Productivity | API Key | Issues, projects, sprints |
| Notion | Productivity | API Key | Pages, databases, wiki |
| Home Assistant | Smart Home | API Key + URL | Device control, automations, states |
Setting Up an Integration
1. Install
Open the GUI at localhost:31415, go to the Marketplace, and switch to the Integrations tab. Click Install on the integration you want.
2. Configure credentials
Each integration needs credentials. The setup flow depends on the auth type:
API Key integrations (GitHub, Stripe, Linear, etc.):
- Click the integration card in the Marketplace
- Follow the setup steps shown — they'll link you to the right settings page
- Paste your API key
- Credentials are encrypted with AES-256-GCM and stored locally
Google OAuth integrations (Gmail, Calendar, Drive, etc.):
- Click Sign in with Google in the setup flow
- Your browser opens for OAuth consent
- Tokens are saved and refreshed automatically
Google OAuth Setup
For Google OAuth integrations (Gmail, Calendar, Drive, Docs, Sheets, Slides), you need to create OAuth credentials in the Google Cloud Console:
- Create a new project (or use an existing one)
- Go to APIs & Services > Credentials
- Click Create Credentials > OAuth client ID
- Set application type to Web application
- Add
http://localhost:31415/api/integrations/oauth/callbackas an Authorized redirect URI - Copy the Client ID and Client Secret into the Groove integration setup
3. Attach to an agent
When spawning an agent, select which integrations it should have access to. In the GUI's Spawn Panel, you'll see a list of installed integrations to attach.
From the API:
curl -X POST http://localhost:31415/api/agents \
-H "Content-Type: application/json" \
-d '{
"role": "backend",
"integrations": ["github", "postgres"]
}'How Agents Use Integrations
Claude Code agents
Claude Code has native MCP support. When you attach integrations to a Claude Code agent, Groove writes a .mcp.json file that Claude Code reads directly. The agent uses MCP tools as if they were built-in — no HTTP calls needed.
All other providers (Gemini, Codex, Ollama, local models)
For non-Claude-Code agents, Groove injects playbook instructions into the agent's context at spawn time. These instructions tell the agent exactly how to call each integration via HTTP.
The playbook includes:
- The HTTP endpoint to call (
POST http://localhost:31415/api/integrations/{id}/exec) - Available tools and their parameters
- Usage rules (e.g., "confirm before sending emails")
The agent then uses its standard tool-calling or code-execution capabilities to make HTTP requests to the daemon.
Discovering available tools
Any agent can list the tools an integration provides:
curl http://localhost:31415/api/integrations/github/tools{
"tools": [
{
"name": "create_issue",
"description": "Create a new issue in a GitHub repository",
"inputSchema": {
"type": "object",
"properties": {
"owner": { "type": "string" },
"repo": { "type": "string" },
"title": { "type": "string" },
"body": { "type": "string" }
},
"required": ["owner", "repo", "title"]
}
}
]
}Executing a tool
curl -X POST http://localhost:31415/api/integrations/github/exec \
-H "Content-Type: application/json" \
-d '{
"tool": "search_repositories",
"params": { "query": "groove" }
}'{
"result": {
"content": [
{
"type": "text",
"text": "Found 3 repositories matching \"groove\"..."
}
]
}
}Approval Gates
Dangerous tools require human approval before they execute. When an agent tries to create a GitHub issue, send an email, make a Stripe charge, or perform any other high-impact action, Groove pauses the call and asks you to approve it first.
How it works
- Agent calls
POST /api/integrations/github/execwithtool: "create_issue" - Groove checks the integration's
requiresApprovallist —create_issueis on it - Groove returns 202 with an
approvalIdinstead of executing - The approval appears in the GUI's Approvals tab (and via
GET /api/approvals) - You review the tool name and parameters, then approve or reject
- The agent retries the same call with the
approvalIdin the request body - Groove verifies the approval status and executes the tool
# Step 1: Agent calls a dangerous tool — gets blocked
curl -X POST http://localhost:31415/api/integrations/github/exec \
-H "Content-Type: application/json" \
-d '{"tool": "create_issue", "params": {"owner": "myorg", "repo": "myapp", "title": "Fix redirect"}}'{
"requiresApproval": true,
"approvalId": "approval-42",
"message": "Tool \"create_issue\" requires approval. Retry with this approvalId once approved."
}# Step 2: After approval — agent retries with approvalId
curl -X POST http://localhost:31415/api/integrations/github/exec \
-H "Content-Type: application/json" \
-d '{"tool": "create_issue", "params": {"owner": "myorg", "repo": "myapp", "title": "Fix redirect"}, "approvalId": "approval-42"}'{
"result": {
"content": [{ "type": "text", "text": "Created issue #42 in myorg/myapp" }]
}
}Which tools require approval
| Integration | Gated Tools |
|---|---|
| GitHub | create_issue, create_pull_request, create_or_update_file, delete_file, push_files |
| Stripe | create_charge, create_payment_link, create_invoice, create_subscription, create_refund |
| Gmail | send_email |
| Google Calendar | create_event, delete_event |
| Linear | create_issue, update_issue, delete_issue |
| Notion | create_page, update_page, delete_page |
| Home Assistant | call_service |
| PostgreSQL, Brave Search, Google Drive/Docs/Sheets/Slides/Maps | None — read-only or low-risk |
TIP
Read-only operations (searching, listing, querying) never require approval. Only write operations that create, modify, or delete external resources are gated.
Rate Limiting
Every integration is rate-limited to 30 calls per minute using a sliding window. This prevents runaway agents from flooding external APIs.
If an agent exceeds the limit, the endpoint returns 429:
{
"error": "Rate limit exceeded (30/min) for github"
}The window is per-integration, not per-agent — all agents sharing the same integration share the same 30/min budget.
Audit Logging
Every integration execution is logged to Groove's append-only audit log. Each entry records:
- Event type —
integration.execfor successful calls,integration.exec.blockedfor approval-gated calls,integration.exec.rate_limitedfor throttled calls - Integration ID — which integration was called
- Tool name — which tool was executed
- Parameters — truncated to 200 characters
- Agent ID — which agent made the call (if provided)
View the audit log with groove audit or GET /api/audit.
Under the Hood
MCP Server Lifecycle
Groove manages MCP server processes with a pool-and-reuse model:
- Lazy start — MCP servers are not started when the daemon boots. They start on first use (first
execortoolscall) - Connection — the daemon spawns the MCP server as a child process with stdio pipes, sends a JSON-RPC
initializehandshake, then anotifications/initializedmessage - Pooling — once started, the server stays alive and handles multiple requests. No startup overhead after the first call
- Idle timeout — servers that receive no calls for 10 minutes are automatically stopped to free resources
- Crash recovery — if a server process crashes, Groove retries on the next call. After 3 consecutive crashes, the integration is marked as failed and won't restart until the daemon is restarted
Request Flow
Agent calls POST /api/integrations/github/exec
→ validate: installed? tool is string? params is object?
→ rate limit check (30/min sliding window per integration)
→ exceeded? return 429 + audit log
→ approval gate check (tool in requiresApproval?)
→ no approvalId? create approval, return 202 + audit log
→ approvalId present? verify status (approved/rejected/pending)
→ McpManager.execTool("github", "create_issue", params)
→ server not running? startServer("github") first
→ JSON-RPC over stdin → await response on stdout (30s timeout)
← parse response, audit log, return result as HTTP JSONDaemon Lifecycle Integration
- Startup —
McpManageris initialized with the daemon, but no servers are started - Shutdown —
mcpManager.stopAll()sends SIGTERM to every running MCP server process during graceful shutdown - No orphans — child processes are spawned with
detached: false, so they die with the daemon
Provider Compatibility
| Provider | How integrations work |
|---|---|
| Claude Code | Native MCP via .mcp.json — no HTTP proxy needed |
| Gemini CLI | HTTP exec endpoints via injected playbook |
| Codex | HTTP exec endpoints via injected playbook |
| Ollama | HTTP exec endpoints via injected playbook |
| Local Agent Engine | HTTP exec endpoints via injected playbook |
Every provider gets the same integrations. The only difference is the transport: Claude Code talks MCP directly, everyone else goes through Groove's HTTP bridge.
