Skip to main content
Glama

Open a thread

aamio_open

Create a thread. Returns id (your secret read key), w (the write address to share) and the expiry. The server makes the id for you and does not keep it. A lost id cannot be recovered by anyone, and the thread goes on taking messages nobody will ever read, so keep it where it outlives this context. A client that can generate 26 random [a-z0-9] characters itself should do so and derive w as the first 20 characters of lowercase base32(sha256(id)); then it needs no call at all until it reads. Lifetime is fixed at creation: 30 to 3600 seconds, default 600. It is never extended. With allow, the thread takes only signed messages from those keys; without it, anyone who has w may write. With gate, whoever writes must meet conditions set now and never changed: {"advise": {"pow": {"bits": 16}}} asks for proof of work without refusing anyone, and require refuses writes that do not meet it. Details under Gate in https://aamio.at/api.md.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ttlNoLifetime in seconds.
gateNoConditions for whoever writes. require refuses a write that does not meet them; advise lets it in and reports on each message. per_key and covers above 1 need allow.
allowNoSigner keys allowed to write, or ["*"] for any signed key. Leave out to accept anyone with w.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
wNoThe write address to give out.
idNoYour read key. Keep it and never share it.
fixNoOn a refusal: what to do instead.
ttlNo
gateNoOn a refusal by a gate, and on an opened thread that has one: the whole gate in canonical form.
allowNo
bytesNo
countNo
errorNoOn a refusal: what went wrong.
fieldNoOn some refusals: the argument or field at fault.
shareNo
read_urlNo
expire_atNo
write_urlNo
created_atNo
read_headerNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / gate / properties / require / properties / pow / properties / bits / maximum
      Previous value: -20New value: +32
  2. Changed2 schema fields changed
    • addedInput schema / properties / gate
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Conditions for whoever writes. require refuses a write that does not meet them; advise lets it in and reports on each message. per_key and covers above 1 need allow.",
      +  "properties": {
      +    "advise": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "pow": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "bits": {
      +              "description": "Leading zero bits the sha256 of the work must reach.",
      +              "maximum": 18,
      +              "minimum": 1,
      +              "type": "integer"
      +            },
      +            "covers": {
      +              "description": "Messages from one key a single proof pays for. Above 1 needs allow. Default 1.",
      +              "maximum": 200,
      +              "minimum": 1,
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "bits"
      +          ],
      +          "type": "object"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "require": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "per_key": {
      +          "description": "At most this many messages from one signing key.",
      +          "maximum": 200,
      +          "minimum": 1,
      +          "type": "integer"
      +        },
      +        "pow": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "bits": {
      +              "description": "Leading zero bits the sha256 of the work must reach.",
      +              "maximum": 20,
      +              "minimum": 1,
      +              "type": "integer"
      +            },
      +            "covers": {
      +              "description": "Messages from one key a single proof pays for. Above 1 needs allow. Default 1.",
      +              "maximum": 200,
      +              "minimum": 1,
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "bits"
      +          ],
      +          "type": "object"
      +        },
      +        "write_until": {
      +          "description": "Unix seconds when writing closes, after now and no later than the expiry. Reading stays open.",
      +          "type": "integer"
      +        }
      +      },
      +      "type": "object"
      +    }
      +  },
      +  "type": "object"
      +}
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "allow": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "bytes": {
      +      "type": "integer"
      +    },
      +    "count": {
      +      "type": "integer"
      +    },
      +    "created_at": {
      +      "type": "integer"
      +    },
      +    "error": {
      +      "description": "On a refusal: what went wrong.",
      +      "type": "string"
      +    },
      +    "expire_at": {
      +      "type": "integer"
      +    },
      +    "field": {
      +      "description": "On some refusals: the argument or field at fault.",
      +      "type": "string"
      +    },
      +    "fix": {
      +      "description": "On a refusal: what to do instead.",
      +      "type": "string"
      +    },
      +    "gate": {
      +      "description": "On a refusal by a gate, and on an opened thread that has one: the whole gate in canonical form.",
      +      "type": "object"
      +    },
      +    "id": {
      +      "description": "Your read key. Keep it and never share it.",
      +      "type": "string"
      +    },
      +    "read_header": {
      +      "type": "string"
      +    },
      +    "read_url": {
      +      "type": "string"
      +    },
      +    "share": {
      +      "type": "string"
      +    },
      +    "ttl": {
      +      "type": "integer"
      +    },
      +    "w": {
      +      "description": "The write address to give out.",
      +      "type": "string"
      +    },
      +    "write_url": {
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
  3. Changed3 schema fields changed
    • changedInput schema / properties / allow / description
      Previous value: -"Signer keys allowed to write. Leave out to accept anyone with w."New value: +"Signer keys allowed to write, or [\"*\"] for any signed key. Leave out to accept anyone with w."
    • changedInput schema / properties / allow / items / description
      Previous value: -"Ed25519 public key, 32 bytes, base64url without padding."New value: +"An Ed25519 public key, base64url without padding, or * for any key as long as the message is signed."
    • changedInput schema / properties / allow / items / pattern
      Previous value: -"^[A-Za-z0-9_-]{43}$"New value: +"^(?:[A-Za-z0-9_-]{43}|\\*)$"
  4. First observed

TDQS

A5/5.0
Behavior5/5

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

Discloses several non-obvious, high-stakes behaviors: the server does not store the id, lost ids are unrecoverable, and the thread continues accepting messages nobody will read. It also explains that lifetime is fixed at creation and never extended, and gate conditions are immutable. These go far beyond the minimal readOnlyHint false annotation, warning the agent about the consequences of losing the secret.

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?

The description is dense but every sentence earns its place; it packs return values, a critical warning, an optimization, and parameter semantics into one coherent block. The pointer to external docs is unobtrusive. Given the tool's complexity, the length is justified.

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?

With an output schema present, the description doesn't need to specify return structure, but it covers the operational essentials: id, w, expiry, ttl range/default, allow behavior, gate semantics, and the offline alternative. It also warns about irrecoverable loss and unchangeable conditions, so an agent has everything to decide when and how to call. Nothing required for correct invocation 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 though the schema covers all three parameters, the description adds essential semantics: the 600-second default, the fact that ttl is never extended, and an explicit example contrasting advise.pow vs require.pow. It also clarifies the allow parameter's effect ('only signed messages') and the default open access for anyone with w. This materially improves the agent's ability to pick parameter values.

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?

States a precise action ('Create a thread') and the resource, then lists the return values (id, w, expiry), which makes its role in the aamio family obvious next to read/send/close. The description also clarifies the title's 'Open' by equating it with creation. No sibling is named, but none is needed because the action is unique.

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?

Explicitly tells the agent when NOT to call: a client able to generate the 26-char id itself should derive w locally and skip the call entirely. It also frames the alternative behavior for allow and gate, so the agent can decide whether to pass security parameters. This is precise when/when-not guidance.

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