Developer docs

MCP server

Connect the AI assistant your organization already uses (Claude, ChatGPT or another client that speaks the Model Context Protocol, MCP) to Melora Connect, so it can read and update your members, events and dues invoices when you ask it to.

What it is

The MCP server gives an assistant one tool for each operation of the REST API, except the webhook subscriptions. Each tool makes the same checks, uses the same permission and limits, and gives the same answer as its endpoint.

No AI runs inside Melora Connect for this: the assistant runs where you use it, and calls Melora Connect with your organization's API key. Changes it makes are recorded in the organization's audit log with the key's name, as changes made through the API are.

Server address

The server address is:

https://app.meloraconnect.com/api/public/mcp
  • Every request carries an API key in the Authorization header, after the word Bearer, as for the REST API.
  • The transport is MCP streamable HTTP, stateless: one JSON-RPC 2.0 message per POST request, answered with JSON. There is no event stream and no session, so GET and DELETE answer 405.
  • Protocol versions: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05. The server answers with the version the client asks for when it supports it, otherwise with the newest.
  • A request sent from a web page of another site (with a different Origin header) is refused with 403.

Make a key

  1. In Melora Connect, open Settings and then the API keys tab. You need permission to manage the organization's settings.
  2. Make a key for the assistant alone, named after it, with only the permissions you want it to use and an expiry date.
  3. Copy the key. It is shown only once. Put it in the assistant's configuration, never in a chat message.

The assistant is shown only the tools its key allows. A key that can only read cannot change anything, whatever the assistant is asked.

Connect a client

Set the environment variable MELORA_API_KEY to your key, or put your key where the examples say melora_YOUR_KEY.

Claude Code

Add the server from a terminal:

claude mcp add --transport http melora https://app.meloraconnect.com/api/public/mcp \
  --header "Authorization: Bearer $MELORA_API_KEY"

Claude Desktop

Claude Desktop reaches a server that takes a key through the open-source mcp-remote bridge, which needs Node.js. Add this to its configuration file (Settings, Developer, Edit config) and restart Claude Desktop:

{
  "mcpServers": {
    "melora": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://app.meloraconnect.com/api/public/mcp",
        "--header",
        "Authorization:${MELORA_AUTH}"
      ],
      "env": {
        "MELORA_AUTH": "Bearer melora_YOUR_KEY"
      }
    }
  }
}

OpenAI API

The Responses API calls the server itself through its MCP tool. Keep require_approval on, so each call is shown to you first.

curl https://api.openai.com/v1/responses \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "YOUR_MODEL",
    "tools": [{
      "type": "mcp",
      "server_label": "melora",
      "server_url": "https://app.meloraconnect.com/api/public/mcp",
      "headers": { "Authorization": "Bearer melora_YOUR_KEY" },
      "require_approval": "always"
    }],
    "input": "List our lapsed members."
  }'

Claude.ai and ChatGPT

Their web and app connectors sign in with OAuth, and the Melora Connect MCP server takes an API key instead. Connect through Claude Code, Claude Desktop or the OpenAI API.

Other MCP clients

Any client that connects to a remote server over streamable HTTP and can send an Authorization header can use the server, with the address and header above.

Tools

The tools, the permission each one needs, the REST endpoint it matches and what it returns:

ToolRequired permissionSame asWhat it returns
list_membersmembers.readGET /membersA page of members: data, page, per_page and has_more.
get_membermembers.readGET /members/{id}One member, in data.
create_membermembers.writePOST /membersThe new member in data, and welcome_drips when asked for.
update_membermembers.writePATCH /members/{id}The changed member, in data.
unsubscribe_membermembers.writePOST /members/{id}/email-preferencesThe member's opt-out (member_id, email_marketing_opt_out, email_marketing_opted_out_at), in data.
list_eventsevents.readGET /eventsA page of events.
get_eventevents.readGET /events/{id}One event with its registrations, in data.
create_eventevents.managePOST /eventsThe new draft event, in data.
list_dues_invoicesmembers.billing.readGET /dues-invoicesA page of dues invoices.

A tool takes the same fields as its endpoint: the filters, page and per_page of a list, the id of one record, and the body of a create or a change (update_member takes the id with the fields to change). No tool takes an organization: it is always the key's, and a tool refuses any field it does not know. Results come back as JSON text and as structured content.

Read tools are marked read-only. Tools that add or change something are marked as changes, so clients ask before running them: keep approving each of those calls, and in Claude Code and Claude Desktop do not let them run without asking you. create_member can start the organization's welcome emails when asked to.

What the tools return (names, bios, companies, custom fields, event descriptions) was written by people, so the assistant must treat it as data, never as instructions. The server tells the assistant so when it connects.

Limits

  • Each request to the MCP server counts once against the key's limit of 120 requests every 60 seconds, including starting the connection and listing the tools. The organization's limit of 600 requests every 60 seconds across all its keys applies too.
  • A request with no key or an unknown key is answered 401, and too many requests 429 with Retry-After, before any tool runs.
  • A request can be up to 64 KB, and a list returns at most 100 records per call.

When a call is refused

A refused tool call comes back as a tool error carrying the REST API's own error, with the same error codes, so the assistant can tell you why:

{
  "content": [
    {
      "type": "text",
      "text": "{\"error\":{\"code\":\"permission_denied\",\"message\":\"This API key does not have the members.write permission.\",\"details\":{\"required_permission\":\"members.write\"}}}"
    }
  ],
  "structuredContent": {
    "error": {
      "code": "permission_denied",
      "message": "This API key does not have the members.write permission.",
      "details": {
        "required_permission": "members.write"
      }
    }
  },
  "isError": true
}
  • permission_denied: the key lacks the permission named in details.required_permission. Make a new key that has it.
  • api_key_revoked or api_key_expired: make a new key and connect the assistant with it.
  • validation_failed: a field is not valid, or is one the tool does not take. details names it.
  • plan_required, billing_hold, account_restricted and limit_reached: the same as for the REST API, solved in Melora Connect.

Revoke access

  1. In Melora Connect, open Settings and then the API keys tab.
  2. Click Revoke on the assistant's key and confirm.

The key is refused from the next request, and a revoked key cannot be restored. Remove the server from the assistant's configuration too. To change what an assistant may do, make a new key with the permissions you want, connect the assistant with it, and revoke the old key.

See it with your own data

Ready to give your members the platform they deserve?

A walkthrough with our team, built around how your organization works today. Live from 5 weeks after you sign, with a Melora specialist doing the setup.

Book a demoEstimate your go-live date