Skip to main content
Glama
README.md
# Gealo MCP Server

**Hosted remote [Model Context Protocol](https://modelcontextprotocol.io) server for [Gealo](https://gealo.app) workspaces.**

Connect Claude, Cursor, VS Code, Codex, or Gemini CLI to your organization's tasks, projects, meetings, documents, and chat — with OAuth 2.1, tenant isolation, and the same project permissions you have in the app.

> **The MCP server runs on Gealo's infrastructure** at your tenant URL (`https://{slug}.gealo.app/mcp`). This repository documents the public integration surface and ships an **optional STDIO bridge** Docker image for MCP clients that only support local subprocess transport.

## Endpoint

Every Gealo organization has its own MCP endpoint:

```
https://{your-tenant-slug}.gealo.app/mcp
```

Example: workspace `acme` → `https://acme.gealo.app/mcp`

Copy the exact URL from **Tenant → AI Agents** after sign-in.

### Discovery

OAuth protected-resource metadata is published per tenant:

```
GET https://{your-tenant-slug}.gealo.app/.well-known/oauth-protected-resource/mcp
```

## Transport

Gealo's hosted MCP server uses **Streamable HTTP** at `/mcp` (MCP 2025-03-26+). It also supports **session-backed SSE** when clients send `Accept: text/event-stream` and maintain an `Mcp-Session-Id`. **stdio is not served by Gealo** — clients that only speak stdio need a local bridge (see Docker image below).

| Transport | Gealo hosted server | This Docker image |
|-----------|--------------------|-------------------|
| Streamable HTTP | Yes (primary) | Proxied to remote |
| SSE (session) | Yes (optional) | Proxied when client requests it |
| stdio | No | **Local side only** (bridge speaks stdio to your MCP client) |

## Authentication

- **Interactive (default):** OAuth 2.1 + PKCE. Your MCP client (or the bridge) opens a browser consent flow on first connect. Tokens are stored **locally** by the client/bridge (`~/.mcp-auth` or `MCP_REMOTE_CONFIG_DIR`), not on Gealo beyond server-side refresh-token rotation metadata.
- **Scopes:** `mcp:read` (default), `mcp:write` (when tenant admin enables write tools)
- **Headless / CI:** Service accounts via `client_credentials` grant (Tenant → AI Agents → Service Accounts)

```bash
curl -X POST "https://{slug}.gealo.app/oauth/mcp/token" \
  -d grant_type=client_credentials \
  -d client_id=sa:{service-account-id} \
  -d client_secret={api-key} \
  -d scope=mcp:read \
  -d resource=https://{slug}.gealo.app/mcp
```

Use the returned `access_token` as `Authorization: Bearer` on `POST /mcp`.

## Quick connect (recommended — no Docker)

Replace `{slug}` with your tenant slug. **Prefer direct remote URL** when your client supports HTTP + OAuth natively.

### Cursor

`~/.cursor/mcp.json` or project `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "gealo": {
      "url": "https://{slug}.gealo.app/mcp"
    }
  }
}
```

Cursor opens the OAuth consent flow on first use.

See also: [examples/cursor-mcp.json](./examples/cursor-mcp.json)

### Claude (Desktop / Web)

1. **Settings → Connectors → Add custom connector**
2. URL: `https://{slug}.gealo.app/mcp`
3. **Advanced → OAuth Client ID:** `claude` (secret empty)
4. Complete sign-in and consent in the browser

### VS Code (Copilot agent mode)

`.vscode/mcp.json`:

```json
{
  "servers": {
    "gealo": {
      "type": "http",
      "url": "https://{slug}.gealo.app/mcp"
    }
  }
}
```

See also: [examples/vscode-mcp.json](./examples/vscode-mcp.json)

### Codex CLI

`~/.codex/config.toml`:

```toml
[mcp_servers.gealo]
url = "https://{slug}.gealo.app/mcp"
```

Then: `codex mcp login gealo`

### Gemini CLI

`~/.gemini/settings.json`:

```json
{
  "mcpServers": {
    "gealo": {
      "httpUrl": "https://{slug}.gealo.app/mcp"
    }
  }
}
```

Then `/mcp auth gealo` if needed.

## Docker image (optional STDIO bridge)

**Image:** `ghcr.io/mhdyousuf/gealo-mcp:latest`  
**Purpose:** Lets **stdio-only** MCP clients connect to Gealo's **hosted** Streamable HTTP endpoint. The container is **not** the Gealo MCP server — it is a local proxy.

Use Docker when:

- Your MCP client only supports `command` / stdio servers
- You need OAuth bridging for a client without native remote MCP support

Do **not** use Docker when your client supports `url` / HTTP remote MCP (Cursor, VS Code, Claude Web, Codex, Gemini) — connect directly to `https://{slug}.gealo.app/mcp`.

### Environment variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `GEALO_TENANT_SLUG` | Yes* | — | Tenant slug (e.g. `acme` → `https://acme.gealo.app/mcp`) |
| `GEALO_MCP_URL` | Yes* | — | Full MCP URL override (alternative to slug) |
| `GEALO_AUTH_MODE` | No | `oauth` | `oauth` (interactive PKCE) or `service_account` (headless) |
| `GEALO_TRANSPORT` | No | `http-only` | Remote transport strategy passed to the bridge (`http-only` recommended) |
| `GEALO_SCOPE` | No | `mcp:read` | OAuth / service-account scope |
| `GEALO_CLIENT_ID` | SA only | — | Service account ID (`sa:{uuid}`) |
| `GEALO_CLIENT_SECRET` | SA only | — | Service account API key |
| `GEALO_OAUTH_CALLBACK_PORT` | No | auto | OAuth callback port (map with `-p` in Docker) |
| `GEALO_ENABLE_HTTP_PROXY` | No | `false` | Set `true` to honor `HTTP_PROXY` / `HTTPS_PROXY` |
| `MCP_REMOTE_CONFIG_DIR` | No | `/home/gealo/.mcp-auth` | OAuth token cache directory (mount a volume) |

\* Set `GEALO_TENANT_SLUG` **or** `GEALO_MCP_URL`.

**Security:** Never bake secrets into the image. Pass service-account credentials via env at runtime. Mount a named volume for OAuth tokens so reconnects do not re-prompt.

### Local testing

```bash
# Build
docker build -t ghcr.io/mhdyousuf/gealo-mcp:local .

# Health check (discovery endpoint reachable)
docker run --rm -e GEALO_TENANT_SLUG=acme ghcr.io/mhdyousuf/gealo-mcp:local dist/health.js

# Interactive OAuth bridge (stdio — pipe JSON-RPC for manual tests)
docker run -i --rm \
  -e GEALO_TENANT_SLUG=acme \
  -p 3333:3333 \
  -v gealo-mcp-auth:/home/gealo/.mcp-auth \
  ghcr.io/mhdyousuf/gealo-mcp:local

# Service account (headless)
docker run -i --rm \
  -e GEALO_TENANT_SLUG=acme \
  -e GEALO_AUTH_MODE=service_account \
  -e GEALO_CLIENT_ID=sa:YOUR-SA-ID \
  -e GEALO_CLIENT_SECRET=YOUR-API-KEY \
  ghcr.io/mhdyousuf/gealo-mcp:local
```

```bash
# Node (without Docker)
npm install && npm run build
GEALO_TENANT_SLUG=acme npm start
```

### Docker + Cursor (stdio clients)

See [examples/cursor-mcp-docker.json](./examples/cursor-mcp-docker.json). Map port `3333` for the OAuth browser callback on first connect.

### Docker + VS Code

See [examples/vscode-mcp-docker.json](./examples/vscode-mcp-docker.json).

### Docker + service accounts / CI

See [examples/cursor-mcp-service-account-docker.json](./examples/cursor-mcp-service-account-docker.json).

### Publishing

GitHub Actions workflow [`.github/workflows/publish-docker.yml`](./.github/workflows/publish-docker.yml) publishes to GHCR using `GITHUB_TOKEN`:

- `ghcr.io/mhdyousuf/gealo-mcp:latest` (on `main`)
- `ghcr.io/mhdyousuf/gealo-mcp:<version>` (from `package.json` and git tags `v*`)

Make the package public in GitHub → Packages after the first successful publish.

## First tool call

After connecting, call **`whoami`** to ground the session:

- User, tenant, and plan
- Remaining monthly MCP tool budget
- Whether write tools are enabled for your token

Use **`search_tools`** to browse the catalog filtered to your permissions.

## Tools (60+)

Tools are scoped to your tenant and project permissions. Writes require admin opt-in (`mcp:write` scope).

| Group | Tools |
|-------|-------|
| **Core** | `whoami`, `search_tools`, `execute_tool`, `apply_pending_action` |
| **Projects** | `list_projects`, `get_project_overview`, `archive_project`, `list_task_statuses`, `create_task_status`, `update_task_status`, `delete_task_status`, `reorder_task_statuses`, `list_custom_fields`, `create_custom_field`, `update_custom_field`, `delete_custom_field` |
| **Tasks** | `search_tasks`, `get_task`, `create_task`, `update_task`, `assign_task`, `bulk_update_task_status`, `add_comment`, `list_task_comments`, `add_task_comment`, `update_task_comment`, `delete_task_comment`, `list_task_dependencies`, `add_task_dependency`, `remove_task_dependency` |
| **Sprints & releases** | `list_sprints`, `get_sprint`, `create_sprint`, `update_sprint`, `start_sprint`, `complete_sprint`, `delete_sprint`, `list_releases`, `get_release`, `create_release`, `update_release`, `delete_release`, `set_task_releases` |
| **Meetings & chat** | `list_meetings`, `get_meeting`, `search_messages` |
| **Documents & search** | `search_documents`, `semantic_search`, `answer_from_workspace`, `find_related_docs` |
| **Insights** | `summarize_project`, `summarize_workspace`, `find_blockers`, `review_sprint`, `compare_releases`, `summarize_meeting`, `extract_action_items`, `get_recent_activity` |
| **Workforce** | `my_work`, `my_leave_balance`, `workspace_health`, `usage_report` |
| **Notifications** | `list_notifications`, `get_unread_notification_count`, `mark_notification_read`, `mark_all_notifications_read` |

Catalog tools (e.g. sprint/release write ops) are reachable via `search_tools` → `execute_tool` when your role allows.

## Requirements

- A Gealo workspace with **MCP access** on your plan
- Active membership in that tenant (agents act **as you**)
- MCP not disabled by a workspace admin

## Governance

- **Tenant isolation** — every call is scoped to your workspace `tenant_id`
- **Project permissions** — same templates as the REST API; no privilege escalation via MCP
- **Read by default** — writes off until an owner enables them
- **Destructive preview** — archive, bulk status, delete comment, etc. return a preview token; `apply_pending_action` confirms (10-minute expiry)
- **Audit & metering** — tool calls logged; monthly caps from your subscription entitlements

Details: [gealo.app/mcp-server/governance](https://gealo.app/mcp-server/governance)

## Multi-tenant users

Connections are **per organization**. Add one server entry per tenant slug you work in.

## Troubleshooting

| Symptom | Likely cause |
|---------|----------------|
| `401` | Token expired or revoked — reconnect |
| `policy_violation:mcp_disabled` | Admin disabled MCP for the tenant |
| `policy_violation:mcp_client_blocked` | Client blocked in Tenant → AI Agents |
| `limit_reached:mcpAccess` | Plan does not include MCP |
| `limit_reached:mcpMonthlyToolCalls` | Monthly tool budget exhausted |
| `policy_violation:mcp_write_disabled` | Write tools not enabled — ask admin |
| `forbidden` on writes | Token lacks `mcp:write` — re-authorize |
| Few or no tools | Your role lacks module permissions |

## Links

- Product: [gealo.app](https://gealo.app)
- MCP overview: [gealo.app/mcp-server](https://gealo.app/mcp-server)
- Governance: [gealo.app/mcp-server/governance](https://gealo.app/mcp-server/governance)
- Sign up: [gealo.app/register](https://gealo.app/register)

## License

MIT — see [LICENSE](./LICENSE). Gealo is a commercial product; this repo documents the public MCP integration surface only.