# RevCent MCP Operation: `CreateKeyValue`

This document explains how MCP/AI clients should use the `CreateKeyValue` operation in RevCent.

A Key Value is an account-wide value accessible by a unique key. Key Values are useful for shared configuration, reusable shortcodes, API-call pointers, and Function state/configuration.

Sources:
- RevCent operation schema for `CreateKeyValue`
- RevCent operation schema for `EditKeyValue`
- RevCent operation schema for `GetKeyValue`
- RevCent operation schema for `GetKeyValues`
- RevCent Knowledge Base: https://kb.revcent.com/en/tools/key-value

---

## Operation Summary

`CreateKeyValue` creates a system-wide Key Value in the RevCent account.

The schema states:

```text
Only use this operation if explicitly told to create a Key Value.
This is NOT related to inserting metadata.
If instructed to insert metadata, use the InsertMetadata operation.
```

This distinction is critical.

A Key Value is not metadata.

A Key Value is an account-wide named value that can be referenced by supported RevCent tools and features.

---

# Critical Rule: Only Create When Explicitly Asked

MCP/AI should only call `CreateKeyValue` when the user or client explicitly asks to create/save/store a Key Value.

Correct user intent:

```text
Create a Key Value called default_payment_profile.
Save this as a Key Value.
Create a Key Value for the active payment profile.
Store this value as a RevCent key value.
```

Incorrect MCP behavior:

```text
The user gave a useful value, so I will create a Key Value.
This configuration might be reusable, so I will silently save it.
The user asked to add metadata, so I will create a Key Value.
```

Rule:

```text
No explicit Key Value creation request = no CreateKeyValue call.
```

---

# Key Values Are Not Metadata

Key Values and metadata serve different purposes.

| Concept | Purpose |
|---|---|
| Key Value | Account-wide value accessed by key across supported RevCent tools/features. |
| Metadata | Data attached to a specific item, such as a customer, sale, transaction, or other record. |

If the user says:

```text
Add metadata to this customer.
Insert metadata on this sale.
Save this metadata field.
```

do not use `CreateKeyValue`.

Use the metadata operation instead.

---

# Required Fields

| Field | Type | Required | Description |
|---|---:|---:|---|
| `key` | string | Yes | Unique immutable key name. |
| `value` | string | Yes | Value for the key. Cannot exceed 5 MB. |

---

# Optional Fields

| Field | Type | Description |
|---|---:|---|
| `description` | string | Optional description. Maximum 255 characters. |
| `key_type` | enum | Either `string` or `pointer`. Defaults to `string`. |
| `pointer_type` | enum | Required if `key_type = pointer`. Currently supports `payment_profile`. |

The schema has:

```json
"additionalProperties": false
```

Do not send unknown fields.

---

# `key`

The `key` is the unique name used to access the Key Value.

The key cannot be modified once created.

Rules:

```text
Minimum length: 2
Maximum length: 100
Alphabetical characters and underscores only
Cannot start with underscore
Cannot end with underscore
Cannot contain spaces
Cannot contain numbers
Cannot contain hyphens
Cannot contain periods
```

Schema pattern:

```text
^[a-zA-Z](?:_?[a-zA-Z]+)*$
```

Good keys:

```text
support_email
default_payment_profile
active_renewal_profile
last_processed_sale
daily_report_cursor
brand_voice
checkout_footer
```

Invalid keys:

```text
_support_email
support_email_
support-email
support.email
support email
support_email_1
1support_email
a
```

MCP/AI should choose stable, descriptive key names because the key cannot be changed later.

---

# `description`

The description should explain:

- What the Key Value is for
- Which RevCent features use it
- Whether it is a string or pointer
- If it is state, what updates it
- If it is a pointer, what entity it points to
- Whether Functions or AI Assistants are expected to read/update it
- Any operational risk

Examples:

```text
Support email used in Email Templates and AI Assistant messages.
```

```text
Pointer to the active payment profile used by API-call pointer shortcuts.
```

```text
Function-managed cursor storing the last processed sale ID for nightly reporting.
```

Description maximum:

```text
255 characters
```

---

# `value`

The value is a string and cannot exceed 5 MB.

For `key_type = string`, the value is the raw string stored for the key.

Examples:

```json
{
  "key": "support_email",
  "value": "support@example.com"
}
```

```json
{
  "key": "daily_report_cursor",
  "value": "{\"last_sale_id\":\"XXXXXXXXXXXXXXXXXXXX\",\"last_run_unix\":1740000000}"
}
```

For `key_type = pointer`, the value must be either the RevCent ID or name of the item matching the `pointer_type`.

Example:

```json
{
  "key": "active_payment_profile",
  "value": "Primary Credit Card Profile",
  "key_type": "pointer",
  "pointer_type": "payment_profile"
}
```

or:

```json
{
  "key": "active_payment_profile",
  "value": "XXXXXXXXXXXXXXXXXXXX",
  "key_type": "pointer",
  "pointer_type": "payment_profile"
}
```

---

# `key_type`

Allowed values:

```text
string
pointer
```

Default:

```text
string
```

## `string`

A string Key Value stores a raw string value up to 5 MB.

String Key Values are useful for:

- Shared text
- Shared config
- Shortcodes
- Feature flags
- Function state
- JSON state objects
- Dynamic content
- Operational cursors

## `pointer`

A pointer Key Value points to another RevCent entity.

Pointer Key Values are useful for aliases.

For example, a pointer can point to a payment profile, allowing supported API-call pointer shortcodes to resolve to the current target payment profile ID.

Currently supported pointer type from the schema:

```text
payment_profile
```

---

# `pointer_type`

Required when:

```text
key_type = pointer
```

Currently allowed:

```text
payment_profile
```

If `pointer_type = payment_profile`, then `value` must match an existing payment profile by ID or name.

MCP/AI should verify the payment profile exists before creating a pointer.

Do not create a pointer to a non-existent item.

---

# Key Value Availability Across RevCent

The Key Value KB describes where Key Values can be used.

## Email Templates

Email Templates can use Key Values with double-curly shortcode syntax:

```handlebars
{{key_values.my_key}}
```

For string Key Values:

```text
Outputs the raw string value.
```

For pointer Key Values:

```text
Outputs the raw pointer value, such as the target payment profile ID.
```

Example:

```handlebars
Contact us at {{key_values.support_email}}.
```

---

## AI Assistant Messages

AI Assistant messages can use Key Values with bracket shortcode syntax:

```text
[key_values.my_key]
```

This can be used in:

```text
Web Chat messages
Autonomous assistant node step messages
Branch messages
```

Example:

```text
For support, contact [key_values.support_email].
```

---

## API Call Pointers

API calls can use pointer Key Values with bracket shortcode syntax:

```text
[key_values.my_key]
```

Important:

```text
Only pointer key types are supported in API calls at this time.
String key types are not supported in API calls to avoid misconfiguration and payment errors.
```

Example:

```json
{
  "payment_profile": "[key_values.active_payment_profile]"
}
```

If `active_payment_profile` is a pointer to a payment profile, RevCent replaces the shortcode with the target payment profile ID.

This is useful because MCP/API workflows can reference a stable key rather than hardcoding the payment profile ID.

---

## Functions

Functions can access Key Values through the RevCent Function object:

```javascript
global["revcent"].GetKeyValue(my_key, callback)
```

Functions can also update string Key Values through:

```javascript
global["revcent"].UpdateKeyValue(my_key, value, callback)
```

Important:

```text
Functions can only update Key Values with key_type = string.
Pointer Key Values cannot be updated within a Function.
```

This makes string Key Values useful for Function-managed state.

---

# Key Values and Functions for State Management

One of the most powerful uses of Key Values is Function state management.

A RevCent Function is often stateless by default. A Key Value can store shared state between Function runs.

Use cases include:

## Last Processed Cursor

Store the last processed item ID.

Example key:

```text
last_processed_sale
```

Value:

```json
{
  "last_sale_id": "XXXXXXXXXXXXXXXXXXXX",
  "last_run_unix": 1740000000
}
```

Use case:

```text
A scheduled Function runs every hour and only processes sales after the last processed sale ID or timestamp.
```

## Report Checkpoint

Store when a report last ran.

Example key:

```text
daily_report_cursor
```

Value:

```json
{
  "last_run_date": "2026-05-30",
  "last_run_unix": 1770000000
}
```

Use case:

```text
A reporting Function avoids duplicating reports by checking the last run state.
```

## Feature Flag

Store whether a Function behavior is enabled.

Example key:

```text
fraud_alerts_enabled
```

Value:

```text
true
```

Use case:

```text
A Function checks this key before sending fraud alerts to Slack.
```

## Dynamic Threshold

Store an adjustable threshold.

Example key:

```text
vip_ltv_threshold
```

Value:

```text
500
```

Use case:

```text
A Function checks customer lifetime value against a threshold without hardcoding the threshold in function_code.
```

## External Integration Cursor

Store an external API cursor.

Example key:

```text
shippo_sync_cursor
```

Value:

```json
{
  "cursor": "abc123",
  "last_sync_unix": 1770000000
}
```

Use case:

```text
A Function syncs external shipping updates without reprocessing old records.
```

---

# Function State Management Best Practices

When using Key Values for Function state:

1. Use `key_type = string`.
2. Store structured state as JSON string.
3. Keep values under 5 MB.
4. Use descriptive keys.
5. Document which Function owns or updates the state.
6. Use `GetKeyValue` before updating when preserving previous state matters.
7. Avoid storing secrets unless RevCent explicitly documents this as safe for your use case.
8. Avoid using Key Values for high-frequency counters if concurrency/race conditions may matter.
9. Do not assume updates are atomic unless RevCent explicitly documents atomic behavior.
10. Do not let multiple Functions update the same key unless intentional.

Example structured state:

```json
{
  "last_processed_id": "XXXXXXXXXXXXXXXXXXXX",
  "last_run_unix": 1770000000,
  "version": 1
}
```

---

# Key Values vs Environment Variables in Functions

Key Values and environment variables are different.

| Concept | Best for |
|---|---|
| Key Value | Shared account-wide config or state that may be read/updated by supported tools. |
| Environment Variable | Sensitive secrets or Function-specific configuration. |

Use environment variables for:

```text
API keys
Tokens
Passwords
Secrets
Private credentials
```

Use Key Values for:

```text
Shared settings
Reusable public values
Function cursors
Feature flags
Payment profile pointer aliases
Template shortcodes
AI Assistant message shortcodes
```

---

# Key Values vs AI Prompts

A Key Value is not an AI Prompt.

| Concept | Purpose |
|---|---|
| Key Value | Account-wide key-accessible value or pointer. |
| AI Prompt | Saved reusable prompt text. |

Do not create a Key Value when the user asks to save an AI Prompt.

---

# Key Values vs AI Voice Snippets

A Key Value is not an AI Voice Snippet.

| Concept | Purpose |
|---|---|
| Key Value | Shared value or pointer used across supported RevCent features. |
| AI Voice Snippet | Reusable AI Voice Agent instruction content. |

Do not create a Key Value when the user asks for reusable AI Voice Agent instructions.

---

# Create Examples

## Example 1: Support Email for Templates and AI Assistants

```json
{
  "key": "support_email",
  "description": "Support email used in Email Templates and AI Assistant messages.",
  "value": "support@example.com",
  "key_type": "string"
}
```

Email Template usage:

```handlebars
{{key_values.support_email}}
```

AI Assistant message usage:

```text
[key_values.support_email]
```

---

## Example 2: Payment Profile Pointer

```json
{
  "key": "active_payment_profile",
  "description": "Pointer to the active payment profile used by API-call pointer shortcuts.",
  "value": "Primary Credit Card Profile",
  "key_type": "pointer",
  "pointer_type": "payment_profile"
}
```

API call usage:

```json
{
  "payment_profile": "[key_values.active_payment_profile]"
}
```

---

## Example 3: Function State Cursor

```json
{
  "key": "daily_report_cursor",
  "description": "Function-managed state cursor for the daily reporting Function.",
  "value": "{\"last_run_unix\":0,\"last_processed_sale_id\":null}",
  "key_type": "string"
}
```

Function use:

```javascript
global["revcent"].GetKeyValue("daily_report_cursor", function(error, value) {
  if (error) {
    callback(error);
    return;
  }

  const state = JSON.parse(value || "{}");

  // Do work here...

  const nextState = JSON.stringify({
    last_run_unix: Math.floor(Date.now() / 1000),
    last_processed_sale_id: "XXXXXXXXXXXXXXXXXXXX"
  });

  global["revcent"].UpdateKeyValue("daily_report_cursor", nextState, callback);
});
```

---

# MCP Creation Workflow

Before calling `CreateKeyValue`, MCP/AI should:

1. Confirm the user explicitly asked to create a Key Value.
2. Confirm the user is not asking for metadata.
3. Determine whether the key should be `string` or `pointer`.
4. Validate the key name.
5. Confirm the key cannot be changed later.
6. Ensure the value is known and under 5 MB.
7. If pointer, confirm `pointer_type`.
8. If pointer, verify the target item exists.
9. Write a clear description.
10. Confirm intended usage: Email Template, AI Assistant, API pointer, Function state, or other.
11. If Function state, use `key_type = string`.
12. If API call pointer, use `key_type = pointer`.

---

# Validation Checklist

Before submitting `CreateKeyValue`:

1. `key` is present.
2. `key` is 2 to 100 characters.
3. `key` contains only letters and underscores.
4. `key` does not start or end with underscore.
5. `key` contains no numbers, spaces, hyphens, or periods.
6. `key` is stable because it cannot be modified later.
7. `value` is present.
8. `value` is under 5 MB.
9. `description` is under 255 characters if provided.
10. `key_type` is either `string` or `pointer`.
11. If `key_type` is omitted, MCP understands it defaults to `string`.
12. If `key_type = pointer`, `pointer_type` is present.
13. If `pointer_type = payment_profile`, the value matches an existing payment profile ID or name.
14. The operation is not being used for metadata.
15. The operation is only used because the user/client explicitly requested Key Value creation.
16. No unknown fields are included.

---

# Output Schema

Successful response:

```json
{
  "api_call_id": "XXXXXXXXXXXXXXXXXXXX",
  "api_call_unix": 1740000000,
  "code": 1,
  "key": "support_email",
  "description": "Support email used in templates.",
  "value": "support@example.com",
  "key_type": "string",
  "pointer_type": null,
  "result": "..."
}
```

---

# Key Takeaways

```text
CreateKeyValue creates an account-wide key-accessible value.
```

```text
The key cannot be modified once created.
```

```text
Key Values are not metadata.
```

```text
String Key Values can be used for shortcodes and Function state management.
```

```text
Pointer Key Values can act as aliases for supported entities such as payment profiles.
```

```text
Functions can read Key Values and can update string Key Values through the global revcent object.
```


---
Document Parent Directory
* [Operations](https://revcent.com/documentation/markdown/mcp/operation/index.md) - AI/MCP details and overviews for operations available within the RevCent MCP.