Skip to content

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:

  1. Install an integration in the GUI (Marketplace > Integrations tab) and provide credentials
  2. Attach it to an agent when spawning — e.g., integrations: ["github", "stripe"]
  3. Groove handles the rest:
    • For Claude Code agents: Groove writes .mcp.json as usual — they use MCP natively
    • For all other providers: Groove injects playbook instructions into the agent's context with HTTP endpoints to call

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
  ← result

Available Integrations

IntegrationCategoryAuth TypeWhat It Does
GitHubDeveloperAPI KeyRepos, issues, PRs, code search, file operations
StripeFinanceAPI KeyCustomers, payments, subscriptions, invoices
GmailCommunicationGoogle OAuthSend, read, search, draft emails
Google CalendarProductivityGoogle OAuthEvents, availability, scheduling
Google DriveProductivityGoogle OAuthSearch and read files
Google DocsProductivityGoogle OAuthRead and edit documents
Google SheetsProductivityGoogle OAuthRead and update spreadsheets
Google SlidesProductivityGoogle OAuthRead and edit presentations
Google MapsAnalyticsAPI KeyGeocoding, directions, place search
PostgreSQLDatabaseConnection StringQuery databases, inspect schemas, run SQL
Brave SearchAnalyticsAPI KeyWeb search and local search
LinearProductivityAPI KeyIssues, projects, sprints
NotionProductivityAPI KeyPages, databases, wiki
Home AssistantSmart HomeAPI Key + URLDevice 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:

  1. Create a new project (or use an existing one)
  2. Go to APIs & Services > Credentials
  3. Click Create Credentials > OAuth client ID
  4. Set application type to Web application
  5. Add http://localhost:31415/api/integrations/oauth/callback as an Authorized redirect URI
  6. 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:

bash
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:

bash
curl http://localhost:31415/api/integrations/github/tools
json
{
  "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

bash
curl -X POST http://localhost:31415/api/integrations/github/exec \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "search_repositories",
    "params": { "query": "groove" }
  }'
json
{
  "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

  1. Agent calls POST /api/integrations/github/exec with tool: "create_issue"
  2. Groove checks the integration's requiresApproval list — create_issue is on it
  3. Groove returns 202 with an approvalId instead of executing
  4. The approval appears in the GUI's Approvals tab (and via GET /api/approvals)
  5. You review the tool name and parameters, then approve or reject
  6. The agent retries the same call with the approvalId in the request body
  7. Groove verifies the approval status and executes the tool
bash
# 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"}}'
json
{
  "requiresApproval": true,
  "approvalId": "approval-42",
  "message": "Tool \"create_issue\" requires approval. Retry with this approvalId once approved."
}
bash
# 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"}'
json
{
  "result": {
    "content": [{ "type": "text", "text": "Created issue #42 in myorg/myapp" }]
  }
}

Which tools require approval

IntegrationGated Tools
GitHubcreate_issue, create_pull_request, create_or_update_file, delete_file, push_files
Stripecreate_charge, create_payment_link, create_invoice, create_subscription, create_refund
Gmailsend_email
Google Calendarcreate_event, delete_event
Linearcreate_issue, update_issue, delete_issue
Notioncreate_page, update_page, delete_page
Home Assistantcall_service
PostgreSQL, Brave Search, Google Drive/Docs/Sheets/Slides/MapsNone — 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:

json
{
  "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 typeintegration.exec for successful calls, integration.exec.blocked for approval-gated calls, integration.exec.rate_limited for 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:

  1. Lazy start — MCP servers are not started when the daemon boots. They start on first use (first exec or tools call)
  2. Connection — the daemon spawns the MCP server as a child process with stdio pipes, sends a JSON-RPC initialize handshake, then a notifications/initialized message
  3. Pooling — once started, the server stays alive and handles multiple requests. No startup overhead after the first call
  4. Idle timeout — servers that receive no calls for 10 minutes are automatically stopped to free resources
  5. 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 JSON

Daemon Lifecycle Integration

  • StartupMcpManager is initialized with the daemon, but no servers are started
  • ShutdownmcpManager.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

ProviderHow integrations work
Claude CodeNative MCP via .mcp.json — no HTTP proxy needed
Gemini CLIHTTP exec endpoints via injected playbook
CodexHTTP exec endpoints via injected playbook
OllamaHTTP exec endpoints via injected playbook
Local Agent EngineHTTP 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.

FSL-1.1-Apache-2.0