Unkey MCP by usefulapi
Manage API keys, identities, permissions, rate-limit overrides and verification analytics.
Should I use this
Quality & Safety
Findings (1)
- LOWin unkey_query_verification_analytics
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"unkey": {
"url": "https://unkey.usefulapi.io/mcp"
}
}
}Remote endpoints
https://unkey.usefulapi.io/mcpstreamable-httpWhat it can do
Tool inventory
Tools (19)
🟢unkey_liveness
Check that the Unkey API is reachable and the root key works. The only GET in the v2 surface. Unkey: GET /v2/liveness.
Input Schema
{
"type": "object",
"properties": {},
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_get_key(keyId, decrypt)
Fetch a key's metadata by its key id — name, owner, permissions, credits, rate limits and whether it is enabled. Read-only despite being a POST. Unkey: POST /v2/keys.getKey.
Input Schema
{
"type": "object",
"properties": {
"keyId": {
"type": "string",
"description": "The key's id (key_...), NOT the secret key itself."
},
"decrypt": {
"description": "Also return the plaintext secret. Only works for keys created as recoverable.",
"type": "boolean"
}
},
"required": [
"keyId"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_whoami_key(key)
Given a plaintext API key, return which key it is and its metadata — without spending credits or recording a verification. This is the safe way to identify a key a customer sent you. Unkey: POST /v2/keys.whoami.
Input Schema
{
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "The plaintext API key to identify."
}
},
"required": [
"key"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_get_api(apiId)
Fetch an API namespace by id. Read-only despite being a POST. Unkey: POST /v2/apis.getApi.
Input Schema
{
"type": "object",
"properties": {
"apiId": {
"type": "string",
"description": "The API's id (api_...)."
}
},
"required": [
"apiId"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_list_api_keys(apiId, externalId, limit, cursor)
List every key issued under one API, optionally narrowed to a single customer by externalId. Read-only despite being a POST. Unkey: POST /v2/apis.listKeys.
Input Schema
{
"type": "object",
"properties": {
"apiId": {
"type": "string",
"description": "The API whose keys to list."
},
"externalId": {
"description": "Only keys belonging to this external identity.",
"type": "string"
},
"limit": {
"description": "Page size, 1-100.",
"type": "integer",
"minimum": 1,
"maximum": 100
},
"cursor": {
"description": "Cursor from the previous page's response. Omit for the first page.",
"type": "string"
}
},
"required": [
"apiId"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_list_identities(search, limit, cursor)
List identities — the end users or organisations your keys belong to. Read-only despite being a POST. Unkey: POST /v2/identities.listIdentities.
Input Schema
{
"type": "object",
"properties": {
"search": {
"description": "Free-text search over external ids.",
"type": "string"
},
"limit": {
"description": "Page size, 1-100.",
"type": "integer",
"minimum": 1,
"maximum": 100
},
"cursor": {
"description": "Cursor from the previous page's response. Omit for the first page.",
"type": "string"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_get_identity(identity)
Fetch a single identity with its metadata and shared rate limits. Read-only despite being a POST. Unkey: POST /v2/identities.getIdentity.
Input Schema
{
"type": "object",
"properties": {
"identity": {
"type": "string",
"description": "The identity's external id or Unkey id."
}
},
"required": [
"identity"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_list_permissions(search, limit, cursor)
List the permissions defined in the workspace. Read-only despite being a POST. Unkey: POST /v2/permissions.listPermissions.
Input Schema
{
"type": "object",
"properties": {
"search": {
"description": "Free-text search.",
"type": "string"
},
"limit": {
"description": "Page size, 1-100.",
"type": "integer",
"minimum": 1,
"maximum": 100
},
"cursor": {
"description": "Cursor from the previous page's response. Omit for the first page.",
"type": "string"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_list_roles(search, limit, cursor)
List the roles defined in the workspace. Read-only despite being a POST. Unkey: POST /v2/permissions.listRoles.
Input Schema
{
"type": "object",
"properties": {
"search": {
"description": "Free-text search.",
"type": "string"
},
"limit": {
"description": "Page size, 1-100.",
"type": "integer",
"minimum": 1,
"maximum": 100
},
"cursor": {
"description": "Cursor from the previous page's response. Omit for the first page.",
"type": "string"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_list_ratelimit_overrides(namespace, limit, cursor)
List the per-identifier overrides in one rate-limit namespace. Read-only despite being a POST. Unkey: POST /v2/ratelimit.listOverrides.
Input Schema
{
"type": "object",
"properties": {
"namespace": {
"type": "string",
"description": "The rate-limit namespace name."
},
"limit": {
"description": "Page size, 1-100.",
"type": "integer",
"minimum": 1,
"maximum": 100
},
"cursor": {
"description": "Cursor from the previous page's response. Omit for the first page.",
"type": "string"
}
},
"required": [
"namespace"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_get_ratelimit_override(namespace, identifier)
Fetch the override for one identifier in a namespace. Read-only despite being a POST. Unkey: POST /v2/ratelimit.getOverride.
Input Schema
{
"type": "object",
"properties": {
"namespace": {
"type": "string",
"description": "The rate-limit namespace name."
},
"identifier": {
"type": "string",
"description": "The identifier the override applies to."
}
},
"required": [
"namespace",
"identifier"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢unkey_query_verification_analytics(query)
Run a read-only SQL query over key-verification analytics. The query must use one of the public aliases: key_verifications_v1, key_verifications_per_minute_v1, key_verifications_per_hour_v1, key_verifications_per_day_v1 or key_verifications_per_month_v1. Physical default.* table names are rejected, and results are scoped to your workspace. Unkey: POST /v2/analytics.getVerifications.
Input Schema
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The SQL query, e.g. SELECT time, outcome, count(*) FROM key_verifications_per_day_v1 GROUP BY time, outcome."
}
},
"required": [
"query"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🔴unkey_create_api(name)
Create a new API namespace to issue keys under. Unkey: POST /v2/apis.createApi.
Input Schema
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The API name."
}
},
"required": [
"name"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🔴unkey_create_key(apiId, name, externalId, prefix, byteLength, ...)
Issue a new API key under an API. The plaintext key is returned ONCE in the response and cannot be retrieved later unless recoverable is set. Unkey: POST /v2/keys.createKey.
Input Schema
{
"type": "object",
"properties": {
"apiId": {
"type": "string",
"description": "The API to issue the key under."
},
"name": {
"description": "A human-readable label for the key.",
"type": "string"
},
"externalId": {
"description": "The identity (your user or org id) this key belongs to.",
"type": "string"
},
"prefix": {
"description": "Prefix for the generated key, e.g. acme.",
"type": "string"
},
"byteLength": {
"description": "Entropy in bytes. Defaults to 16.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"expires": {
"description": "Expiry as a Unix timestamp in milliseconds.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"enabled": {
"description": "Create the key enabled. Defaults to true.",
"type": "boolean"
},
"recoverable": {
"description": "Store the key encrypted so it can be shown again later. Defaults to false.",
"type": "boolean"
},
"roles": {
"description": "Role names to attach.",
"type": "array",
"items": {
"type": "string"
}
},
"permissions": {
"description": "Permission names to attach.",
"type": "array",
"items": {
"type": "string"
}
},
"meta": {
"description": "Arbitrary JSON metadata.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
},
"required": [
"apiId"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🔴unkey_update_key(keyId, name, externalId, expires, enabled, ...)
Change a key's name, owner, metadata, expiry, roles, permissions or enabled state. Unkey: POST /v2/keys.updateKey.
Input Schema
{
"type": "object",
"properties": {
"keyId": {
"type": "string",
"description": "The key to update."
},
"name": {
"description": "New label.",
"type": "string"
},
"externalId": {
"description": "Reassign the key to this identity.",
"type": "string"
},
"expires": {
"description": "New expiry as a Unix timestamp in milliseconds.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"enabled": {
"description": "Enable or disable the key.",
"type": "boolean"
},
"roles": {
"description": "Replace the key's roles.",
"type": "array",
"items": {
"type": "string"
}
},
"permissions": {
"description": "Replace the key's permissions.",
"type": "array",
"items": {
"type": "string"
}
},
"meta": {
"description": "Replace the key's metadata.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
},
"required": [
"keyId"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🔴unkey_update_key_credits(keyId, operation, value)
Set, increment or decrement a key's remaining credits. Use set with no value for unlimited. Unkey: POST /v2/keys.updateCredits.
Input Schema
{
"type": "object",
"properties": {
"keyId": {
"type": "string",
"description": "The key to change."
},
"operation": {
"type": "string",
"enum": [
"set",
"increment",
"decrement"
],
"description": "How to apply the value."
},
"value": {
"description": "The credit amount. Omit with operation=set to make the key unlimited.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"keyId",
"operation"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🔴unkey_delete_key(keyId, permanent)
Revoke a key. By default this is a soft delete the key stops working but stays queryable; pass permanent to erase it. Unkey: POST /v2/keys.deleteKey.
Input Schema
{
"type": "object",
"properties": {
"keyId": {
"type": "string",
"description": "The key to revoke."
},
"permanent": {
"description": "Erase the key entirely instead of soft-deleting it. Defaults to false.",
"type": "boolean"
}
},
"required": [
"keyId"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🔴unkey_create_identity(externalId, meta)
Create an identity — an end user or organisation that keys and shared rate limits attach to. Unkey: POST /v2/identities.createIdentity.
Input Schema
{
"type": "object",
"properties": {
"externalId": {
"type": "string",
"description": "Your own id for this user or organisation."
},
"meta": {
"description": "Arbitrary JSON metadata.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
},
"required": [
"externalId"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🔴unkey_set_ratelimit_override(namespace, identifier, limit, duration)
Set a custom rate limit for one identifier in a namespace — how you raise or lower a single customer's limit. Unkey: POST /v2/ratelimit.setOverride.
Input Schema
{
"type": "object",
"properties": {
"namespace": {
"type": "string",
"description": "The rate-limit namespace name."
},
"identifier": {
"type": "string",
"description": "The identifier the override applies to."
},
"limit": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Requests allowed per window."
},
"duration": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "Window length in milliseconds."
}
},
"required": [
"namespace",
"identifier",
"limit",
"duration"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}Community
Evidence