OAuth 2.1

Building MCP Servers

Advanced guide for developers building their own MCP servers that authenticate against Whatalo using OAuth 2.1.

This is an advanced guide for developers building their own MCP servers (Model Context Protocol) that authenticate against Whatalo's API on behalf of a merchant.

Most integrators do not need this. If you want to connect an AI tool to a Whatalo store, use the existing Whatalo MCP server instead — see Connecting your store to AI tools. This page is only for developers building a new MCP server of their own.

Audience: MCP server authors and third-party developers building OAuth-based resource servers for Whatalo.

Architecture

There are three principals in every MCP + Whatalo integration:

RoleWhoIdentifier
Authorization ServerWhataloapp.whatalo.com
Resource ServerYour MCP serverReceives Bearer tokens, validates via introspection
OAuth ClientMCP host applicationGets a client_id via Dynamic Client Registration
┌─────────────────────┐     ┌──────────────────────┐     ┌───────────────────┐
│   MCP Host App      │     │  Whatalo Auth Server  │     │  Your MCP Server  │
│   (OAuth Client)    │     │  (app.whatalo.com)    │     │  (Resource Server)│
└──────────┬──────────┘     └──────────┬────────────┘     └─────────┬─────────┘
           │                           │                             │
           │  1. DCR: POST /oauth/register                          │
           ├──────────────────────────►│                             │
           │  ◄── client_id ───────────│                             │
           │                           │                             │
           │  2. Authorization Code + PKCE                          │
           ├──────────────────────────►│                             │
           │  ◄── access + refresh ────│                             │
           │                           │                             │
           │  3. MCP request with Bearer token                       │
           ├─────────────────────────────────────────────────────►  │
           │                           │  4. Introspect token        │
           │                           │◄────────────────────────────┤
           │                           ├──── { active, sub, scope } ►│
           │  ◄── MCP response ──────────────────────────────────────┤

Key point: your MCP server is a Resource Server, not an OAuth client. The MCP host application running on the user's machine is the OAuth client. This is the single most common mistake when combining MCP and OAuth — do not register your server as the client.

OAuth flow — reuse the canonical reference

Your MCP server relies on Whatalo's standard OAuth 2.1 endpoints. Each step is documented once, in the OAuth section — follow those pages rather than a duplicated copy:

StepReference
Authorization Server metadataDiscovery
Dynamic Client RegistrationRegistration
Authorization Code + PKCEAuthorization Flow
Exchanging the code for tokensToken Endpoint
Refreshing tokensToken Exchange
Validating Bearer tokensIntrospection
Revoking tokensRevocation
Available scopesScopes
Error formatErrors

Resource Server discovery

Your MCP server must publish OAuth Protected Resource metadata (RFC 9728) so that MCP host applications can discover Whatalo as the authorization server:

GET https://YOUR_MCP_DOMAIN/.well-known/oauth-protected-resource

Response:

{
  "resource": "https://YOUR_MCP_DOMAIN",
  "authorization_servers": ["https://app.whatalo.com"],
  "scopes_supported": [
    "read:store",
    "read:products",
    "write:products",
    "read:inventory",
    "write:inventory",
    "read:categories",
    "write:categories",
    "read:customers",
    "read:orders",
    "write:orders"
  ],
  "bearer_methods_supported": ["header"]
}

The authorization_servers array pointing to https://app.whatalo.com is what ties your MCP server to Whatalo as the authorization server. Only advertise the scopes your server actually enforces.

Routing requests to the right store

When you validate an incoming Bearer token via introspection, the active-token response includes a whatalo_store_id field:

{
  "active": true,
  "scope": "read:products read:orders",
  "sub": "usr_7f3a9b2c1d4e5f6a",
  "whatalo_store_id": "str_8k2m4n6p"
}

The whatalo_store_id field contains the store's public short ID — the same one used in Whatalo URLs. Use it to route operations to the correct store context in your multitenant MCP server. A merchant with multiple stores authorizes each store separately, so each token resolves to exactly one store.

Security checklist

  • ✅ Always use PKCE with S256 — never plain
  • ✅ Validate the state parameter on every callback
  • ✅ Store tokens in OS keychain or encrypted storage — never localStorage
  • ✅ Cache active: true introspection responses for at most 60 seconds — revocations are immediate
  • ✅ Request only the minimum scopes you need
  • ❌ Never log raw tokens or send them in URL query strings

References

On this page