Skip to content

Troubleshooting

Common errors and how to fix them when using the Vivreal MCP server

intermediate5 min readFor developers

Troubleshooting

Connection errors

connection refused or ENOTFOUND mcp.vivreal.io

DNS resolution failure. Check:

curl https://mcp.vivreal.io/.well-known/oauth-protected-resource

If this returns JSON, the server is reachable — the problem is on your client side (firewall, corp proxy, DNS cache). If it fails too, the deploy may be mid-rollout — wait 1-2 minutes and retry.

404 when calling /mcp

The path is /mcp exactly (no trailing slash variations). Make sure your client URL is https://mcp.vivreal.io/mcp, not https://mcp.vivreal.io or https://mcp.vivreal.io/.

Auth errors

401 Unauthorized with WWW-Authenticate: Bearer resource_metadata="..."

You didn't send a bearer token, or the token expired. The resource_metadata URL in the response header is the OAuth discovery URL — your client should fetch it and walk the OAuth flow. Claude.ai and Claude Code do this automatically.

If you're testing manually with curl, refresh your token:

curl -X POST https://mcp.vivreal.io/oauth/token \
  -d "grant_type=refresh_token&refresh_token=YOUR_REFRESH_TOKEN&client_id=YOUR_CLIENT_ID" \
  -H "Content-Type: application/x-www-form-urlencoded"

invalid_grant on token exchange

Three causes:

  1. PKCE verification failed. You sent a different code_verifier than the code_challenge you sent at authorize-time. Make sure your client persists the verifier across the redirect.
  2. redirect_uri mismatch. The URI at token-exchange must exactly match the one at authorize-time.
  3. Code expired. Broker codes are valid for 60 seconds. If the user took longer than that to complete the flow, restart.

invalid_scope

You requested a scope the server doesn't recognize. Supported scopes are listed at /.well-known/oauth-protected-resource. Common typo: vivreal.cms.read instead of vivreal/cms.read (note the slash, not dot).

Session / Active-Group errors

Tool returns No active group set. Call set-active-group first.

Every CMS, sites, channels, and billing tool requires an active group. Workflow:

// 1. Discover groups
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get-session-context","arguments":{}}}
// → returns { groups: [{ groupId, name, dbKey }, ...] }

// 2. Activate one
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"set-active-group","arguments":{"groupId":"68f..."}}}

// 3. Now any tool works
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list-content-types","arguments":{}}}

Group '...' is not available for this user.

You passed a groupId that the authenticated user doesn't belong to. Re-check get-session-context.groups[].groupId and pass an exact match.

Tool-call errors

Tool '...' requires tier 'pro_plus' (current: 'basic')

The tool is tier-gated. Either upgrade the active group's plan or use a different tool. Gated tools:

  • bulk-create-content, bulk-update-content-publish-date, sync-channel → pro+

VALIDATION_FAILED with field-level errors

The tool's input schema rejected something. Read the details object — every validation error includes the path that failed (e.g. schema.tableConfig.headers.columnOne.meta — expected boolean, received string).

Stripe tools fail with No Stripe integration configured

The active group hasn't connected Stripe. Connect it via the portal at vivreal.io/app/channels — paste the secret API key and save. The MCP does not expose channel-setup tools (no activate-channel, no connect-channel-account); setup is portal-only by design. Once Stripe is configured, every Stripe tool works immediately on the next call.

Channel post tools fail with Channel not connected or list-channel-accounts returns empty

The user hasn't connected an account on the social platform (X, LinkedIn, Instagram, Facebook, TikTok, Mailchimp). They must complete the OAuth dance via the portal at vivreal.io/app/channels — there's no headless way to bind OAuth tokens to a Vivreal group, and the MCP does not expose connect/disconnect tools. Once an account is connected, list-channel-accounts returns it and create-channel-post accepts its accountId.

Rate-limit errors

RATE_LIMITED with errorCode: "RATE_LIMITED"

You exceeded the per-(user, tool) sliding-window limit. Only write tools (anything requiring cms.write) are rate-limited — pure-read tools are not throttled. Limits are tier-based via a multiplier applied to the base 30 calls/minute:

Tier (active group dbKey)MultiplierCalls per minute, per tool
general_shared / free / basic1x30
pro2x60
pro_plus4x120

The limit is sliding-window over 60 seconds, keyed by (userId, toolName). A burst on one tool doesn't consume budget for another. Back off and retry on consecutive limits.

Diagnostic checklist

When something's broken, check in this order:

  1. Is the server up? curl https://mcp.vivreal.io/.well-known/oauth-protected-resource returns JSON.
  2. Is your token valid? curl -H "Authorization: Bearer YOUR_TOKEN" https://mcp.vivreal.io/mcp -X POST -d '{"jsonrpc":"2.0","id":1,"method":"session/get"}' returns your session info.
  3. Is an active group set? Same call as above — look at activeGroupId in the response. If null, call set-active-group.
  4. Does the active group have the right tier? Look at the dbKey field — pro_plus means pro_plus tier, pro means pro, anything else (general_shared, basic) means basic.
  5. Does the tool exist at all? tools/list returns the current tool catalog filtered to your tier. If your target tool isn't there, either you don't qualify or it's been removed.

If after this checklist you still can't figure it out, contact support with:

  • The exact JSON-RPC request you sent (with Authorization token redacted)
  • The full response (headers + body)
  • The session ID from the Mcp-Session-Id header
  • Approximate timestamp (so we can find it in CloudWatch)