Docs

MCP Consumers

A second kind of consumer — a headless end-user identity that an AI agent creates for itself through the Keen MCP server.

A Consumer for an Agent, Not a Person

The same tenancy, none of the human parts.

An MCP consumer is the end-user identity an AI agent uses when it needs to talk to your agents the way a site visitor would — to test a flow, run a job, or drive a conversation. It does not borrow a human's login. Compared with a normal consumer it is headless: it has no email, no password and is never asked for a one-time passcode; its credential is an ID plus a secret; it belongs to one consumer contract and reaches a subset of that contract's spaces; and its login token is obtained only through the Keen MCP Server — never through a partner site's sign-in.

Everything on the Overview page about tenants, contracts and spaces applies unchanged: an MCP consumer only ever reaches its own tenant's spaces, a space revoked from the contract stops working for it immediately, and it never crosses tenants. In the admin console MCP consumers live under Ai → MCP Consumers; on this site they sit with the other consumer pages.

ID + secretnever a passcodetoken via the MCP server onlytenant-scoped

Core Concepts

Credential (ID + secret)
The ID is minted at creation and never changes; the secret is a long random value shown exactly once — on creation and on every rotation — and stored irreversibly hashed. Together they are what the agent presents to obtain a token. Lose the secret and the only way forward is to rotate it.
Enabled
The access switch. Off, the consumer can no longer obtain a token and its next refresh is refused; an access token already issued runs until it expires. Prefer switching a consumer off over deleting it when you only want a pause.
Contract
The tenant it belongs to. Its token is stamped with that contract's key, and its tenant chain — the API key, certificate and client bound to that contract — is the one every verification re-walks. No contract, no token.
Spaces
Always a subset of the contract's allowed spaces: a grant outside the contract's offer is refused, and the token carries only spaces the contract currently offers.
Created by
The MCP account that created it, kept for audit. The consumer belongs to its contract, not to that account — deleting the account does not delete the consumer.
Last login
Stamped on every successful token mint; the console shows Last login … or Never used.

Who Creates Them, and How

Provisioning belongs to the agent; the console never creates one.

MCP consumers are provisioned only by an MCP account signed in through the Keen MCP server at https://<your-host>/mcp, with the mcp_consumers scope's write grant. The tools are:

  • create_mcp_consumer — a unique, immutable name; optionally the contract ID, the spaces and the enabled state. The reply carries the record and the secret, shown this once.
  • assign_mcp_consumer_contract — a contract ID, or null to unbind.
  • assign_mcp_consumer_spaces — replace-all: the list sent is the new grant; an empty list clears it.
  • set_mcp_consumer_enabled, rotate_mcp_consumer_secret, delete_mcp_consumer — the lifecycle actions, which a human with the same write grant can also perform from the console.
  • list_mcp_consumers, get_mcp_consumer — reading, never the secret.

A human session calling a provisioning action — create, assign the contract, assign spaces, or mint a token — is refused with 403 Only MCP accounts may manage MCP consumers. The admin console has no Create page for them, on purpose: the agent that makes one is the one that knows its purpose and holds its secret.

Getting and Refreshing a Token

One door in, and it is not the partner site's login.

The agent calls get_mcp_consumer_token with the consumer's ID and secret and receives the same pair a human consumer gets after login, with no passcode step:

the token reply

{
  "access_token":  "<consumer access token>",
  "token_type":    "Bearer",
  "expires_in":    600,
  "refresh_token": "<consumer refresh token>"
}
  • Every failure — unknown ID, wrong secret, disabled consumer, no contract, or a contract whose API key is not fully bound — is the same uniform 406 that says nothing about which.
  • When the access token expires, refresh_mcp_consumer_token with the refresh token issues a new pair and spends the old refresh token — keep both values from every reply. It is refused if the consumer was disabled, deleted, unbound from its contract, or moved to another tenant since the pair was minted; the agent then obtains a fresh token.
  • The partner-facing sign-in and refresh routes never issue or renew an MCP consumer's token: there is no email or password to sign in with, and the refresh route refuses the token.

Using the Token

The live chat surface, exactly as a human consumer uses it.

The token drives the live chat surface exactly like a human consumer's: the WebSocket run carries it in userContext.accessToken, userContext.userId is the MCP consumer's ID, the requested space must be in the consumer's grant and in the contract's current allowed set, and the token is verified on every message. The two-token chat routes (list, search, history, rename, delete) accept it together with your application token when both belong to the same tenant.

Profile, password and account-delete self-service does not apply — an MCP consumer has no email or password. See Live Chat and Self-Service for the surfaces themselves.

What the Console Lets a Human Do

View everything; stop, re-key or remove — never create or assign.

Under Ai → MCP Consumers (visible with the mcp_consumers scope's read grant) the list shows Name, Contract, Enabled, Last login, Created and a link; the detail page shows the MCP Consumer ID (with a copy button), Name, Contract, Spaces, Created by and a Timeline — all read-only. With the write grant three actions appear:

  • The Enabled switch, saved with Save (active only when the switch differs from the stored state).
  • Rotate Secret — the new secret is revealed once, together with the consumer ID, until you acknowledge I have copied it — back to the consumer. The previous secret stopped working the moment you rotated; hand the pair to the agent that runs this consumer.
  • Delete — Confirm delete / Cancel, then back to the list.

Name, contract and spaces are the agent's to manage and cannot be edited here; there is no Create page. Empty list: No MCP consumers yet.

Why can I stop one but not make one?
Because they are the agent's working identities: creation, the contract and the spaces stay with the agent that knows their purpose. But a compromised or abandoned consumer must be stoppable without a bot — so any admin with the write grant can switch it off, re-key it or remove it. Each of those interrupts whatever the agent is in the middle of.

Rules & Limits

Exact refusals and revocation semantics.

  • The name is required, trimmed, unique and immutable — a duplicate answers 406 An MCP consumer with that name already exists!
  • The contract is named by its contract ID (not its 19-character key); an unknown one answers 406 No such consumer contract! Unbinding wipes the spaces; re-homing clamps them to the new contract's allowed set.
  • Spaces must be within the contract's allowed set — otherwise 406 Space not offered by the consumer contract!; with no contract only an empty set passes.
  • A consumer without a contract, or one that is disabled, is refused a token (406).
  • Token lifetimes are the consumer defaults: access 10 minutes, refresh 30 days; each refresh token works once.
  • Rotating the secret kills the old secret immediately but revokes no outstanding token. Disabling or deleting the consumer stops new tokens and refreshes at once, while an access token already issued runs until it expires.
  • Deleting the contract releases its MCP consumers — they keep their record but lose the contract and cannot obtain a token until an MCP account assigns one again. Shrinking the contract's allowed spaces prunes their grants; deleting a space drops it from every MCP consumer.
  • Deleting the MCP account that created a consumer does not delete the consumer.

How It Differs from a Normal Consumer

ConsumerMCP consumer
Created byAn admin invite, or a sign-up on the partner siteAn MCP account, through the Keen MCP server
CredentialEmail + passwordID + secret (shown once, rotatable)
One-time passcodePer the contract's policyNever
Token obtainedPartner site sign-inMCP server only
Token refreshedPartner site refresh routeMCP server only (always a new pair)
Self-service (profile, password, delete)YesDoes not apply
Live chat and chat routesYesYes
ConsoleFull management with the consumer scope's write grantView; enable/disable, rotate, delete with the mcp_consumers scope's write grant
Partner notified of changesYes (spaces, tenant)No — the agent learns at its next refresh

Good to Know

  • Prefer Enabled off over Delete when you only want to pause an agent's consumer — it can be switched back on; a deleted consumer is gone, with its ID.
  • Re-homing an MCP consumer to another tenant invalidates its outstanding pair at the next refresh — the agent obtains a fresh token under the new tenant.
  • The secret exists only in the create / rotate reply. If it is lost, rotate — there is no way to read it back.
  • The MCP server's refresh always issues a new pair; keep both values from every reply.

Where To Go Next

Keen MCP Server

The door an AI agent uses to configure Keen.

MCP Accounts

The agent's login — the account that provisions MCP consumers.

Authentication

The token pair, its lifetimes and per-request verification.

Live Chat

The surface an MCP consumer's token drives.

Previous

Self-Service

Next

Chat SDK

Keen Agents 2026

Documentation

Release 15