Unkey MCP by usefulapi

Manage API keys, identities, permissions, rate-limit overrides and verification analytics.

Should I use this

Quality & Safety

A
Description quality
100%
Schema completeness
95%
Naming quality
79%
Poisoning risk
100%
Permission match
100%
Protocol compliance
100%

Findings (1)

  • LOWTool 'unkey_query_verification_analytics' name length outside 3-30 rangein unkey_query_verification_analytics

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~3,030Tokens (tool definitions)
~1.1 KBTypical response size
Significant attention impact (2.37% of 128k context)

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-http

What it can do

Tool inventory

Tools (19)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢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

Rate this Server

Evidence

Recent observations

verifiedversion not recorded19 tools
verifiedversion not recorded19 tools