MCP Integration for AI Agents
Connect Claude Code, VS Code, or any MCP client to your Herald realm with OAuth — no API keys, no client secrets. Sign in once in the browser and query your realm through nine read-only tools.
Herald ships an official MCP (Model Context Protocol) server, so your AI agent can query your realm's data with structured tool semantics instead of reading REST docs and hand-writing calls. Authorization is OAuth: you sign in once with your Herald account in the browser, and the agent holds user credentials — no API key, no client id, no secret to paste anywhere.
The endpoint is a standard MCP Streamable HTTP endpoint (protocol version 2026-07-28) served by your Herald instance — the same origin as the REST API, no separate deployment. Herald's MCP server does not accept API keys.
1. Get Your Tenant URL
Each realm has one canonical MCP address:
https://<origin>/mcp/<realmId><origin>— your Herald deployment origin (or the realm's configured custom domain)<realmId>— your realm id
The realm id is part of the address: a token issued for one realm never works against another realm's URL.
2. Connect Your Agent Client (URL Only)
Your client needs the tenant URL and nothing else. Through RFC 9728 / RFC 8414 discovery and a controlled RFC 7591 registration endpoint, the client obtains the realm's preset public MCP client (herald-mcp) by itself.
Enable the realm's MCP access first: the built-in Herald MCP client ships disabled. A realm admin must enable it once in the admin console's Client App list before an agent can register and authorize (see the per-realm switch in section 7).
Claude Code — verified end-to-end with Claude Code 2.1.269: registration, browser authorization, tool discovery, and tool calls all work with the URL alone.
claude mcp add --transport http herald https://your-herald-host/mcp/your-realm-idVS Code (.vscode/mcp.json, or via MCP: Add Server → HTTP) — consumes the same discovery and registration contracts verified with Claude Code (checked against VS Code 1.140); the interactive OAuth handshake in VS Code itself is still pending end-to-end verification.
{
"servers": {
"herald": {
"type": "http",
"url": "https://your-herald-host/mcp/your-realm-id"
}
}
}Other MCP clients that implement the MCP authorization specification (protected-resource discovery, browser authorization with PKCE, dynamic client registration) should work the same way — pass them the tenant URL only.
3. Sign In Once in the Browser
On first connect, the client opens Herald's login page in your browser. Sign in as usual — including any consent prompt or second factor your realm enforces. After the browser redirects back, the tools are available.
Closing the browser before completing sign-in simply issues no credentials; reconnect from the client and try again. If your authorization later expires or is revoked, the client asks you to re-authorize the same way.
4. The Nine Read-Only Tools
Admin tools
These check the authorizing user's RBAC permissions — grant the user a role with the permission, not a key:
| Tool | What it does | Required permission |
|---|---|---|
query_users | List or look up users in the realm | users.view |
get_points_balance | A user's realm-wide points balance | points.view |
list_points_transactions | A user's points history, newest first | points.view |
list_audit_logs | The realm's audit events | audit.view |
get_realm_config_status | Which configs exist and whether they are enabled | settings.view |
The admin balance tool returns the target user's balance across the whole realm, not per client app. Config status never returns configuration values.
Self tools
These operate on the authorizing user only. They take no userId — asking one to query someone else is rejected:
| Tool | What it does | Required scope |
|---|---|---|
get_my_profile | Your profile | mcp:profile:read |
get_my_points_balance | Your points balance | mcp:points:read |
list_my_points_transactions | Your points history | mcp:transactions:read |
list_my_subscriptions | Your subscriptions and entitlement status | mcp:subscriptions:read |
Any Herald user granted the scopes can call the self tools — no admin role needed.
Shared conventions
- Pagination is 1-based, default
page=1/pageSize=20, max 100. - Time filters accept RFC 3339 timestamps or
YYYY-MM-DD(interpreted as UTC midnight). - Outputs are deliberately narrow because agents may carry results into third-party models: no IP addresses, user agents, trace ids, config values, or payment metadata.
- Read-only is deliberate. Write operations are excluded and only arrive tool-by-tool after a per-tool security review. For writes or the full field surface, call the REST API with a client credential instead — see the third-party backend integration guide and the OpenAPI reference.
5. Connectivity Self-Check
After connecting, ask the agent:
Use the herald
get_my_profiletool.
It takes no arguments, reads only your own profile, and needs nothing beyond the profile scope — no admin permissions. A successful result echoing your id and email proves the whole chain works: discovery, client registration, browser authorization, and data access.
6. Troubleshooting
| Symptom | Cause | Recovery |
|---|---|---|
Tool returns permission_denied — "Your user does not have the 'X' permission" | Admin tools check the authorizing user's RBAC | Ask your realm administrator to grant you a role with that permission; re-login does not help |
HTTP 403 with an insufficient_scope challenge | A self tool's scope was not granted to your authorization | Re-authorize in the agent client and accept the requested scopes |
| HTTP 401 authorization challenge on every call | Credentials missing, expired, or revoked — or the realm's MCP access was disabled | Re-authorize; if the realm disabled MCP, ask your realm administrator to re-enable it, then re-authorize (old grants do not revive) |
| HTTP 404 on connect | Wrong tenant URL | Check https://<origin>/mcp/<realmId> — realm id included, no trailing slash |
invalid_target / invalid_scope errors | The authorization request was tampered with or the client is misconfigured | Remove and re-add the server with the tenant URL only |
Tool returns not_found | The target id does not exist — or belongs to another realm (cross-realm ids always read as not found) | Check the id; an agent cannot query outside the authorized realm |
Tool returns invalid_argument | A malformed argument — the message names the field and the expected format | Follow the message and re-send with a corrected value (e.g. a valid UUID, startTime not after endTime) |
Tool returns internal_error | Server-side failure | Retry; if it persists, check server logs |
7. Credentials, Isolation, and Limits
- Bidirectional credential isolation: MCP credentials represent you but are separate from your browser and admin-console sessions — neither side accepts the other's tokens.
- Long sessions: clients renew through the standard refresh token grant; refresh tokens rotate and have an absolute lifetime.
- Immediate revocation: your MCP credentials stop working the moment your account is disabled, you are forced offline, or the realm's built-in MCP client app is disabled.
- Realm on/off switch: each realm has a built-in "Herald MCP" client app in the admin console's Client Apps list. Disabling it closes the realm's MCP access — existing and new authorizations are rejected. Re-enabling does not revive old grants; agents must re-authorize. The built-in client cannot be deleted.
- Rate limit: each authorized user is limited to 60 MCP requests per 60 seconds.