Skip to content

Create MCP API Key

Method

REST method is adopted.

HTTP Method

POST: Create MCP API key

Naming Convention

To unify the naming of query parameters and nodes and improve readability, snake_case is used for URIs and JSON nodes in requests.

Request and Response

Headers

Meta information is set in HTTP headers, not in the response body.

Request Headers

  • Authorization
  • Content-Type
  • Accept
  • Accept-language

Response Headers

  • Content-Type

Create MCP API Key

URI

POST /v1/organizations/{organization_id}/projects/{project_id}/mcp_api_key

Path Parameters

Name Type Required Description
organization_id integer Required Organization ID
project_id integer Required Project ID

Request Body

The request body is JSON.

{
  "scope": "project",
  "name": "mcp for project A",
  "keyPrefix": "abc123",
  "permission": 0,
  "expiresAt": 1735689600000
}

Request Parameters

Name Type Required Description
scope string Required API key scope (user or project)
name string Required API key name (max 255 characters)
keyPrefix string Required Key prefix (max 100 characters, unique)
permission integer Optional Access permission (0: READ, 1: WRITE, default: 0)
expiresAt integer Optional Expiry timestamp (epoch milliseconds, defaults to creation date + 30 days)

Response

The response is JSON (HTTP status: 201 Created).

{
  "id": 1,
  "userId": 1,
  "projectId": 2,
  "name": "mcp for project A",
  "keyPrefix": "abc123",
  "apiKey": "guinness_abc123_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
  "permission": 0,
  "expiresAt": 1735689600000,
  "revokedAt": null,
  "lastUsedAt": null,
  "createdAt": 1234567890000,
  "updatedAt": 1234567890000,
  "deletedAt": null,
  "createdBy": "user-cognito-sub",
  "updatedBy": "user-cognito-sub",
  "deletedBy": null
}

Important: The apiKey is only returned once at creation time. It will not be returned in subsequent requests.

Authentication

Authentication is performed using JSON Web Tokens (JWT) issued by Amazon Cognito.

Error Handling

The status codes for error handling are as follows.

Description Status Code Status Name
Invalid request (invalid scope, empty name, etc.) 400 Bad Request
Missing credentials 401 Unauthorized
Insufficient permissions 403 Forbidden
Organization or project not found 404 Not Found
keyPrefix already in use 409 Conflict
Internal server error 500 Internal Server Error

Processing Flow

  1. Extract organization ID and project ID from path parameters
  2. Extract each field from the request body
  3. Set userId or projectId depending on the scope
  4. Validate that keyPrefix is unique
  5. Verify the user or project access permissions
  6. If expiresAt is not specified, set to creation date + 30 days
  7. Generate a random salt value and secrets
  8. Generate the API key (format: guinness_{keyPrefix}_{secrets})
  9. Hash the key and save to the database
  10. Return the created API key information (actual key is only returned at this time)

API Key Structure

API keys are generated in the following format:

guinness_{key_prefix}_{secrets}

Example: guinness_abc123_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

Security

  • API keys are stored as hashes (key_hash and salt)
  • The actual API key is only returned in the creation response
  • keyPrefix must be unique

Detailed Flowchart

flowchart TD
    Start([POST Request]) --> Auth[Auth & Parameter Extraction]
    Auth --> Service[Service Layer]
    Service --> AccessCheck[Access Check]
    AccessCheck --> HasAccess{Write permission?}
    HasAccess -->|No| Err404[404 Not Found]
    HasAccess -->|Yes| Validate[Input Validation]
    Validate --> ValidScope{scope validation}
    ValidScope -->|NG| Err400[400 Bad Request]
    ValidScope -->|OK| CheckPrefix[Check keyPrefix uniqueness]
    CheckPrefix --> Duplicate{Duplicate?}
    Duplicate -->|Yes| Err409[409 Conflict]
    Duplicate -->|No| CreateDB[DB Create<br/>Generate API key]
    CreateDB --> Success[201 Created]