# Swoogo MCP Server — Knowledge File

## Platform Setup

### Lovable

MCP server URL: `https://mcp.swoogo.io/mcp`

1. Go to **Settings > Connectors > Personal connectors**.
2. Click **Add MCP server**.
3. Enter the URL above.
4. Approve the OAuth prompt when it appears.

Transport: SSE (Lovable supports SSE only). Requires a paid plan.

### Replit

MCP server URL: `https://mcp.swoogo.io/mcp`

1. Open your Repl.
2. Go to **Agent configuration > MCP servers**.
3. Add a new MCP server with the URL above.
4. Approve the OAuth prompt when it appears.

Transport: SSE. Paste this file's content into the **Agent instructions** field.

### Cursor

MCP server URL: `https://mcp.swoogo.io/mcp/assistant`

Configure in Cursor: **Settings > MCP Servers > Add server**

```json
{
  "mcpServers": {
    "swoogo": {
      "url": "https://mcp.swoogo.io/mcp/assistant"
    }
  }
}
```

Save this file as `.cursor/rules/swoogo.md` in your project root for automatic context.

### Claude Desktop

MCP server URL: `https://mcp.swoogo.io/mcp/assistant`

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "swoogo": {
      "url": "https://mcp.swoogo.io/mcp/assistant"
    }
  }
}
```

**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

On first connection, Claude Desktop will prompt you to approve OAuth access. Enter your Swoogo API credentials (client_id and client_secret).

#### Multi-Account Setup

For multiple Swoogo accounts, add separate entries:

```json
{
  "mcpServers": {
    "swoogo-production": {
      "url": "https://mcp.swoogo.io/mcp/assistant"
    },
    "swoogo-staging": {
      "url": "https://mcp-stage.swoogo.io/mcp/assistant"
    }
  }
}
```

Each connection authenticates independently.

### Windsurf / Other MCP Clients

MCP server URL: `https://mcp.swoogo.io/mcp`

For the full assistant profile (31 tools): `https://mcp.swoogo.io/mcp/assistant`

Transport: Streamable HTTP with OAuth 2.1 + PKCE.

Configure your MCP client with:
- **Server URL**: one of the URLs above
- **Transport**: `streamable-http`
- **Authentication**: `oauth2` (the server provides `.well-known/oauth-authorization-server` metadata)

On first connection, you will be prompted to enter your Swoogo API credentials (client_id and client_secret).

## OAuth Endpoints

| Endpoint | URL |
|----------|-----|
| Authorization Server Metadata | `https://mcp.swoogo.io/.well-known/oauth-authorization-server` |
| Protected Resource Metadata | `https://mcp.swoogo.io/.well-known/oauth-protected-resource` |
| Authorization | `https://mcp.swoogo.io/oauth/authorize` |
| Token Exchange | `https://mcp.swoogo.io/oauth/token` |
| Client Registration | `https://mcp.swoogo.io/oauth/register` |

## Mandatory Workflow

When building event pages, registration forms, or any Swoogo-related UI, follow these steps in order. Skipping ANY step produces incorrect pages.

1. `swoogo-session-briefing()` — Read the rules. Do NOT skip.
2. `swoogo-get-recipe(task_type)` — Step-by-step instructions for your page type.
   - Match user intent: event page → `event_page`, registration/signup → `registration_form`, speakers → `speaker_directory`, schedule/agenda → `session_schedule`.
3. `swoogo-event-bundle(event_id)` — ALL event data + `event_features`.
4. **DISCOVERY PHASE** — Present `event_features` to the user and ask:
   - What sections? (only those with data)
   - Embedded registration form or CTA link?
   - If form: multi-page wizard or single-page?
   - If form: guide user to store client_id/client_secret securely (see API Submission).
   - Do NOT skip. Do NOT assume. Wait for answers.
5. `swoogo-get-schema(page_type)` — Page structure reference. Use `FieldValueTypes` for every form.
6. `swoogo-validate-page({ event_id, sections, speaker_ids, ... })` — MUST pass before delivering.

If validation fails: fix errors and re-validate. After 3 failures: STOP.

## Critical Rules

- **NEVER invent data.** All content must come from Swoogo tools only.
- **Choice fields** (dropDownList, radioList, checkboxList): send the choice **ID** (integer), NEVER the name.
- **Address fields**: attribute `work_address_id` → payload key `workAddress` (camelCase, drop `_id` suffix).
- **Session questions** (`sq_*`): SKIP in POST. Assign sessions via PUT with `session_ids` after creation.
- **Upload fields**: SKIP in POST. Use `PUT /image/registrant/{id}/{attribute}` after creation.
- **`.json` suffix**: REQUIRED on entity CRUD endpoints (`/registrants.json`). NOT on auth or action endpoints.
- **Flat body**: POST `/registrants.json` requires a flat body (no nested wrapper). MUST include `event_id`.
- **No required markers in UI**: the API validates server-side (422 errors).

## Adaptive Behavior

Use `event_features` from `swoogo-event-bundle` to adapt:

| Feature | If true | If false |
|---------|---------|----------|
| `has_paid_registration` | Show pricing from reg_types fees and package fees | No pricing section |
| `has_speakers` | Include speakers section | No speakers section |
| `has_sponsors` | Include sponsors section | No sponsors section |
| `has_sessions` | Include sessions/agenda section | No sessions section |
| `has_session_selection` | Render session picker (sq_* questions) | No session picker |
| `has_translations` | Show language switcher, use question.translations | Single language |
| `has_file_uploads` | Render file upload inputs | No file uploads |
| `has_packages` | Show package selector with fees | No packages |
| `page_count > 1` | Build multi-step form with navigation | Single-page form |

## Payment Integration

For paid events, the registration form must handle payments via an external gateway (Stripe, PayPal, etc.):

1. User completes registration form.
2. Frontend sends payment to your payment gateway.
3. On payment success, server-side backend calls `swoogo-create-transaction` with:
   - `event_id`, `registrant_id`, `amount`, `type` (e.g., `wire_transfer_payment`), `datetime`.
4. Amount sign is auto-controlled by type (payments → negative, refunds → positive).
5. Transactions are immutable after creation.

## API Submission

The Swoogo API has NO CORS headers — browsers cannot call it directly. You MUST build a server-side endpoint that proxies requests to the Swoogo API.

Your server-side endpoint must:
1. Store credentials securely (never in frontend code).
2. Handle OAuth token exchange (`POST /oauth2/token` with Basic auth header).
3. Forward registration POSTs to `/registrants.json`.
4. Return the response to the frontend.

**Platform-specific credential storage:**
- **Lovable**: Use a **Supabase Edge Function** with **Supabase Secrets**.
- **Replit**: Build a server-side route in your Repl backend (Express/Fastify) using **Replit Secrets**.
- **Cursor / Claude Desktop / Other**: Use environment variables or your platform's secrets manager.

## Failure Recovery

- On 422 validation error: map `error.field` to `question.attribute` and show inline.
- On 400 bad request: show general error message.
- On validation failure from `swoogo-validate-page`: fix errors and re-validate.
- After 3 consecutive validation failures: STOP and explain errors to the user.
- POST `/registrants.json` is NOT idempotent — persist `registrant_id` immediately after success.
