Skip to main content
Glama
README.md
# zoom-mcp

Zoom MCP server built from the skeleton pattern with:

- Multi-user token management.
- Vault as the persistent secret store.
- Postgres as the persistent configuration store.
- Admin-gated mutation tools through `MCP_ADMIN_AUTH_KEY`.
- Dedicated Zoom tools plus generic full-coverage API execution.
- Query suggestion and schema discovery tooling for LLM workflows.

## Architecture

Runtime components:

1. `src/index.js`: Starts stdio MCP transport.
2. `src/http/index.js`: Starts HTTP MCP transport with auth/rate controls.
3. `src/bootstrap/runtime.js`: Creates shared runtime dependencies.
4. `src/services/vault.js`: Persistent secret access in Vault.
5. `src/services/configStore.js`: Persistent config access in Postgres.
6. `src/services/zoomTokenStore.js`: User token + OAuth client persistence.
7. `src/services/targetService.js`: Zoom API and OAuth token refresh client.
8. `src/mcp/server.js`: MCP tool registration and auth gate enforcement.
9. `src/config/zoomApiCatalog.js`: Endpoint catalog for discovery/suggestions.

## Core Guarantees

- Secrets are persisted in Vault, including user access/refresh tokens and OAuth client credentials.
- Configuration is persisted in Postgres, including non-secret token metadata and arbitrary user-scoped config keys.
- All user token operations are multi-user and scoped by `userId`.
- Mutating tools require `authorizationKey` when `MCP_ADMIN_AUTH_KEY` is configured.
- Full Zoom API coverage is available through `zoom_api_request`.

## Tool Catalog

All tools return MCP text content with JSON:

```json
{
  "ok": true,
  "status": 200,
  "data": {}
}
```

Error shape (`isError=true`):

```json
{
  "ok": false,
  "status": 401,
  "error": "Unauthorized: invalid authorizationKey for mutating operation"
}
```

### Read-only tools

- `zoom_connection_info`
- `zoom_scope_info`
- `zoom_schema_discovery`
- `zoom_query_suggestion`
- `zoom_token_get_metadata`
- `zoom_oauth_client_get_metadata`
- `zoom_production_auth_env_readiness`
- `zoom_config_get`
- `zoom_config_list`
- `zoom_users_list`
- `zoom_user_get`
- `zoom_meetings_list`
- `zoom_meeting_get`
- `zoom_meeting_notes_get`
- `zoom_webinars_list`
- `zoom_recordings_list`
- `zoom_report_user_meetings`
- `zoom_phone_users_list`
- `zoom_phone_call_logs_list`
- `zoom_chat_channels_list`
- `zoom_chat_messages_list`
- `zoom_rooms_list`
- `zoom_room_get`

### Mutating tools (admin-gated when `MCP_ADMIN_AUTH_KEY` is set)

- `zoom_token_upsert`
- `zoom_token_delete`
- `zoom_oauth_client_upsert`
- `zoom_seed_initial_oauth_vault_state`
- `zoom_production_auth_env_upsert`
- `zoom_bootstrap_production_auth`
- `zoom_token_refresh`
- `zoom_config_set`
- `zoom_config_delete`
- `zoom_meeting_create`
- `zoom_meeting_update`
- `zoom_meeting_delete`
- `zoom_webinar_create`
- `zoom_webinar_delete`
- `zoom_chat_channel_create`
- `zoom_api_request` for `POST|PUT|PATCH|DELETE`

## Tool Definition Quality Fields

`zoom_query_suggestion` returns `toolSchemas` with enriched metadata for each tool including:

- When the tool should and should not be used.
- Read-only, mutating, or high-risk classification.
- Required permissions and prerequisites.
- Environment-selection behavior.
- Parameter formats and constraints.
- Expected response shape.
- Common failure conditions.
- Recommended prerequisite and follow-up tools.
- Safety warnings for destructive operations.
- Short valid invocation examples.

## Query Suggestion and Schema Discovery

Use these first in LLM workflows:

- `zoom_query_suggestion`: recommends tool execution order and safety checks.
- `zoom_schema_discovery`: searches endpoint catalog by category/method/path/text.

The catalog is broad and the fallback `zoom_api_request` tool provides full endpoint surface execution against Zoom REST APIs.

## Multi-user Token Model

Vault secret path for user tokens:

- `${APP_NAME}/users/${normalizedUserId}/zoom/oauth/tokens`

Stored fields:

- `accessToken`
- `refreshToken`
- `tokenType`
- `scope`
- `expiresAt`
- `accountId`

Postgres metadata key:

- `zoom.oauth.token.meta`

OAuth client secret path:

- `${APP_NAME}/zoom/oauth/client`

Postgres metadata key:

- `zoom.oauth.client.meta`

## Deployment Auth Setup With MCP Tools

These tools are designed for LLM-driven deployment preparation workflows:

1. Bootstrap all deployment auth setup in one call:
- `zoom_bootstrap_production_auth`

2. Seed initial OAuth client secret and per-user tokens in Vault:
- `zoom_seed_initial_oauth_vault_state`

3. Persist production `MCP_ADMIN_AUTH_KEY` and HTTP auth vars before deployment:
- `zoom_production_auth_env_upsert`

4. Validate readiness before rollout:
- `zoom_production_auth_env_readiness`

Recommended order for a new production environment:

1. Run `zoom_bootstrap_production_auth` for one-shot setup.
2. Run `zoom_production_auth_env_readiness` and confirm `ready=true`.

`zoom_production_auth_env_upsert` persists:

- Secrets in Vault path `${APP_NAME}/deployment/production/http-auth-secrets`.
- Non-secret HTTP auth config in Postgres key `deployment.production.http.auth` (default user scope).

## Environment Variables

Use `.env.example` as source of truth. Key groups:

- App and admin auth: `APP_NAME`, `MCP_SERVER_NAME`, `MCP_ADMIN_AUTH_KEY`
- User scope defaults: `MCP_CONFIG_DEFAULT_USER_ID`
- Postgres persistence: `POSTGRES_*`
- Vault persistence: `VAULT_*`
- Zoom API: `ZOOM_API_BASE_URL`, `ZOOM_OAUTH_TOKEN_URL`, `ZOOM_API_TIMEOUT_MS`
- HTTP transport and auth: `MCP_HTTP_*`

## Local Development

1. Install dependencies:

```bash
npm ci
```

2. Start infrastructure and HTTP MCP:

```bash
docker compose up -d
```

3. Start stdio MCP mode:

```bash
npm run start:stdio
```

4. Run tests:

```bash
npm test
```

## External Services Mode

Use `docker-compose.external.yml` for environments where Vault and Postgres are already provided.

- This is an app-only compose path.
- Requires external `POSTGRES_*` and `VAULT_*` values.
- Minimum required examples: `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, `VAULT_ADDR`, and `VAULT_TOKEN`.

## Security Notes

- Never place OAuth access/refresh tokens in Postgres.
- Keep `MCP_ADMIN_AUTH_KEY` enabled in non-local environments.
- Use least-privilege Zoom OAuth scopes per workload.
- For destructive endpoints, prefer dedicated tools and validate ids before execution.