Skip to main content
Glama

Register an action

register_action

Tell Ogen which fact an action kind depends on, and how costly that action is to undo. Actions that are costly to undo wait for a person, so any cost other than "read" must name the approver who decides them — register that person with register_approver first. Record only. Each kind with a named approver is one scope; Record covers 5, and more can be added.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
keyYesThe bound key this kind depends on.
costYesHow costly this kind of action is to undo. The costlier it is to undo, the more a person is involved before it happens.
kindYesThe action kind commit_gated_action will be called with.
approverNoThe name of the person who confirms a hold on this kind (see register_approver), or the reserved word "principal" — the kind then waits for whoever commit_gated_action's own ask names (principal: { email }), never a registered approver. Required for any cost other than "read", and for decide_with "passkey_only" (which a principal-gated kind can never use — a principal has no passkey). Omit to leave an already-registered approver unchanged; pass null to clear the approver, which only a "read" kind with decide_with "token_or_passkey" may do.
decide_withNoWhich door may decide this kind's holds: the mailed one-time token or a passkey ("token_or_passkey", the default), or a passkey only ("passkey_only") — requires approver. Omit to leave an already-registered kind's setting unchanged.
release_whenNoRelease this kind without a person when its OWN bound fact — read live, the business's own record — resolves and satisfies exactly one rule: fact_equals (a string match) or fact_at_least (a number comparison against a named argument of the ask). Never both, never anything else. A fact that disagrees between systems, or can't be read, always waits for a person. Shares the same daily count as auto_release_under (one counter, not two). Applies to a caller's ask too — your own record deciding, not a limit you set. Only on a cost "expensive" kind; never with decide_with "passkey_only". Owner key only. Omit to leave unchanged; pass null to clear.
hold_ttl_hoursNoHow long a hold on this kind waits for a person, in whole hours (1-168, default 24). Omit to leave unchanged. A longer window is a longer time for the fact to move; a decision still goes by the fact as it stands when it runs.
fallback_approverNoA second registered approver (see register_approver) who is handed a hold on this kind once half its life has passed with no decision. The approver can still decide. Omit to leave unchanged; pass null to clear.
auto_release_underNoRelease this kind without a person when its fact is settled and the arguments' amount is under a limit. A disagreement between systems still waits for a person, whatever the amount. Never with decide_with "passkey_only". Only on a cost "expensive" kind. At most auto_release_per_day releases of this kind in any 24 hours (default 20); past that, a person decides. The value is compared in your own unit (cents or dollars is yours) on that one field; the release ticket binds every argument. Owner key only. Omit to leave unchanged; pass null to clear.
auto_release_per_dayNoHow many times a day this kind may be released without a person: a count, 1-200, over any 24 hours (default 20). Past it, a person decides. Ogen keeps no amount; the most released in a day is your limit times this count. Only on a cost "expensive" kind. Owner key only. Omit to leave unchanged; pass null to go back to the default.
hold_ttl_skip_weekendsNoCount only working days toward hold_ttl_hours — your weekend (Saturday-Sunday unless you set another with settings action "contact"), in your timezone. Refused until your timezone is set with settings action "contact". Default false. Omit to leave unchanged.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / approver / description
      Previous value: -"The name of the person who confirms a hold on this kind (see register_approver). Required for any cost other than \"read\", and for decide_with \"passkey_only\". Omit to leave an already-registered approver unchanged; pass null to clear the approver, which only a \"read\" kind with decide_with \"token_or_passkey\" may do."New value: +"The name of the person who confirms a hold on this kind (see register_approver), or the reserved word \"principal\" — the kind then waits for whoever commit_gated_action's own ask names (principal: { email }), never a registered approver. Required for any cost other than \"read\", and for decide_with \"passkey_only\" (which a principal-gated kind can never use — a principal has no passkey). Omit to leave an already-registered approver unchanged; pass null to clear the approver, which only a \"read\" kind with decide_with \"token_or_passkey\" may do."
    • addedInput schema / properties / release_when
      Added value: +{
      +  "anyOf": [
      +    {
      +      "anyOf": [
      +        {
      +          "additionalProperties": false,
      +          "properties": {
      +            "fact_equals": {
      +              "description": "Release when this kind's own bound fact resolves and equals this string exactly.",
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "fact_equals"
      +          ],
      +          "type": "object"
      +        },
      +        {
      +          "additionalProperties": false,
      +          "properties": {
      +            "fact_at_least": {
      +              "description": "Release when this kind's own bound fact resolves to a number at least as large as this argument, e.g. \"quantity\".",
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "fact_at_least"
      +          ],
      +          "type": "object"
      +        }
      +      ]
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Release this kind without a person when its OWN bound fact — read live, the business's own record — resolves and satisfies exactly one rule: fact_equals (a string match) or fact_at_least (a number comparison against a named argument of the ask). Never both, never anything else. A fact that disagrees between systems, or can't be read, always waits for a person. Shares the same daily count as auto_release_under (one counter, not two). Applies to a caller's ask too — your own record deciding, not a limit you set. Only on a cost \"expensive\" kind; never with decide_with \"passkey_only\". Owner key only. Omit to leave unchanged; pass null to clear."
      +}
  2. Changed1 schema field changed
    • changedInput schema / properties / hold_ttl_skip_weekends / description
      Previous value: -"Count only working days toward hold_ttl_hours — your weekend (Saturday-Sunday unless you set another with set_contact), in your timezone. Refused until your timezone is set with set_contact. Default false. Omit to leave unchanged."New value: +"Count only working days toward hold_ttl_hours — your weekend (Saturday-Sunday unless you set another with settings action \"contact\"), in your timezone. Refused until your timezone is set with settings action \"contact\". Default false. Omit to leave unchanged."
  3. Changed2 schema fields changed
    • addedInput schema / properties / auto_release_per_day
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 200,
      +      "minimum": 1,
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "How many times a day this kind may be released without a person: a count, 1-200, over any 24 hours (default 20). Past it, a person decides. Ogen keeps no amount; the most released in a day is your limit times this count. Only on a cost \"expensive\" kind. Owner key only. Omit to leave unchanged; pass null to go back to the default."
      +}
    • addedInput schema / properties / auto_release_under
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "currency": {
      +          "description": "Optional: a three-letter code. The arguments' \"currency\" must match it.",
      +          "type": "string"
      +        },
      +        "field": {
      +          "description": "The argument that carries the amount, e.g. \"amount\".",
      +          "type": "string"
      +        },
      +        "value": {
      +          "description": "Release without a person only when that argument is a number strictly under this.",
      +          "type": "number"
      +        }
      +      },
      +      "required": [
      +        "field",
      +        "value"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Release this kind without a person when its fact is settled and the arguments' amount is under a limit. A disagreement between systems still waits for a person, whatever the amount. Never with decide_with \"passkey_only\". Only on a cost \"expensive\" kind. At most auto_release_per_day releases of this kind in any 24 hours (default 20); past that, a person decides. The value is compared in your own unit (cents or dollars is yours) on that one field; the release ticket binds every argument. Owner key only. Omit to leave unchanged; pass null to clear."
      +}
  4. Changed3 schema fields changed
    • addedInput schema / properties / fallback_approver
      Added value: +{
      +  "description": "A second registered approver (see register_approver) who is handed a hold on this kind once half its life has passed with no decision. The approver can still decide. Omit to leave unchanged; pass null to clear.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / hold_ttl_hours
      Added value: +{
      +  "description": "How long a hold on this kind waits for a person, in whole hours (1-168, default 24). Omit to leave unchanged. A longer window is a longer time for the fact to move; a decision still goes by the fact as it stands when it runs.",
      +  "maximum": 168,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / hold_ttl_skip_weekends
      Added value: +{
      +  "description": "Count only working days toward hold_ttl_hours — your weekend (Saturday-Sunday unless you set another with set_contact), in your timezone. Refused until your timezone is set with set_contact. Default false. Omit to leave unchanged.",
      +  "type": "boolean"
      +}
  5. Changed3 schema fields changed
    • removedInput schema / properties / fallback_approver
      Removed value: -{
      -  "description": "A second registered approver (see register_approver) who is handed a hold on this kind once half its life has passed with no decision. The approver can still decide. Omit to leave unchanged; pass null to clear.",
      -  "type": [
      -    "string",
      -    "null"
      -  ]
      -}
    • removedInput schema / properties / hold_ttl_hours
      Removed value: -{
      -  "description": "How long a hold on this kind waits for a person, in whole hours (1-168, default 24). Omit to leave unchanged. A longer window is a longer time for the fact to move; a decision still goes by the fact as it stands when it runs.",
      -  "maximum": 168,
      -  "minimum": 1,
      -  "type": "integer"
      -}
    • removedInput schema / properties / hold_ttl_skip_weekends
      Removed value: -{
      -  "description": "Count only Monday-Friday time, in your timezone (set_contact), toward hold_ttl_hours. Default false. Omit to leave unchanged.",
      -  "type": "boolean"
      -}
  6. Changed3 schema fields changed
    • addedInput schema / properties / fallback_approver
      Added value: +{
      +  "description": "A second registered approver (see register_approver) who is handed a hold on this kind once half its life has passed with no decision. The approver can still decide. Omit to leave unchanged; pass null to clear.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / hold_ttl_hours
      Added value: +{
      +  "description": "How long a hold on this kind waits for a person, in whole hours (1-168, default 24). Omit to leave unchanged. A longer window is a longer time for the fact to move; a decision still goes by the fact as it stands when it runs.",
      +  "maximum": 168,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / hold_ttl_skip_weekends
      Added value: +{
      +  "description": "Count only Monday-Friday time, in your timezone (set_contact), toward hold_ttl_hours. Default false. Omit to leave unchanged.",
      +  "type": "boolean"
      +}
  7. Changed2 schema fields changed
    • changedInput schema / properties / approver / description
      Previous value: -"The name of the person who confirms a hold on this kind (see register_approver). Required for any cost other than \"read\". Omit to leave an already-registered approver unchanged; pass null to clear the approver, which only a \"read\" kind may do."New value: +"The name of the person who confirms a hold on this kind (see register_approver). Required for any cost other than \"read\", and for decide_with \"passkey_only\". Omit to leave an already-registered approver unchanged; pass null to clear the approver, which only a \"read\" kind with decide_with \"token_or_passkey\" may do."
    • addedInput schema / properties / decide_with
      Added value: +{
      +  "description": "Which door may decide this kind's holds: the mailed one-time token or a passkey (\"token_or_passkey\", the default), or a passkey only (\"passkey_only\") — requires approver. Omit to leave an already-registered kind's setting unchanged.",
      +  "enum": [
      +    "token_or_passkey",
      +    "passkey_only"
      +  ],
      +  "type": "string"
      +}
  8. First observed

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden and does so meaningfully: it explains that costly actions wait for a person, that a non-'read' cost requires a named approver, and that the approver must be registered first. It also discloses a scope limit ('Each kind with a named approver is one scope; Record covers 5'). It omits re-registration/update semantics and return behavior, but the core mental model is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with the core purpose and the key conditional rule about approvers. Little waste, though the final scope sentence ('Record covers 5, and more can be added') is jargon-heavy and less self-explanatory than the rest.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 11-parameter mutation tool with no annotations and no output schema, the description covers the essential registration model and the approver prerequisite, with the schema handling parameter detail. However, the cryptic scope/plan sentence leaves the 'Record covers 5' constraint unexplained, and there is no disclosure of what happens on re-registration or what the tool returns.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 11 parameters in depth, including the cost/approver coupling and omit-to-leave-unchanged semantics. The description reinforces the cost-to-approver rule and the register_approver dependency, but adds no syntax or format detail beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ('Tell Ogen which fact an action kind depends on, and how costly that action is to undo'), which is clear about what registering an action kind means. It differentiates from the sibling register_approver by making it a prerequisite rather than an alternative. The trailing 'Record only' and scope-counting sentences are cryptic without further context, slightly muddying the purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives one concrete prerequisite ordering: any cost other than 'read' must name an approver, and that person must be registered with register_approver first. However, it never states when to use register_action versus sibling tools like commit_gated_action or bind_source, nor any exclusions. Usage is implied rather than fully guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources