Setu logo

MCP Server

Connect any AI agent or app to Setu over the Model Context Protocol — same capabilities as the REST API, exposed as tools.

v1.0.0Endpoint: https://setu.theabhipatel.com/api/mcp

Overview

The Model Context Protocol (MCP) is an open standard that lets AI assistants (Claude Desktop, Cursor, Cline, custom agents, and more) call external tools. Setu hosts a remote MCP server, so any compatible client can send messages, manage conversations and groups, search users, upload files, and manage webhooks — all on behalf of the user that owns the API key.

Hosted & remote

One URL. No install, no local process to run.

Key or OAuth

Static tap_setu_ key or OAuth 2.1 — same scopes & limits.

Full API surface

Every public API action is available as a tool.

Looking for raw HTTP endpoints instead? See the REST API documentation.

Connection

Endpoint URLhttps://setu.theabhipatel.com/api/mcp
TransportStreamable HTTP
AuthAuthorization: Bearer <token>
Version1.0.0 (reported in serverInfo during initialize)

Every request must carry a bearer token. Setu supports two ways to obtain one — a long-lived static API key or an OAuth 2.1 access token. Both authenticate as a single Setu user and are constrained by the same permission scopes and rate limits. See to pick the right one.

Treat tokens like passwords. Store them in your client's config/secret store — never commit them to a repo.

Authentication

The MCP server accepts two authentication methods. Both resolve to the same Setu user, the same , and the same rate limits — pick based on your client and who the agent acts for.

MethodBest forHow the agent gets access
Static Bearer Token

API key

Personal automation and clients you control yourself.You create a key in the dashboard and paste it into the client config.
OAuth 2.1

authorization code + PKCE

Third-party agents and apps that act on behalf of other Setu users.The user logs in and approves a consent screen; the client receives a scoped, expiring token automatically.

Option A — Static Bearer Token (API key)

The simplest method. Create a key in API Keys, grant it the scopes you want the agent to use, and send it on every request:

http
Authorization: Bearer tap_setu_YOUR_KEY_HERE

Keys start with tap_setu_ and are long-lived (they only stop working if you disable them or set an expiry). The full key is shown once at creation — store it immediately. This is the right choice when you own both the agent and the account it acts as. See for ready-to-paste config.

Option B — OAuth 2.1

Use OAuth when an agent or app needs to act on behalf of a user without ever handling a static key. The user authorizes through a Setu consent screen and your client receives a scoped, expiring access token. Setu implements OAuth 2.1 with mandatory PKCE (S256) and Dynamic Client Registration.

Most MCP clients with built-in OAuth (e.g. Claude, Cursor) run this whole flow automatically — just point them at the MCP URL with no auth header and follow the browser prompt. The steps below are what happens under the hood, and what to implement for a custom client.

Discovery

Clients discover the endpoints from the standard metadata document (RFC 8414):

http
GET https://setu.theabhipatel.com/.well-known/oauth-authorization-server
json
{
  "issuer": "https://setu.theabhipatel.com",
  "authorization_endpoint": "https://setu.theabhipatel.com/oauth/authorize",
  "token_endpoint": "https://setu.theabhipatel.com/api/oauth/token",
  "registration_endpoint": "https://setu.theabhipatel.com/api/oauth/register",
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["none", "client_secret_post"]
}

Step 1 — Register a client (RFC 7591)

Register once to get a client_id. No authentication is required. Redirect URIs must be localhost or HTTPS.

bash
curl -X POST https://setu.theabhipatel.com/api/oauth/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My MCP Client",
    "redirect_uris": ["http://localhost:9999/oauth/callback"],
    "grant_types": ["authorization_code"],
    "response_types": ["code"],
    "token_endpoint_auth_method": "none",
    "scope": "messages:send messages:read conversations:read"
  }'
json
{
  "client_id": "setu_oac_...",
  "redirect_uris": ["http://localhost:9999/oauth/callback"],
  "grant_types": ["authorization_code"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}

Public clients use token_endpoint_auth_method: "none" (no secret). For a confidential client, use client_secret_post and a client_secret (prefix setu_ocs_) is returned.

Step 2 — Authorize (with PKCE)

Generate a PKCE code_verifier and its S256 code_challenge, then send the user to the authorization endpoint in a browser:

http
GET https://setu.theabhipatel.com/oauth/authorize
  ?client_id=setu_oac_...
  &redirect_uri=http://localhost:9999/oauth/callback
  &response_type=code
  &scope=messages:send%20messages:read%20conversations:read
  &state=RANDOM_CSRF_VALUE
  &code_challenge=PKCE_S256_CHALLENGE
  &code_challenge_method=S256

The user signs in (if needed) and approves the requested scopes. Setu then redirects back to your redirect_uri with a one-time authorization code (the state is echoed back — verify it):

http
http://localhost:9999/oauth/callback?code=setu_ocd_...&state=RANDOM_CSRF_VALUE

Step 3 — Exchange the code for tokens

POST the code and the original code_verifier to the token endpoint (accepts JSON or x-www-form-urlencoded):

bash
curl -X POST https://setu.theabhipatel.com/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "setu_ocd_...",
    "client_id": "setu_oac_...",
    "redirect_uri": "http://localhost:9999/oauth/callback",
    "code_verifier": "YOUR_PKCE_VERIFIER"
  }'
json
{
  "access_token": "setu_oat_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "setu_ort_...",
  "scope": "messages:send messages:read conversations:read"
}

Step 4 — Call the MCP server

Send the access token exactly like a static key — same header, same tools:

http
Authorization: Bearer setu_oat_...

Step 5 — Refresh when it expires

Access tokens last 1 hour; refresh tokens last 30 days. When an access token expires, exchange the refresh token for a new pair (the old refresh token is rotated out):

bash
curl -X POST https://setu.theabhipatel.com/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "refresh_token",
    "refresh_token": "setu_ort_...",
    "client_id": "setu_oac_..."
  }'
Discovery/.well-known/oauth-authorization-server
Registration/api/oauth/register
Authorization/oauth/authorize
Token/api/oauth/token
Access token TTL1 hour
Refresh token TTL30 days (rotated on use)

Client Setup

The snippets below use a static API key. If your client supports OAuth, you can instead point it at the URL with no header and it will run the for you in the browser:

json
{
  "mcpServers": {
    "setu-chat": {
      "url": "https://setu.theabhipatel.com/api/mcp"
    }
  }
}

Clients with native remote MCP support (e.g. Cursor)

Point the client at the URL and attach the auth header:

json
{
  "mcpServers": {
    "setu-chat": {
      "url": "https://setu.theabhipatel.com/api/mcp",
      "headers": {
        "Authorization": "Bearer tap_setu_YOUR_KEY_HERE"
      }
    }
  }
}

Claude Desktop / stdio-only clients

Use the mcp-remote bridge to connect a stdio client to the remote server with headers:

json
{
  "mcpServers": {
    "setu-chat": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://setu.theabhipatel.com/api/mcp",
        "--header", "Authorization: Bearer tap_setu_YOUR_KEY_HERE"
      ]
    }
  }
}

Test it with the MCP Inspector

bash
npx @modelcontextprotocol/inspector
# Transport: Streamable HTTP
# URL: https://setu.theabhipatel.com/api/mcp
# Header: Authorization: Bearer tap_setu_YOUR_KEY_HERE

Tools Reference

Parameters marked * are required. Each tool requires the listed permission scope on your API key; calling a tool without its scope returns a PERMISSION_DENIED error.

Messages

ToolScopeParameters
send_message

Send a message to a conversation.

messages:sendconversation_id*, content*, message_type, reply_to
list_messages

List messages in a conversation (paginated, newest-first cursor).

messages:readconversation_id*, before, limit
edit_message

Edit a message you sent.

messages:editmessage_id*, content*
delete_message

Soft-delete a message you sent.

messages:deletemessage_id*

Conversations

ToolScopeParameters
list_conversations

List all conversations the key owner belongs to.

conversations:read
get_conversation

Get a single conversation with its members.

conversations:readconversation_id*
create_conversation

Create a private chat or group. Returns existing private chat if one exists.

conversations:createtype*, member_ids*, name, description

Groups & Members

ToolScopeParameters
add_members

Add members to a group.

members:addgroup_id*, user_ids*
list_members

List a group's members.

members:listgroup_id*
remove_member

Remove a member (self, or others if admin/owner).

members:removegroup_id*, user_id*

Users

ToolScopeParameters
search_users

Search users by name or username (min 2 chars).

users:searchq*, limit
get_user_profile

Get a user's public profile.

users:profileuser_id*

Files

ToolScopeParameters
upload_file

Upload a file (base64) to a conversation. Max 10MB.

files:uploadconversation_id*, file_name*, file_base64*, mime_type

Account

ToolScopeParameters
get_account

Get the authenticated user's account info.

account:read

Webhooks

ToolScopeParameters
list_webhooks

List your webhooks.

webhooks:read
create_webhook

Create a webhook subscription.

webhooks:managename*, url*, events*
update_webhook

Update a webhook.

webhooks:managewebhook_id*, name, url, events, is_active
delete_webhook

Delete a webhook.

webhooks:managewebhook_id*

Example Prompts

Once connected, you can drive Setu in natural language. The agent picks the right tools automatically:

“Search for the user @nidhi and send her a message saying the report is ready.”
“Create a group called ‘Launch Team’ with alice, bob and carol, then post the kickoff agenda.”
“Summarize the last 50 messages in my conversation with the design team.”
“Set up a webhook to my server for message.received events.”

Rate Limits

MCP tool calls share the exact same rate limit and usage tracking as the REST API — each tool call counts as a single request against your key's per-minute limit. See the REST docs for per-plan limits, and Usage & Analytics to monitor consumption.

Troubleshooting

SymptomCause & Fix
401 / connection rejectedMissing or invalid token. Ensure an Authorization: Bearer header is set with an active static key (tap_setu_…) or a valid OAuth access token (setu_oat_…).
OAuth token stopped working after ~1 hourAccess tokens expire after 1 hour. Use the refresh_token grant to get a new pair — see .
PERMISSION_DENIED from a toolThe token lacks that tool's scope. For a static key, add the scope in API Keys; for OAuth, request the scope during authorization.
RATE_LIMIT_EXCEEDEDToo many calls per minute. Slow down or upgrade your plan.
Tools not appearingConfirm the transport is “Streamable HTTP” and the URL is exactly https://setu.theabhipatel.com/api/mcp.