Skip to main content
Glama

airstrings

CLI and MCP server for AirStrings: over-the-air string updates for iOS, Android, web and React Native apps, and Go backends.

Manage strings and locales from the terminal or let an AI agent do it over MCP. airstrings publish has AirStrings sign the bundle (Ed25519) and push it to the CDN; the SDKs verify the signature before showing anything.

Listed in the MCP Registry as io.github.symbionix-sl/airstrings-cli.

Install

npm install -g @airstrings/cli                    # any platform, Node 18+
brew install symbionix-sl/airstrings/airstrings   # macOS / Linux
go install github.com/symbionix-sl/airstrings-cli/cmd/airstrings@latest   # Go 1.26.1+

Installs airstrings and airstrings-mcp.

Related MCP server: i1n

Quick start

cd my-project
airstrings init                                   # log in, create a project, bind this folder
airstrings strings set welcome.title en="Hello" es="Hola" --format text
airstrings push                                   # send local strings to staging
airstrings publish                                # sign + publish staging bundles
airstrings sdk-config                             # IDs, public key and SDK snippets for production

With no key, init opens the browser to log in (an owner of your organization approves), stores an org key in ~/.config/airstrings/credentials.json, creates a project named after the folder and writes .airstrings/config.json. --name <name> names the project, --project <id> binds an existing one, airstrings init <project-key> binds to the key's project. Without a terminal it waits up to 90 s for approval; on timeout, --no-browser or CI it exits 9 with the URL: approve, then re-run the same command.

Staging is active after init. Production is protected: it rejects direct writes and publishing, and changes reach it only by promotion, applied by a human in the dashboard or by airstrings promote --to production with a full-power org key.

Keys

Key

Prefix

Covers

Get it

Org key

as_org_

every project of the org

airstrings login

Project key

as_proj_

every environment of one project

dashboard → API keys

Legacy environment key

64 hex

one environment

created before 0.18

Precedence: AIRSTRINGS_ORG_API_KEY > AIRSTRINGS_API_KEY > workspace key > stored login. In CI use a project key in AIRSTRINGS_API_KEY; across several projects use a gated (non-full-power) org key from the dashboard in AIRSTRINGS_ORG_API_KEY. No init needed when one of these is set.

Commands

# Account and context
airstrings login | logout             # store / revoke the org key
airstrings org                        # stored logins; `org use <name|id>` switches
airstrings status                     # project, env, key scope, protection + next step
airstrings project                    # current project; `project ls` lists the org's
airstrings --project <id> <command>   # run against another project (org key)

# Environments
airstrings env                        # environments: protected/open, key stored or not
airstrings env use staging            # switch (shorthand: airstrings -e -u staging)
airstrings env rm <name>              # remove environment credentials
airstrings locales                    # locales with string counts
airstrings sdk-config [--env <name>]  # IDs + public keys + SDK snippets (default production)

# API keys
airstrings apikey ls                  # the project's keys (✓ = stored in this workspace)
airstrings apikey rotate              # rotate the workspace key
airstrings apikey revoke              # revoke the workspace's stored keys (e.g. after a leak)

# Strings (set/rm edit local CSVs; --push also writes to the API)
airstrings strings ls [--local] [--section <s>] [--locale <l>] [--limit <n>] [--key-prefix <p>]
airstrings strings get <key>
airstrings strings set <key> en="Hello" es="Hola" --format text|icu [--section <s>] [--push]
airstrings strings rm <key> [--locale <l>] [--section <s>] [--push]
airstrings sections list | create <name> [--description <d>] | delete <id>
airstrings push | pull [--section <s>]   # sync local CSVs with the API (draft strings)
airstrings import csv <file>             # bulk import; `import status <id>` to follow

# Publishing
airstrings publish [locale...]        # sign + publish bundles (all locales by default)
airstrings bundles                    # published bundles
airstrings promote preview            # diff staging → production + dashboard link to apply
airstrings promote --to production    # apply (full-power org key only)

# A/B experiments on a string (text only)
airstrings variants create <key>
airstrings variants set <key> <variant> en="Hi there"
airstrings variants allocation <key> control=50 <variant>=50
airstrings variants start|stop|status|rm <key>
airstrings variants promote <key> <variant>   # winner becomes the base string

# Org shared-key bucket
airstrings shared init <api-key>      # save the bucket's scoped write key
airstrings shared ls | add | rm | import <file>

Publishing to a protected environment exits 7 with the next step: publish to staging, then a human promotes at the printed link. airstrings <command> --help shows every flag.

Workspace

init creates .airstrings/ at the project root; commands find it from any subdirectory.

.airstrings/
  config.json                  # project, active env, workspace keys
  strings.csv                  # unsectioned strings
  onboarding/onboarding.csv    # one CSV per section

The CSVs are plain files you can commit.

Offline fallback bundles

airstrings bundles pull [dir] [--locale <bcp47>]
airstrings doctor                     # check the bundled-fallback integration

Downloads the published, signed bundles of the active environment into airstrings/bundles/ (or dir, saved to the workspace config) with a manifest.json, verifying every signature first. Commit the folder: SDKs seed from it on startup, re-verifying each bundle, so the app has strings on a cold offline start or in SSG/SSR builds. Re-run it in CI or before each release.

pull fetches draft strings as editable CSVs; bundles pull fetches published, signed bundles for shipping.

MCP server

airstrings mcp install                  # Claude Code
airstrings mcp install --claude-desktop # Claude Desktop
airstrings mcp status | uninstall

Other clients: run airstrings-mcp over stdio. Details: cmd/airstrings-mcp/README.md.

Tool

Does

airstrings_login, airstrings_init

log in, bind a folder to a project

airstrings_status, airstrings_env_list

active context, environments

airstrings_strings_set, airstrings_strings_rm, airstrings_strings_ls

edit and list local strings (optional push)

airstrings_push, airstrings_pull

sync local strings with the API

airstrings_publish

sign + publish bundles

airstrings_promote_preview

diff between environments + dashboard link

airstrings_sdk_config

IDs, public keys and SDK snippets

airstrings_variant_set, _start, _stop, _status, _promote

A/B experiments

Scripting

--json works on every command. Errors then go to stderr as {"error":{"message":"…","next_step":"…","exit_code":7}}.

Exit

Meaning

0

ok

1

generic error

2

usage / bad input

3

auth: bad or expired key, read key used for a write, or no key for this environment

4

not found

5

network (retry)

6

rate limited (retry)

7

environment protected: publish to staging, a human promotes

8

plan limit reached: upgrade

9

login pending: open the printed URL, approve, re-run

License

MIT, see LICENSE.

Available Tools

17 tools
airstrings_env_listA
Read-onlyIdempotent

List every environment of the project, same as airstrings env: name, ID, whether it is the default, protection (protected/open), whether this workspace holds a key for it, and which one is active. Use it to pick environment names for airstrings_promote_preview or airstrings_sdk_config; for the overall workspace state and next step, use airstrings_status.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. The description adds real value beyond that by disclosing what fields come back (protection mode, key presence, active environment) in the absence of an output schema. It stops short of describing ordering or formatting of the list.

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?

Two sentences, both front-loaded: the first defines the operation and its payload, the second routes to siblings. No filler or restated name/title.

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 zero-parameter read tool with no output schema, the description compensates by enumerating the returned fields and covering the sibling-routing decision. An agent has everything needed to call it correctly and interpret the result.

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

Parameters4/5

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

The tool takes no parameters, so there is nothing for the description to disambiguate; the baseline for a zero-param tool is 4. The description correctly avoids inventing arguments.

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 specific verb and resource ('List every environment of the project') and then enumerates exactly what is returned: name, ID, default flag, protection status, key presence, and active environment. An agent can distinguish it from airstrings_status without opening either schema.

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?

Gives explicit downstream usage ('Use it to pick environment names for airstrings_promote_preview or airstrings_sdk_config') and names the alternative plus the condition that selects it ('for the overall workspace state and next step, use airstrings_status'). This is textbook when-to-use / when-not-to-use routing.

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

airstrings_initA
Idempotent

Bind a directory to an AirStrings project; call this first in a repo with no .airstrings workspace, before any other airstrings_* tool. Writes .airstrings/config.json and stores the key in the workspace. Credentials: api_key, else AIRSTRINGS_ORG_API_KEY, AIRSTRINGS_API_KEY, else the stored login. With none it returns status "pending" and verification_uri_complete: show the user that URL, and once they approve call init again with the same arguments. With an org key it creates a project named after the folder (or name) unless project names an existing one. Returns the project, whether it was created, the active environment, all environments and sections. Use airstrings_login instead only to store an org login without binding a directory.

NameRequiredDescriptionDefault
dirNoDirectory to initialize (absolute or relative). Defaults to the current working directory.
orgNoOrganization ID (org_…) to bind to when the login has several. Uses the stored login for that org, or starts one.
nameNoName for a project created with an org key. Defaults to the folder or repository name. Ignored when project is set.
api_keyNoProject key (as_proj_…), org key (as_org_…) or legacy environment key. Optional: overrides the env vars and stored login.
projectNoExisting project ID (proj_…) or name to bind instead of creating one. Needs an org key or org login.
base_urlNoAPI base URL. Defaults to https://api.airstrings.com; only set it for self-hosted or test servers.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations establish the safety profile (readOnlyHint=false, idempotentHint=true, destructiveHint=false), and the description adds substance on top: it writes .airstrings/config.json, persists the key in the workspace, documents the full credential precedence chain (api_key > AIRSTRINGS_ORG_API_KEY > AIRSTRINGS_API_KEY > stored login), and describes the interactive pending/verification_uri_complete flow including the requirement to re-call with identical arguments. This is exactly the extra context the annotations cannot carry.

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?

Front-loaded with the action and the ordering constraint, then the credential chain, then the fallback flow, then the return summary. Dense but every clause carries information; it is a long paragraph rather than a tightly structured list, which costs it the top mark.

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?

No output schema exists, and the description compensates by summarizing the return payload (project, created flag, active environment, all environments and sections). Combined with the credentials, the re-invocation flow, and the sibling alternative, an agent has everything needed to call and interpret this tool.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds meaning the schema does not: the fallback order among credential sources, and the interaction rule that an org key creates a project named after the folder unless an existing project is named. It stops short of adding syntax or format detail for dir/base_url beyond the schema.

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 specific verb and resource ('Bind a directory to an AirStrings project') and immediately scopes it to the case it serves ('in a repo with no .airstrings workspace'). It also names the sibling it is not (airstrings_login), so an agent can distinguish it from every other airstrings_* tool without opening the schema.

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?

Gives an explicit ordering rule ('call this first ... before any other airstrings_* tool') and an explicit exclusion ('Use airstrings_login instead only to store an org login without binding a directory'). Both the when and the when-not are stated rather than inferred.

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

airstrings_loginA

Log in to an AirStrings organization and store an org key on this machine, without binding a directory. The first call returns status "pending" and verification_uri_complete: an organization owner approves that URL in the browser, then call login again to finish; if it is denied or expires, start over. Returns the organization once stored. Use it before airstrings_init when several directories will share one login; to set up a single repo, call airstrings_init directly (it logs in when needed).

NameRequiredDescriptionDefault
orgNoOrganization ID (org_…) the approval must be for; the approval is rejected for any other org. Optional.
base_urlNoAPI base URL. Defaults to https://api.airstrings.com; only set it for self-hosted or test servers.

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint=false, openWorldHint=true), the description discloses the full two-step protocol: first call returns status 'pending' with verification_uri_complete, an org owner approves in-browser, the agent must call login again, and denial/expiry means restarting. That async approval and retry behavior is exactly the context annotations cannot carry.

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?

Purpose is front-loaded, followed by the exact call sequence and then the usage rule, with no filler. The length is justified by a genuinely multi-step, stateful flow that would be unusable if abbreviated.

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 stateful auth tool with no output schema, the description covers the return states (pending, verification_uri_complete, organization once stored), the failure/retry path, and the persistence side effect. An agent has everything needed to drive both calls correctly.

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 coverage is 100% and the org parameter's constraint ('approval rejected for any other org') is already documented in the schema. The description adds persistence context ('store an org key on this machine') but no new meaning about org or base_url beyond what the schema states, so baseline 3 applies.

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 specific verb+resource ('Log in to an AirStrings organization and store an org key on this machine') and immediately distinguishes itself from siblings by adding 'without binding a directory'. An agent can separate it from airstrings_init without opening either schema.

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 routes the agent: 'Use it before airstrings_init when several directories will share one login; to set up a single repo, call airstrings_init directly (it logs in when needed).' This is a named alternative plus the condition that selects it, leaving nothing to inference.

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

airstrings_promote_previewA
Read-onlyIdempotent

Read-only diff of what promoting strings from one environment to another would change (added, updated, and extra keys per locale). Applies nothing — a human reviews the diff and applies the promotion at apply_url in the dashboard. Use it after publishing to staging to hand a production release to a human; agents cannot promote to a protected environment themselves.

NameRequiredDescriptionDefault
source_envNoEnvironment NAME to promote from, e.g. 'staging'. Defaults to the active environment.
target_envNoEnvironment NAME to promote to, e.g. 'production'. Defaults to the default environment. Must differ from source_env.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered; the description still adds real value by stating 'Applies nothing', that a human applies the change at apply_url in the dashboard, and that protected environments are out of reach for agents. It stops short of describing diff size limits or the full return shape.

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?

Three sentences, front-loaded with the read-only nature of the call, then the human-handoff mechanic, then the usage trigger. No filler and every sentence carries distinct information.

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

Completeness4/5

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

For a 2-optional-parameter tool with no output schema but strong annotations, the description covers what the diff contains and the out-of-band apply path. Minor gaps remain (no mention of pagination or diff size, and apply_url is referenced without saying it comes back in the response).

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 coverage is 100% and both parameters are fully documented in the schema, including defaults and the 'must differ from source_env' constraint. The description only reinforces the direction of the promotion, adding no syntax or format detail beyond the schema, so the baseline 3 applies.

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?

Names a specific operation (read-only diff preview of a cross-environment string promotion) and enumerates the result contents (added, updated, extra keys per locale). It is clearly distinguishable from the sibling airstrings_variant_promote, which acts on variants rather than strings.

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

Usage Guidelines4/5

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

Gives an explicit trigger ('Use it after publishing to staging to hand a production release to a human') and an explicit limitation ('agents cannot promote to a protected environment themselves'). It does not name a sibling alternative for the actual promotion, but the when-to-use condition is unambiguous.

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

airstrings_publishA
Destructive

Make the active environment's current server strings live: builds one bundle per locale, signs it (Ed25519) and uploads it to the CDN, where the SDKs pick it up on their next fetch. Publishes what is on the server, so run airstrings_push first for local edits. Each call creates a new bundle revision that replaces the live one; to undo, set the old values and publish again. Refused on a protected environment (production): publish to staging, then use airstrings_promote_preview and hand the apply_url to a human. Returns per-locale status and the published_at time.

NameRequiredDescriptionDefault
localesNoComma-separated locale codes to publish, e.g. 'en,it'. Omit to publish every locale of the project.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already flag destructive=true, openWorld=true and idempotent=false, and the description adds material context beyond them: every call creates a new bundle revision that replaces the live one, there is no automatic rollback (manual undo via republishing old values), production environments are refused, and signing occurs before CDN upload. This is exactly the behavioral detail an agent needs before mutating live traffic.

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?

Four tightly packed sentences, front-loaded with the what, then prerequisites, then the undo/rollback story, then the production restriction and return payload. No sentence is redundant; each carries a distinct operational fact.

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?

Covers what the tool does, prerequisites, irreversibility and rollback, environment restrictions, and even the return payload (per-locale status and published_at) despite there being no output schema. Nothing needed 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.

Parameters3/5

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

Schema description coverage is 100% for the single 'locales' parameter, so the schema already explains the comma-separated format and the omit-to-publish-all behavior. The description adds nothing about the parameter, which is acceptable but not value-adding; baseline 3 applies.

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 verb and resource ('Make the active environment's current server strings live') and enumerates the mechanism: builds per-locale bundles, Ed25519-signs them, uploads to the CDN. It also implicitly separates this from airstrings_push and airstrings_promote_preview by describing what publishing actually does.

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?

Explicit when-to-use ('run airstrings_push first for local edits'), how to undo ('set the old values and publish again'), and when this tool is the wrong choice ('Refused on a protected environment (production): publish to staging, then use airstrings_promote_preview and hand the apply_url to a human'). Names the alternative sibling and the condition that selects it.

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

airstrings_pullA
DestructiveIdempotent

Download the active environment's strings into the local workspace, overwriting the local CSVs with the server state; unpushed local edits in those files are lost, so run airstrings_push first if you want to keep them. Read-only on the server. Returns the string, section and file counts. Use it to start from the server's state; to inspect local files without touching them, use airstrings_strings_ls.

NameRequiredDescriptionDefault
sectionNoOnly overwrite this section's CSV. Omit to pull every section.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations flag destructiveHint=true and readOnlyHint=false, but the description goes further by naming exactly what is destroyed (unpushed local edits in the target CSVs) and clarifying that the operation is read-only on the server despite the destructive local effect. It also discloses the return payload (string, section, file counts), which the annotations do not.

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?

Front-loads the destructive warning before the routing guidance, and every sentence carries distinct load: mutation semantics, safety caveat, alternative tool, and return values. No filler.

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 single-parameter, destructive local-write tool with no output schema, the description covers the safety profile, the alternative tools, and the return value shape. Nothing an agent needs to call it safely is missing.

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% and the single 'section' parameter is fully documented in the schema ('Only overwrite this section's CSV. Omit to pull every section.'). The description adds nothing beyond that, so the baseline of 3 applies.

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 specific verb+resource (download the active environment's strings into the local workspace) and defines scope precisely (overwriting local CSVs with the server state). It is immediately distinguishable from airstrings_push (upload) and airstrings_strings_ls (inspect without touching).

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 names two alternatives and the conditions that select them: run airstrings_push first to preserve local edits, and use airstrings_strings_ls to inspect without modifying. Also frames the primary use case ('start from the server's state').

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

airstrings_pushA
DestructiveIdempotent

Upload the local workspace CSVs to the active environment: upserts every key and locale value, overwriting the server's values for those keys, and creates missing sections. Keys that exist only on the server are left alone (nothing is deleted). Refused on a protected environment: push to staging, then a human promotes. Returns upserted and error counts, the sections and any failed keys. Use after many airstrings_strings_set edits; for one key, strings_set with push=true is enough. Apps see the change only after airstrings_publish.

NameRequiredDescriptionDefault
sectionNoOnly push this section's CSV. Omit to push every section and the unsectioned strings.

TDQS

A4.7/5.0
Behavior5/5

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

Goes well beyond the annotations: it clarifies the destructiveHint by specifying server-only keys are left alone and nothing is deleted, discloses the protected-environment refusal, names the return payload (upserted and error counts, sections, failed keys), and notes changes are invisible until airstrings_publish. That is rich operational context an agent cannot get from the structured fields.

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?

Front-loaded with the core action, then layered with write semantics, environment constraint, return shape, and sibling routing. Every sentence carries distinct decision-relevant information; there is no filler.

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?

Despite having no output schema, the description enumerates the return fields, covers the destructive/mutation behavior, the protected-env refusal, and the publish dependency. An agent has everything needed to call it correctly and interpret results.

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 coverage is 100% and the single section parameter is fully documented in the schema itself ('Only push this section's CSV'). The description does not add syntax or format detail for the parameter beyond what the schema states, so the baseline of 3 applies.

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 specific verb (upload/upsert) and resource (local workspace CSVs to the active environment) and immediately defines the write semantics (overwrite server values, create missing sections). It distinguishes itself from siblings by name, contrasting with airstrings_strings_set, airstrings_publish, and airstrings_promote.

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?

Gives explicit when-to-use ('after many airstrings_strings_set edits') and when-not ('for one key, strings_set with push=true is enough'). It also states the alternative path for protected environments ('push to staging, then a human promotes'), leaving nothing to inference.

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

airstrings_sdk_configA
Read-onlyIdempotent

Public, non-secret SDK setup values for one environment — safe to show the user, commit and embed in app code; no API key or secret is returned. Returns organization, project and environment IDs, Ed25519 public key(s) (verification keys, not credentials), protection (protected/open) and ready-to-paste initializers for web, react_native, ios, android and go. Use it when wiring the AirStrings SDK into an app. Works with any API key of the project — a staging key returns production's config, so no production key is needed for SDK setup.

NameRequiredDescriptionDefault
envNoEnvironment NAME (e.g. 'staging') or ID (env_…). Defaults to the default (production) environment, which is what shipped apps use.

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, so the description is free to add what they cannot: that no API key or secret is returned, that the output is safe to show the user, commit, and embed, and that the cross-environment key behavior means no production key is needed. These are substantive behavioral traits an agent could not infer from the annotations.

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?

Two dense but front-loaded sentences; the safety/secret framing leads and the use case plus key-behavior note follow. It is efficient, though the long parenthetical enumerations of returned fields make it heavier than strictly necessary.

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?

There is no output schema, so the description carries the return-value burden and does so by listing the concrete fields and artifacts returned (IDs, public keys, protection, per-platform initializers). Combined with the safety and auth notes, an agent has everything needed to call it correctly.

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 single 'env' parameter is already fully documented, including its default to production. The description references 'one environment' but adds no syntax or resolution detail beyond the schema, so the baseline 3 applies.

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 states a specific verb+resource: returning public, non-secret SDK setup values for one environment, and it enumerates exactly what comes back (org/project/env IDs, Ed25519 public keys, protection state, initializers per platform). This distinguishes it from siblings such as airstrings_env_list or airstrings_init without needing to open their schemas.

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

Usage Guidelines4/5

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

It gives a clear use condition: 'Use it when wiring the AirStrings SDK into an app.' It also preempts a common auth question by explaining that any project API key works and a staging key returns production's config. It stops short of naming an explicit alternative tool or a when-not-to-use case, so it is clear context rather than full routing guidance.

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

airstrings_statusA
Read-onlyIdempotent

Workspace status, same as airstrings status: project, active environment, key scope (read/write), protection of every environment (protected/open), the keys stored in this workspace (masked; airstrings apikey revoke removes them) and the one next step for this state. Call it first when unsure what to do next or why a write was refused. For just the environment list, use airstrings_env_list.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds real context beyond them: keys are returned masked and are removed via the revoke command, and the tool emits a single next-step recommendation. It does not mention auth prerequisites or freshness of the status snapshot, which keeps it short of a 5.

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?

Front-loaded with purpose, then the returned fields, then usage. It is a dense single paragraph, but every clause maps to a concrete behavior or routing decision; only the key-masking aside borders on incidental detail.

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?

There is no output schema, so the description carries the burden of describing the return payload, and it does so field by field. For a zero-parameter, read-only diagnostic tool with routing guidance, an agent has everything needed to call it correctly.

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

Parameters4/5

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

The tool takes zero parameters, so the baseline is 4 and there is nothing for the description to disambiguate. It correctly implies a parameterless read-and-report call.

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 specific resource (workspace status) and enumerates exactly what it reports: project, active environment, key scope, per-environment protection, stored (masked) keys, and a suggested next step. It also explicitly distinguishes itself from the sibling airstrings_env_list.

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?

Gives explicit trigger conditions ('call it first when unsure what to do next or why a write was refused') and an explicit alternative for a narrower need ('for just the environment list, use airstrings_env_list'). Nothing is left to inference.

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

airstrings_strings_lsA
Read-onlyIdempotent

List the strings in the local workspace CSVs: key, section, format and the value per locale. Reads files only, never the API, so it shows unpushed edits; run airstrings_pull first to see what the server currently holds.

NameRequiredDescriptionDefault
sectionNoOnly list this section. Omit to list every section and the unsectioned strings.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful context beyond that: it reads local files rather than the API and therefore reflects unpushed edits, which materially affects how an agent interprets the results.

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?

Two tight sentences, zero waste. The behavioral distinction (local files, not API) is front-loaded before the routing advice, so the most important disambiguation comes first.

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 no output schema, the description compensates by naming the exact returned fields and the local vs. server data source. Combined with complete param coverage and rich annotations, an agent has everything needed to invoke and interpret the tool.

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 coverage is 100% and the single optional 'section' parameter is fully documented in the schema, including omit-to-list-all behavior. The description adds no further syntax or format detail, so the baseline 3 applies.

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 specific verb (List) and resource (strings in local workspace CSVs) and enumerates the returned fields (key, section, format, value per locale). It also draws the boundary against sibling tools by clarifying it reads files only, never the API, so an agent can distinguish it from server-side reads.

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 states the use context ('shows unpushed edits') and routes to the alternative: 'run airstrings_pull first to see what the server currently holds.' The condition selecting this tool vs. airstrings_pull is unambiguous.

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

airstrings_strings_rmA
DestructiveIdempotent

Remove a string key, or one locale of it, from the local workspace CSV. Local only unless push=true, which also deletes it in the active environment (refused on a protected environment). Deletion cannot be undone except by setting the string again. Returns what was removed and whether it was pushed. Apps keep the old value until the next airstrings_publish.

NameRequiredDescriptionDefault
keyYesThe string key to remove, e.g. 'onboarding.welcome'.
pushNoDefault false. When true, also delete it in the active environment.
localeNoRemove only this locale's value (e.g. 'it'). Omit to remove the whole key in every locale.
sectionNoSection the key lives in. Omit for unsectioned strings.

TDQS

A4.7/5.0
Behavior5/5

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

Goes well beyond the annotations by disclosing the local-vs-remote split, the protected-environment refusal, irreversibility, the return payload ('what was removed and whether it was pushed'), and the deferred effect on running apps until airstrings_publish. The annotations declare destructive/idempotent, and the description fills in the consequences and guardrails.

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?

Four tight sentences, front-loaded with the action and scope, followed by the push behavior, irreversibility warning, and return value. No filler or repetition.

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 no output schema, the description still covers the return value, the mutation's reversibility, the local/remote distinction, and the downstream publish dependency. An agent has everything needed to call this safely.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: the push flag's environment-level effect and its protected-env restriction, and that omitting locale removes the whole key. It does not restate syntax the schema already provides.

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 verb and resource with scope: 'Remove a string key, or one locale of it, from the local workspace CSV.' It also implicitly distinguishes itself from airstrings_strings_set by contrasting removal with re-setting, and from airstrings_push by describing the push=true flag.

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

Usage Guidelines4/5

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

Gives clear conditions: local-only by default, push=true also deletes in the active environment, refused on a protected environment, and deletion can only be undone by setting the string again. It stops short of naming the sibling tool (airstrings_strings_set) to use for restoration or airstrings_publish for propagation.

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

airstrings_strings_setA
DestructiveIdempotent

Add or update one string key in the local workspace CSV (.airstrings//.csv, or .airstrings/strings.csv without a section). Overwrites the given locales of that key and keeps its other locales. Local only unless push=true, which also upserts the key in the active environment; on a protected environment that push is refused and the local change is rolled back. Returns the key, section and whether it was pushed. Use this for a few keys; after editing many keys, run airstrings_push once instead. Apps see the change only after airstrings_publish.

NameRequiredDescriptionDefault
keyYesDot-separated string key, e.g. 'onboarding.welcome'. Created if it does not exist.
pushNoDefault false. When true, also upsert this key in the active environment right after the local write.
formatYes'text' for plain strings or 'icu' for ICU MessageFormat (plurals, select, {placeholders}). Applies to every locale of the key.
valuesYesJSON object string of locale code to text, e.g. {"en": "Hello", "it": "Ciao"}.
sectionNoSection (group of keys) to write to; created on push if missing. Omit for unsectioned strings.

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond the annotations: discloses merge semantics (overwrites given locales, keeps others), that writes are local unless push=true, that a protected environment refuses the push and rolls back the local change, and what is returned. The destructiveHint=true annotation is consistent with 'Overwrites'.

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?

Front-loaded with the core action, then behavior, then routing guidance, with no filler. The long middle sentence packs several clauses but each carries distinct operational information.

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 mutation tool with no output schema, the description covers write scope, push/publish lifecycle, rollback behavior, and the return shape, leaving no material gap for correct invocation.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds real value: the CSV path layout, the sectionless fallback file, and section creation on push. These clarify how section and push interact beyond the field-level text.

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 specific verb and resource ('Add or update one string key') and pins the exact target file, distinguishing it from siblings like airstrings_strings_rm and airstrings_push. An agent can select it without opening the schema.

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 scopes usage ('Use this for a few keys; after editing many keys, run airstrings_push once instead') and notes that apps see changes only after airstrings_publish, naming the relevant alternative tool.

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

airstrings_variant_promoteA
Destructive

End a running or stopped A/B experiment for one string key by making a variant's values the key's base string, overwriting the old base values, then republish that environment's bundles automatically. Cannot be undone except by setting the old values again. Refused on a protected environment (production): promote in a writable environment instead. Returns the experiment and per-locale publish results. Use it once a winner is clear; to end the test without changing the base string, use airstrings_variant_stop.

NameRequiredDescriptionDefault
keyYesThe string key whose experiment to promote.
variantYesName of the winning variant, as in airstrings_variant_status (not 'control').

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already flag destructiveHint=true and idempotentHint=false, but the description adds substantial context beyond them: the base string is overwritten, the action cannot be undone except by manually resetting old values, bundles are automatically republished, and it is refused on protected environments. This is exactly the operational consequence detail an agent needs before a destructive call.

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?

Five tight sentences, front-loaded with the primary effect, then irreversibility, then the environment restriction, then return value and routing. Every sentence carries distinct decision-relevant information with no filler.

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?

Despite having no output schema, the description states what is returned (the experiment and per-locale publish results). Combined with the irreversibility warning, protected-environment restriction, and sibling routing, an agent has everything needed to invoke this correctly.

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% and both parameters are documented there, including the note that 'variant' is not 'control'. The description reinforces the meaning of 'key' and 'variant' in prose but adds no syntax, format, or constraint beyond the schema, so the baseline 3 applies.

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?

Opening sentence names a specific verb (end/promote) and resource (A/B experiment for one string key) and states the precise effect: variant values become the base string, old values overwritten, bundles republished. It is clearly distinguishable from airstrings_variant_stop, which it explicitly contrasts.

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?

Explicit timing guidance ('use it once a winner is clear') plus a named alternative with the condition that selects it ('to end the test without changing the base string, use airstrings_variant_stop'). It also states when the tool will be refused (protected/production environment) and what to do instead.

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

airstrings_variant_setA
DestructiveIdempotent

Create or replace the A/B experiment for one text-format string key that already exists on the server in the active environment. Replaces the whole experiment as a new draft, so pass every variant each time; the key's base string is the implicit 'control' variant. Refused while the experiment is running (stop it first) and on a protected environment. Does not start it: call airstrings_variant_start, then airstrings_publish. Returns the stored experiment. To read the current one first, use airstrings_variant_status.

NameRequiredDescriptionDefault
keyYesServer-side string key (format text) the experiment belongs to, e.g. 'onboarding.welcome'.
variantsYesEach non-control variant name to an object of locale=value pairs, e.g. {"treatment": {"en": "Hi"}}. Never include 'control' — it is the base string. Give a value for every locale the base string has, or airstrings_variant_start will refuse.
allocationYesVariant name to integer traffic weight, including 'control', e.g. {"control": 50, "treatment": 50}. Weights are relative; give every variant in variants a weight.

TDQS

A4.9/5.0
Behavior5/5

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

Goes well beyond the annotations: it discloses that the whole experiment is replaced (destructive scope), that it is written as a new draft, that every variant must be resupplied because the key's base string is the implicit control, and the two preconditions that cause refusal. The idempotent-by-replacement semantics are also explained, complementing idempotentHint=true rather than merely restating it.

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?

Three dense sentences front-load the operation and replace semantics, then preconditions, then the follow-up tool chain. No sentence is filler and nothing needed for correct invocation is repeated.

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 destructive, nested-object mutation tool with no output schema, the definition supplies preconditions, destruction scope, follow-up calls, and even notes that it returns the stored experiment. An agent has everything required to call it safely without additional discovery.

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

Parameters4/5

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

Schema description coverage is 100%, so the baseline is 3 and the schema already documents key, variants (locale/value pairs, never 'control') and allocation weights. The description adds a genuine cross-parameter constraint — 'pass every variant each time' — that explains why the variants object must be complete on every call, which is not obvious from the schema alone.

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 specific verb pair and resource ('create or replace the A/B experiment') with tight scoping to a text-format string key in the active environment. It is clearly distinguishable from siblings like airstrings_strings_set and airstrings_variant_start without opening any schema.

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 routes the agent: use airstrings_variant_status to read first, airstrings_variant_start then airstrings_publish to activate, and airstrings_variant_stop before re-running. It also states two hard refusal conditions (experiment running, protected environment), which is exactly the when-not guidance the rubric rewards.

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

airstrings_variant_startA

Start a draft A/B experiment for one string key so its variants are served, split by allocation; takes effect in apps after the next airstrings_publish. Only a draft can start, and every variant must have a value for every locale of the base string. Refused on a protected environment (production): start it in a writable environment instead. Returns the updated experiment. Create the draft first with airstrings_variant_set.

NameRequiredDescriptionDefault
keyYesThe string key whose experiment to start.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations declare the write/idempotency profile (readOnlyHint=false, idempotentHint=false, destructiveHint=false), and the description goes well beyond them: it discloses the non-idempotent downstream effect (live after publish), the draft-only constraint, the validation requirement that every variant cover every locale, the environment refusal behavior, and the return value. Substantial added context.

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?

Four sentences, each carrying distinct load: purpose, timing, preconditions, environment behavior, and return value. Front-loaded with the action, no filler or repetition.

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?

Even without an output schema, the description states what is returned (the updated experiment) and covers the prerequisites, env restrictions and lifecycle effects an agent needs to invoke it correctly. Nothing material is missing for a one-parameter tool.

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% and there is only one parameter, so the schema already documents 'key'. The description adds only the framing 'one string key so its variants are served', which does not meaningfully extend the schema semantics. Baseline 3 applies.

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 specific verb (start) and resource (draft A/B experiment for one string key) and clearly distinguishes itself from siblings airstrings_variant_set, airstrings_variant_stop and airstrings_variant_promote. An agent can tell exactly which lifecycle operation this is without opening a schema.

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?

Explicit prerequisites (only a draft can start, invoked after airstrings_variant_set), a stated condition for failure (protected/production environments are refused), and a concrete alternative action (start it in a writable environment instead). Timing guidance ('takes effect after the next airstrings_publish') is also given.

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

airstrings_variant_statusA
Read-onlyIdempotent

Read the A/B experiment for one string key in the active environment: status (draft, running or stopped), allocation and each variant's values. Returns an error if the key has no experiment. Use it before airstrings_variant_set to keep existing variants, or to check state before start, stop or promote.

NameRequiredDescriptionDefault
keyYesThe string key whose experiment to read, e.g. 'onboarding.welcome'.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint, so the safety profile is covered. The description adds useful context beyond annotations: it describes the error condition when no experiment exists and enumerates the return fields, though it does not mention auth or rate limits.

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?

Two sentences, front-loaded with the core action and scope, followed by usage guidance. Every sentence earns its place with no redundancy.

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 simple read tool with one parameter, rich annotations, and no output schema, the description covers purpose, usage context, error behavior, and the shape of returned data. An agent has everything needed to call it correctly.

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 single 'key' parameter is fully documented in the schema. The description only restates the key scope ('one string key'), adding 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.

Purpose5/5

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

States a specific verb (Read) and resource (the A/B experiment for one string key in the active environment), and enumerates the returned fields (status, allocation, variant values). This clearly distinguishes it from sibling tools like airstrings_status and airstrings_variant_set.

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 names when to use it (before airstrings_variant_set to keep existing variants, or before start/stop/promote to check state) and names the relevant alternative tools. Nothing is left to inference.

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

airstrings_variant_stopA

Stop a running A/B experiment for one string key: every user gets the base string again after the next airstrings_publish. A stopped experiment cannot restart; airstrings_variant_set creates a new draft, and a stopped experiment can still be promoted. Refused on a protected environment. Returns the updated experiment. To keep a winning variant instead, use airstrings_variant_promote.

NameRequiredDescriptionDefault
keyYesThe string key whose experiment to stop.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only declare the generic mutation profile (readOnlyHint=false, destructiveHint=false, idempotentHint=false, openWorldHint=true). The description adds real behavioral context beyond them: the change is deferred until the next airstrings_publish, the stop is irreversible (cannot restart), it can still be promoted afterwards, and it is refused on protected environments.

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?

Four short sentences, zero filler, and the primary effect (what stopping does to users) is front-loaded ahead of the state-transition caveats and the alternative-tool routing.

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 no output schema, stating 'Returns the updated experiment' is useful, and the irreversible state transition plus the protected-environment refusal cover the failure modes an agent needs before invoking this.

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?

One parameter with 100% schema description coverage, so the schema already explains 'key'. The description only restates scope ('one string key') without adding format, validation or example detail, so the baseline 3 applies.

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?

Specific verb (stop) plus resource (a running A/B experiment) plus scope (one string key). It is clearly distinguishable from siblings airstrings_variant_set, airstrings_variant_promote and airstrings_variant_start, all of which are named or implied.

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?

Explicit routing guidance: use airstrings_variant_promote to keep a winning variant, airstrings_variant_set creates a new draft if you need one, and it is refused on protected environments. The when-not condition (protected env) and the alternatives are both stated.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 13 tool updatesv0.22.4
    • Changedairstrings_init6 fields changed
      • changedInput schema / properties / api_key / description
        Previous value: -"Project key (as_proj_…), org key (as_org_…) or legacy environment key. Optional."New value: +"Project key (as_proj_…), org key (as_org_…) or legacy environment key. Optional: overrides the env vars and stored login."
      • changedInput schema / properties / base_url / description
        Previous value: -"API base URL. Defaults to https://api.airstrings.com if omitted."New value: +"API base URL. Defaults to https://api.airstrings.com; only set it for self-hosted or test servers."
      • changedInput schema / properties / dir / description
        Previous value: -"Directory to initialize. Uses current working directory if omitted."New value: +"Directory to initialize (absolute or relative). Defaults to the current working directory."
      • changedInput schema / properties / name / description
        Previous value: -"Name for a project created with an org key. Defaults to the folder or repository name."New value: +"Name for a project created with an org key. Defaults to the folder or repository name. Ignored when project is set."
      • changedInput schema / properties / org / description
        Previous value: -"Organization ID to bind to. Uses the stored login for that org, or logs in. Optional."New value: +"Organization ID (org_…) to bind to when the login has several. Uses the stored login for that org, or starts one."
      • changedInput schema / properties / project / description
        Previous value: -"Existing project ID or name to bind instead of creating one (org key)."New value: +"Existing project ID (proj_…) or name to bind instead of creating one. Needs an org key or org login."
    • Changedairstrings_login2 fields changed
      • changedInput schema / properties / base_url / description
        Previous value: -"API base URL. Defaults to https://api.airstrings.com if omitted."New value: +"API base URL. Defaults to https://api.airstrings.com; only set it for self-hosted or test servers."
      • changedInput schema / properties / org / description
        Previous value: -"Organization ID the approval must be for. Optional."New value: +"Organization ID (org_…) the approval must be for; the approval is rejected for any other org. Optional."
    • Changedairstrings_promote_preview2 fields changed
      • changedInput schema / properties / source_env / description
        Previous value: -"Source environment NAME. Defaults to the active environment if omitted."New value: +"Environment NAME to promote from, e.g. 'staging'. Defaults to the active environment."
      • changedInput schema / properties / target_env / description
        Previous value: -"Target environment NAME. Defaults to the default environment if omitted."New value: +"Environment NAME to promote to, e.g. 'production'. Defaults to the default environment. Must differ from source_env."
    • Changedairstrings_publish1 field changed
      • changedInput schema / properties / locales / description
        Previous value: -"Comma-separated locales to publish. If omitted, publishes all."New value: +"Comma-separated locale codes to publish, e.g. 'en,it'. Omit to publish every locale of the project."
    • Changedairstrings_pull1 field changed
      • changedInput schema / properties / section / description
        Previous value: -"Pull only this section. If omitted, pulls all."New value: +"Only overwrite this section's CSV. Omit to pull every section."
    • Changedairstrings_push1 field changed
      • changedInput schema / properties / section / description
        Previous value: -"Push only this section. If omitted, pushes all."New value: +"Only push this section's CSV. Omit to push every section and the unsectioned strings."
    • Changedairstrings_sdk_config1 field changed
      • changedInput schema / properties / env / description
        Previous value: -"Environment NAME or ID. Defaults to the default (production) environment."New value: +"Environment NAME (e.g. 'staging') or ID (env_…). Defaults to the default (production) environment, which is what shipped apps use."
    • Changedairstrings_strings_ls1 field changed
      • changedInput schema / properties / section / description
        Previous value: -"Filter to a specific section. If omitted, lists all sections."New value: +"Only list this section. Omit to list every section and the unsectioned strings."
    • Changedairstrings_strings_rm4 fields changed
      • changedInput schema / properties / key / description
        Previous value: -"The string key to remove"New value: +"The string key to remove, e.g. 'onboarding.welcome'."
      • changedInput schema / properties / locale / description
        Previous value: -"Remove only this locale. If omitted, removes all locales for the key."New value: +"Remove only this locale's value (e.g. 'it'). Omit to remove the whole key in every locale."
      • changedInput schema / properties / push / description
        Previous value: -"Also mirror the removal to the API immediately."New value: +"Default false. When true, also delete it in the active environment."
      • changedInput schema / properties / section / description
        Previous value: -"Section to remove from. If omitted, removes from flat strings.csv"New value: +"Section the key lives in. Omit for unsectioned strings."
    • Changedairstrings_strings_set5 fields changed
      • changedInput schema / properties / format / description
        Previous value: -"String format: 'text' or 'icu'. Required."New value: +"'text' for plain strings or 'icu' for ICU MessageFormat (plurals, select, {placeholders}). Applies to every locale of the key."
      • changedInput schema / properties / key / description
        Previous value: -"The string key (e.g., 'onboarding.welcome')"New value: +"Dot-separated string key, e.g. 'onboarding.welcome'. Created if it does not exist."
      • changedInput schema / properties / push / description
        Previous value: -"Also push this key to the API immediately after the local write."New value: +"Default false. When true, also upsert this key in the active environment right after the local write."
      • changedInput schema / properties / section / description
        Previous value: -"Section name. If omitted, string goes to flat strings.csv"New value: +"Section (group of keys) to write to; created on push if missing. Omit for unsectioned strings."
      • changedInput schema / properties / values / description
        Previous value: -"JSON object of locale=value pairs, e.g. {\"en\": \"Hello\", \"it\": \"Ciao\"}"New value: +"JSON object string of locale code to text, e.g. {\"en\": \"Hello\", \"it\": \"Ciao\"}."
    • Changedairstrings_variant_promote1 field changed
      • changedInput schema / properties / variant / description
        Previous value: -"The variant name to promote to the winning value."New value: +"Name of the winning variant, as in airstrings_variant_status (not 'control')."
    • Changedairstrings_variant_set4 fields changed
      • changedInput schema / properties / allocation / description
        Previous value: -"Object mapping variant name to integer weight, e.g. {\"control\": 50, \"treatment\": 50}."New value: +"Variant name to integer traffic weight, including 'control', e.g. {\"control\": 50, \"treatment\": 50}. Weights are relative; give every variant in variants a weight."
      • changedInput schema / properties / key / description
        Previous value: -"The string key the experiment belongs to (e.g., 'onboarding.welcome')."New value: +"Server-side string key (format text) the experiment belongs to, e.g. 'onboarding.welcome'."
      • changedInput schema / properties / variants / description
        Previous value: -"Object mapping each non-control variant name to an object of locale=value pairs, e.g. {\"treatment\": {\"en\": \"Hi\"}}. Never include 'control' — it is the base string."New value: +"Each non-control variant name to an object of locale=value pairs, e.g. {\"treatment\": {\"en\": \"Hi\"}}. Never include 'control' — it is the base string. Give a value for every locale the base string has, or airstrings_variant_start will refuse."
      • changedInput schema / required
        Previous value: -[
        -  "key"
        -]New value: +[
        +  "key",
        +  "allocation",
        +  "variants"
        +]
    • Changedairstrings_variant_status1 field changed
      • changedInput schema / properties / key / description
        Previous value: -"The string key whose experiment to read."New value: +"The string key whose experiment to read, e.g. 'onboarding.welcome'."
  2. 17 tool updatesv0.1.0
    • First observedairstrings_env_list
    • First observedairstrings_init
    • First observedairstrings_login
    • First observedairstrings_promote_preview
    • First observedairstrings_publish
    • First observedairstrings_pull
    • First observedairstrings_push
    • First observedairstrings_sdk_config
    • First observedairstrings_status
    • First observedairstrings_strings_ls
    • First observedairstrings_strings_rm
    • First observedairstrings_strings_set
    • First observedairstrings_variant_promote
    • First observedairstrings_variant_set
    • First observedairstrings_variant_start
    • First observedairstrings_variant_status
    • First observedairstrings_variant_stop

TDQS

A4.4/5.0

Scored across 17 tools

Disambiguation5/5

Each tool has a distinct resource+action, and descriptions explicitly disambiguate near-neighbors ('for just the environment list, use airstrings_env_list'; 'to end the test without changing the base string, use airstrings_variant_stop'). The variant family (set/status/start/stop/promote) and the strings family (set/rm/ls vs push/pull/publish) are clearly separated despite similar names.

Naming Consistency4/5

All tools share the airstrings_ prefix with snake_case and a consistent resource-namespace scheme (variant_*, strings_*, env_list). Minor deviation: some tools are verb-only (login, push, pull, publish) while others are noun_verb (variant_set, strings_rm), but the grouping remains predictable.

Tool Count4/5

17 tools is slightly heavy but each earns its place across distinct domains (auth, workspace init/status, strings sync, publish, A/B variants, SDK config). The 5-tool variant lifecycle is the main driver of the count and is genuinely necessary for the experiment workflow.

Completeness4/5

Strong lifecycle coverage: auth, init, local/server string CRUD, push/pull/publish, environment listing, promotion preview, and full A/B variant lifecycle. Minor gaps: no environment create/delete or project management/teardown operations, but the core localization and release loop is complete.

Maintenance

ActivityMaintained
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers