MCP server

Any command, through one tool

list_commands and invoke_command reach the rest of Dynomatic, under the same permission ladder, minus what is deliberately withheld.

The typed tools are the front door. list_commands and invoke_command are the rest of the building.

list_commands returns every command the Dynomatic window itself calls, with what each one does to your data, the plan features it needs, the names of its arguments, and whether it can be run this way. That list is the whole surface, not a sample of it. invoke_command then runs any command the list marks runnable, under the ladder every other tool runs under.

The classes, and how many of each

Dynomatic registers 259 commands, and a person has classified every one of them by hand. A command with no row refuses, so a command added to the app starts out unreachable rather than open.

Class Count What it means
read 111 Reads DynamoDB or reads Dynomatic’s own data. Runs at every rung
localWrite 46 Writes Dynomatic’s own database and never reaches AWS. Needs Allow writes
remoteWrite 15 Reaches your AWS account. Needs Allow writes, and goes through the production check over the table it names
fromPartiqlStatement 1 dynamodb_execute_statement, whose statement decides whether it reads or writes
withheld 74 Somebody read it and decided an agent must not run it
notHeadless 11 Drives the window (9) or opens a native file dialog (2)
unclassified 1 Nobody has decided what it does yet, so it refuses

Of the 259, 166 run over the protocol. The rest are the 74 withheld, the 11 that drive the window or open a dialog, the 1 unclassified, and 7 more that the argument scan finds take a progress channel, so they are refused on their shape even where their class would have run them.

The 46 local writes split again inside the app. Rows a workspace owns, such as saved queries and table settings, are also refused while Dynomatic could not verify which profile owns the workspace at startup. Rows no workspace owns, such as an imported schema, are not.

Plan gates

Each row carries gates, the list of plan features the command needs on top of the MCP Server gate every call checks. Most rows list none or one. The two that create a table from an S3 export, dynamodb_import_table and dynamodb_describe_import, list both S3 transfers and table editing, ["exportToS3", "tableCrud"], and a call clears every gate in the list or is refused as Gated. The streamed import into an existing table, s3_import_run, lists S3 transfers alone, but it takes a progress channel, so it cannot run this way at all.

Naming the target

The profile is named, never described. An agent passes the profile name and Dynomatic looks up the real one, so a call cannot be pointed at an account by handing it that account’s details.

A table has to be a plain table name for the same reason. The classification store matches a bare name exactly, so an ARN would miss the row that says production, and the write would clear a check it should have failed. A malformed table name is refused at the boundary.

The argument spelling rule

Dynomatic renames arguments to camelCase on the wire, and that is the spelling list_commands reports. An agent that read the Rust signature instead would send request_id. Both name one parameter, so either is accepted and both become the declared spelling.

An argument the command does not declare is refused outright rather than ignored. Ignoring it was a real hole. A stray tableName on a command that takes none used to decide the environment verdict while the command read its real table out of a different argument, so the call could be judged on a development table and write to a production one.

Getting a command name wrong is answered with the nearest names that exist.

What is withheld, and why

The 74 withheld commands are refused on purpose. Each one is withheld for a reason that falls into one of these groups.

  • Credentials and identity. Storing, renaming, updating or deleting an AWS profile redefines which account a profile name reaches. Signing in or out of SSO, of an AWS CLI session, or of MFA, and running your external credential program, are all yours to do.
  • The keychain. Writing or deleting an AI API key, and moving a template value in or out of the OS keychain.
  • Environment classification. Classifying a profile, overriding a table’s environment, and every rule that drives the engine. A production verdict is what refuses an agent’s write, so an agent must not write it.
  • Cleanup rules. They decide which tables Dynomatic offers to delete.
  • The MCP server’s own settings. Enabling it, changing its permission, rotating its token and revealing its token. An agent must not widen its own permission or read its own bearer token.
  • Settings and model writes. settings_patch, models_upsert, models_delete and the two per-key settings commands write any row in the settings table, which is another way to turn on production writes.
  • File access. file_read, file_write and file_delete reach any path. An agent has its own filesystem tools and its own sandbox. local_export_discard is withheld for the same reason, since it removes files at any path the caller names, and so are ddb_file_open and ddb_file_import_run, which read a DynamoDB JSON file at any path, together with the four commands that stage a file dropped onto the window.
  • Raw script and schema execution. scripting_execute runs JavaScript against any table with none of the per-call guards run_script installs. schema_import_extract evaluates source files with none of the path checks import_schema applies.
  • Your Dynomatic account. Signing in, signing out, cancelling a login and starting a trial.
  • Installing software. Checking for, downloading and installing an update.
  • Sample mode. Entering it, exiting it, clearing its data and stopping its sidecar all switch which profile every later call targets.
  • The rest. feedback_submit sends a message to Ajar Software as you. experimental_gates_set_toggle turns on the app’s own experiments. reveal_in_folder opens your file manager. Two embedding backfill commands name their table only by a registry key, which no lens resolves.

The first group is the important one. Changing which account a profile name reaches would change where every later call lands. The MCP group is the other. An agent that could edit these settings could grant itself the writes you withheld.

The commands that cannot run here

Three of the NotHeadless reasons are about shape rather than permission, and each names a different fix. Permissions and refusals lists all six.

  • NeedsWebview drives the Dynomatic window or your clipboard through its app handle. list_commands names which commands these are.
  • NeedsChannel streams progress into the window and has nowhere to send it over the protocol. Background exports and the streamed S3 import are these, and export_start, export_status and export_cancel exist for that reason. Exports and show in the app covers them.
  • NeedsDialog opens a native file dialog and waits for a person to answer it.

Answers that are too large

An answer over 4 MB is trimmed the way every other answer is, and says so. One with nothing left to trim is refused with its size rather than silently cut.

Last updated on