Skip to main content
Glama

Propose Run Scope

propose_scope
Destructive

Propose what this run will touch and block until the user ratifies it. Call ONCE at the start of a multi-step run, before doing work. The user sees the paths you intend to change, the areas you promise to leave alone, and your definition of done, and approves the whole thing in one tap. After that, editing a file outside the agreed scope stops being auto-approvable: it becomes a separate "wants to widen scope" question instead of a silent approval, so you are asked once about the boundary rather than repeatedly about each file. Use glob syntax ("src/", "docs/"). WHAT IS ENFORCED: only file paths, and only for tool calls that carry one (Edit, Write, MultiEdit). Shell commands, Read, web requests and every MCP tool carry no path, so a contract says nothing about them and they stay governed by the permission policy. A contract with no paths at all therefore gates NOTHING: use promises for a run that touches no files, and read the returned "enforces" rather than assuming ratified:true means something is being checked. A scope can only turn an automatic approval into a question; it never turns a question into an approval. Scope lives for this session only and is never inherited by another run. Returns { correlationId, ratified, answered, value, enforces, contract }. If the first wait times out, poll its correlationId once; a late phone yes ratifies the stored proposal. If that poll is also pending, cancel it before asking in the current chat whether to continue without an enforced scope. If cancellation loses a race, honor the phone answer instead. Never describe a client-only agreement as ratification. SIDE EFFECT: sends a real push notification.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
doneWhenYesWhat "finished" means for this run, one or two lines. Carried for the human to judge against; never enforced automatically.
promisesNoBoundaries that are not file paths: recipients, channels, spend limits, systems you will not open. For an agent whose work is not code (marketing, sales, support, operations), this is where the boundary goes. Shown to the user labelled "Promised, not checked" and recorded in the ledger, but NEVER enforced, because the gate judges a file path and these have none. Do not put these in allowedPaths.
agentNameNoName of the agent asking, format "{Agent} - {project}".
machineIdNoStable machine id, so two machines never collapse into one session.
sessionIdYesYour per-session id, as your client reports it for THIS run. Required, and it is the key the gate reads the contract back by: a value that matches no live session still returns ratified:true and enforces nothing. Never invent one, and never reuse one from another run.
timeoutMsNoHow long this call blocks, in milliseconds (max 55000).
allowedPathsNoGlobs you intend to change, e.g. ["src/**", "docs/*.md"]. File paths only: a word that is not a path ("hubspot", "summer-campaign") matches no file and makes every edit read as out of scope. A bare directory is expanded for you, so "docs" also covers "docs/**". Omit or leave empty to propose no path restriction, which the user is told plainly.
offLimitsPathsNoGlobs you promise not to touch, e.g. [".env*", "infra/**"]. These win wherever they overlap allowedPaths. A leading "**/" needs a directory before it, so "**/.env*" is expanded for you to also cover a root ".env".

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
noteNoPresent only when the scope is not in force, saying what to do instead of proceeding.
valueNoThe raw answer behind ratified, "yes" or "no".
statusNoThe underlying scope-question state.
answeredYesTrue when the user responded at all. Answered but not ratified means they declined, so ask what scope they want rather than proceeding.
contractYesThe scope as it is STORED and gated, echoed back so you and the server hold the same contract. Paths are the EXPANDED ones: a bare directory and a leading "**/" each gain the variant they would otherwise have missed, so this can contain more entries than you sent. The user was shown the paths you sent, because the added twin says the same thing to a reader; the expansion only changes what the matcher covers, never what it means.
enforcesYesWhat this contract CONTAINS that can be checked, not a promise about what the gate on this machine will do. An EMPTY array means nothing here is checked automatically: the contract is a recorded promise, and every action stays governed by the permission policy exactly as it was before. Never tell the user a boundary is enforced when this is empty.
hookSeenNoWhether any agent hook has actually reported this sessionId. FALSE means the gate will look this contract up under a key that does not exist, so nothing will be checked no matter what ratified says: fix the session id rather than proceeding as if a scope were in force. ABSENT means the check could not run, which is not evidence either way.
ratifiedYesTrue only on an explicit yes. The contract is in force for this session only when this is true; anything else means proceed as if no scope was agreed.
nextActionNoPoll one live question once; otherwise ask in the current chat whether to continue without an enforced scope.
correlationIdYesId of the scope question. Pass it to wait_for_answer once when the first wait times out.
handoffActionNoRace-safe directive for updated clients. Takes precedence over nextAction.
enforcementNoteNoPresent only when there is something true to say about the limits of this contract. Repeat it to the user rather than paraphrasing it.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed12 schema fields changed
    • changedInput schema / properties / allowedPaths / description
      Previous value: -"Globs you intend to change, e.g. [\"src/**\", \"docs/*.md\"]. Omit or leave empty to propose no path restriction, which the user is told plainly."New value: +"Globs you intend to change, e.g. [\"src/**\", \"docs/*.md\"]. File paths only: a word that is not a path (\"hubspot\", \"summer-campaign\") matches no file and makes every edit read as out of scope. A bare directory is expanded for you, so \"docs\" also covers \"docs/**\". Omit or leave empty to propose no path restriction, which the user is told plainly."
    • changedInput schema / properties / offLimitsPaths / description
      Previous value: -"Globs you promise not to touch, e.g. [\"**/.env*\", \"infra/**\"]. These win wherever they overlap allowedPaths."New value: +"Globs you promise not to touch, e.g. [\".env*\", \"infra/**\"]. These win wherever they overlap allowedPaths. A leading \"**/\" needs a directory before it, so \"**/.env*\" is expanded for you to also cover a root \".env\"."
    • addedInput schema / properties / promises
      Added value: +{
      +  "description": "Boundaries that are not file paths: recipients, channels, spend limits, systems you will not open. For an agent whose work is not code (marketing, sales, support, operations), this is where the boundary goes. Shown to the user labelled \"Promised, not checked\" and recorded in the ledger, but NEVER enforced, because the gate judges a file path and these have none. Do not put these in allowedPaths.",
      +  "items": {
      +    "maxLength": 200,
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "maxItems": 10,
      +  "type": "array"
      +}
    • changedInput schema / properties / sessionId / description
      Previous value: -"Your per-session id. Required: a scope with no session cannot be enforced, and must never leak into another run."New value: +"Your per-session id, as your client reports it for THIS run. Required, and it is the key the gate reads the contract back by: a value that matches no live session still returns ratified:true and enforces nothing. Never invent one, and never reuse one from another run."
    • changedOutput schema / properties / contract / description
      Previous value: -"The scope exactly as it was put to the user, echoed back so the agent and the human are holding the same contract."New value: +"The scope as it is STORED and gated, echoed back so you and the server hold the same contract. Paths are the EXPANDED ones: a bare directory and a leading \"**/\" each gain the variant they would otherwise have missed, so this can contain more entries than you sent. The user was shown the paths you sent, because the added twin says the same thing to a reader; the expansion only changes what the matcher covers, never what it means."
    • changedOutput schema / properties / contract / properties / allowedPaths / description
      Previous value: -"Globs the run may change. Empty means no path restriction was proposed, which the user was told plainly."New value: +"Globs the run may change, after expansion. Empty means no path restriction was proposed, which the user was told plainly."
    • changedOutput schema / properties / contract / properties / offLimitsPaths / description
      Previous value: -"Globs the run promised not to touch. These win wherever they overlap allowedPaths."New value: +"Globs the run promised not to touch, after expansion. These win wherever they overlap allowedPaths."
    • addedOutput schema / properties / contract / properties / promises
      Added value: +{
      +  "description": "Non-path boundaries as the user saw them. Recorded, never enforced.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / enforcementNote
      Added value: +{
      +  "description": "Present only when there is something true to say about the limits of this contract. Repeat it to the user rather than paraphrasing it.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / enforces
      Added value: +{
      +  "description": "What this contract CONTAINS that can be checked, not a promise about what the gate on this machine will do. An EMPTY array means nothing here is checked automatically: the contract is a recorded promise, and every action stays governed by the permission policy exactly as it was before. Never tell the user a boundary is enforced when this is empty.",
      +  "items": {
      +    "enum": [
      +      "paths"
      +    ],
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / hookSeen
      Added value: +{
      +  "description": "Whether any agent hook has actually reported this sessionId. FALSE means the gate will look this contract up under a key that does not exist, so nothing will be checked no matter what ratified says: fix the session id rather than proceeding as if a scope were in force. ABSENT means the check could not run, which is not evidence either way.",
      +  "type": "boolean"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "correlationId",
      -  "ratified",
      -  "answered",
      -  "contract"
      -]New value: +[
      +  "correlationId",
      +  "ratified",
      +  "answered",
      +  "enforces",
      +  "contract"
      +]
  2. Changed5 schema fields changed
    • addedOutput schema / properties / correlationId
      Added value: +{
      +  "description": "Id of the scope question. Pass it to wait_for_answer once when the first wait times out.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / handoffAction
      Added value: +{
      +  "description": "Race-safe directive for updated clients. Takes precedence over nextAction.",
      +  "enum": [
      +    "cancel_then_ask_in_current_client",
      +    "stop"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / nextAction
      Added value: +{
      +  "description": "Poll one live question once; otherwise ask in the current chat whether to continue without an enforced scope.",
      +  "enum": [
      +    "wait_for_answer",
      +    "ask_in_current_client"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / status
      Added value: +{
      +  "description": "The underlying scope-question state.",
      +  "enum": [
      +    "answered",
      +    "pending",
      +    "cancelled",
      +    "expired",
      +    "missing",
      +    "unavailable",
      +    "notified",
      +    "terminal",
      +    "stopped"
      +  ],
      +  "type": "string"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "ratified",
      -  "answered",
      -  "contract"
      -]New value: +[
      +  "correlationId",
      +  "ratified",
      +  "answered",
      +  "contract"
      +]
  3. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "answered": {
      +      "description": "True when the user responded at all. Answered but not ratified means they declined, so ask what scope they want rather than proceeding.",
      +      "type": "boolean"
      +    },
      +    "contract": {
      +      "additionalProperties": false,
      +      "description": "The scope exactly as it was put to the user, echoed back so the agent and the human are holding the same contract.",
      +      "properties": {
      +        "allowedPaths": {
      +          "description": "Globs the run may change. Empty means no path restriction was proposed, which the user was told plainly.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "doneWhen": {
      +          "description": "What finished means for this run, as the user saw it.",
      +          "type": "string"
      +        },
      +        "offLimitsPaths": {
      +          "description": "Globs the run promised not to touch. These win wherever they overlap allowedPaths.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "allowedPaths",
      +        "offLimitsPaths",
      +        "doneWhen"
      +      ],
      +      "type": "object"
      +    },
      +    "note": {
      +      "description": "Present only when the scope is not in force, saying what to do instead of proceeding.",
      +      "type": "string"
      +    },
      +    "ratified": {
      +      "description": "True only on an explicit yes. The contract is in force for this session only when this is true; anything else means proceed as if no scope was agreed.",
      +      "type": "boolean"
      +    },
      +    "value": {
      +      "description": "The raw answer behind ratified, \"yes\" or \"no\".",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "ratified",
      +    "answered",
      +    "contract"
      +  ],
      +  "type": "object"
      +}
  4. First observed

TDQS

A5/5.0
Behavior5/5

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

Beyond the annotations, the description discloses the push-notification side effect, blocking behavior, timeout/polling/cancellation races, session-only lifetime, and the 'enforces' flag meaning. It thoroughly explains what is and isn't enforced without contradicting the existing annotations.

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

Conciseness5/5

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

Although long, every sentence carries essential operational detail and is logically structured: definition, usage, enforcement scope, edge cases, return value, and side effects. Front-loaded with the core directive and then expanding into the contractual nuances an agent must know.

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

Completeness5/5

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

For a tool with this complexity, the description covers all critical scenarios: polling, late ratification, cancellation races, no-path contracts, and clarifying that ratified:true doesn't imply enforcement. Combined with the rich output schema, nothing an agent needs to invoke it correctly is missing.

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

Parameters5/5

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

Even with 100% schema coverage, the description adds high-value parameter semantics: glob syntax expansion, directory auto-expansion, off-limits precedence, promises being never-enforced, doneWhen never auto-enforced, and sessionId matching behavior. These clarifications prevent misuse that raw schema would not.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Propose what this run will touch and block until the user ratifies it.' It clearly distinguishes itself from sibling tools (ask_user, send_notification, etc.) by stating it is the gate-setting action for a multi-step run.

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

Usage Guidelines5/5

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

The description explicitly says 'Call ONCE at the start of a multi-step run, before doing work' and gives detailed when-not-to-use guidance: use promises for file-less runs, note that shell/web/MCP calls are not covered, and a scope only turns auto-approvals into questions, never the reverse. This fully routes the agent to alternatives.

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