Skip to main content

Settings over MCP

Let a coding agent read and change Tale settings through the MCP endpoint, within the role of the person whose API key it uses.

7 min read

A coding agent connected to the MCP endpoint can read your organization's settings, plan a change and make it with three tools: get_settings, plan_settings and apply_settings. It acts with the role of the person whose API key it uses. It can change what that person could change in the app, through the same checks, and the audit log records every change as that person's, made through MCP.

What an agent can change

Tale reads and writes each kind of setting with its own code and the checks the app applies, so the role rules are the same as in the app.

KindWhat it holdsChangesWho can change it
providerAn AI provider your organization defined: its endpoint, API format and model catalog. The providers Tale ships are not settings.Set, delete; read its model catalog again (refresh-catalogs)Owners, admins and developers
provider-credentialA credential that reads its key from an environment variable of the deployment. Credentials with a key or a subscription are listed without their secret and can be removed.Set, deleteOwners, admins and developers
governanceOne organization policy, named by its key: models and model access, budgets and limits, sign-in and session security, guardrails, sandbox quotas.SetOwners and admins
knowledge-embeddingThe embedding model of the organization's knowledge base, with its similarity floor and serving limits.SetOwners and admins
brandingThe accent color and the file names of the logo and the favicons.SetOwners and admins
project-instructionsA project's standing instructions.SetWhoever can edit the project
agent-instructionsA project agent's instructions.SetWhoever can edit the project
agent-toolsThe tools a project agent may use.SetWhoever can edit the project
agent-modelThe agent runtime (harness), model and provider a project agent runs on. A change applies to the runs it starts next.SetWhoever can edit the project
task-instructionsA task's description.SetWhoever can change the task
task-review-contextWhether a task's work goes to an independent review by another project agent, and which agent reviews it. Once set, the reviewer stays the same.SetWhoever can edit the project
deploymentThe deployment's own settings, shared by every organization on it, such as the sandbox runtime.SetAn owner or admin of any organization on the deployment reads them, with their own API key; only the addresses on the deployment's editor allowlist change them. A key made for another member, a team, a project or the organization reaches none of them

A resource has an id within its kind: a provider by its name, a credential as <provider>/<name> with the name URI-encoded, a policy by its key such as password_policy, a project by its id, an agent as <projectId>/<agentId> and a task as <projectId>/<taskId>. The embedding model, the branding and the deployment settings have no id. get_settings lists project and agent settings page by page over the projects you can read; it reads a task's description and its review context only by the task's id.

Some changes stay in Tale:

  • Every secret, such as a provider's API key, a subscription or the moderation provider's key, is entered by a person in Tale.
  • The retention policy and the data subject request policy change through their own staged workflows.
  • Branding images are uploaded in Tale. A file name an agent sets must name an image already uploaded.
  • Over MCP, the embedding model itself changes only while the knowledge base holds no document and no website, so that vectors from two models never meet in one search. Its similarity floor and serving limits change at any time; with documents indexed, a person changes the model in Tale.
  • A project's standard agent follows the standard_agent policy, which the governance kind changes; its own instructions, tools and model are not settings.
  • No kind covers members, teams, connectors, skills, competences, legal holds, the audit log, metrics or personal settings. get_settings without arguments shows what each kind covers.

Make a change

  1. Call get_settings without arguments. It lists every kind, whether this deployment serves it, and whether your role may read and change it.
  2. Read what you want to change with get_settings and kinds (and ids). Each resource comes with its key, its config and its hash.
  3. Plan the change with plan_settings. A set replaces the whole resource with its config, so send every field it should keep, as you read it. The plan names each change's action, its diff, its effects and its risk, or the refusal that stops it. Nothing is written.
  4. Show the plan to the person and wait for their decision. Put the effects and the risk first.
  5. Apply the same changes with apply_settings. expected maps each changed resource's key to the hash you read, or to null for one you create.

These are the arguments of a plan that turns on password rotation:

json
{
  "changes": [
    {
      "kind": "governance",
      "id": "password_policy",
      "op": "set",
      "config": {
        "minLength": 12,
        "requireUpper": true,
        "requireLower": true,
        "requireDigit": true,
        "requireSpecial": true,
        "rotationDays": 90
      }
    }
  ]
}

The plan answers the change with its effect on members, because rotation expires passwords that are already set. The hash is shortened here:

json
{
  "ok": true,
  "changes": [
    {
      "kind": "governance",
      "id": "password_policy",
      "key": "governance/password_policy",
      "op": "set",
      "action": "update",
      "currentHash": "5c1f…",
      "diff": [{ "path": "/rotationDays", "before": 0, "after": 90 }],
      "effects": ["may-lock-out-members"],
      "risk": "critical"
    }
  ]
}

To apply it, send the same changes with "expected": { "governance/password_policy": "5c1f…" }, using the full hash. Before anything is written, every change is planned again against what is stored now. If one is refused, or a resource changed since you read it, nothing is applied. Otherwise the changes run in a fixed order across kinds, so that what a resource refers to exists first. The first failure stops the rest, and the answer lists what was applied, what failed and what was skipped. A change that already landed is not undone.

apply_settings asks the person before every call and uses a budget of its own.

Read a plan's effects

A plan's risk is the highest of its kind's base risk and its effects' risk. These are the effects the kinds served today can name:

EffectRiskWhen a plan names it
may-lock-out-memberscriticalThe sign-in lockout is on after the change, password rotation starts or gets shorter, or two-factor authentication becomes stricter
signs-out-memberscriticalThe idle timeout is turned on or gets shorter
removes-human-approvalcriticalAn approval rule or a review requirement no longer asks a person
changes-serving-accounthighA provider's endpoint changes, or another credential serves its requests
breaks-dependentshighThe provider's active default credential is removed and nothing replaces it
requires-empty-corpuscriticalThe embedding model changes, which needs an empty knowledge base
restart-requiredcriticalThe deployment's sandbox runtime changes
reaches-vendorhighA provider's model catalog is read again with your organization's key

The settings reference that get_docs returns for the topic settings (also tale://docs/settings) lists the whole vocabulary, every kind's fields and every governance policy.

Secrets

No secret goes into or comes out of a settings call. A stored secret reads as {"masked": true, "preview": "…"}, and so does anything else in a stored setting that Tale never shows in a run's record: a key someone pasted into a policy or an instruction, a key typed into a header whose name says it holds one, or a password in an address. A header that only names the stored secret, such as Bearer {{secret}}, reads as written. A key inside a longer text masks the whole text. Send a masked value back unchanged to keep what is stored there, or replace the whole value. A change that carries a secret is refused with SECRET_ARGUMENT_REFUSED, which names where the secret was found and never its value. A person enters a new secret in Tale.

When a change is refused

A refusal is data with an error, a code, a hint and sometimes data, never a failed connection. These are the codes an agent meets most often:

CodeWhat it means
SETTINGS_STALEThe resource changed since it was read. Read it again, plan against what is stored now, and apply with data.currentHash.
SETTINGS_INVALIDThe config is not the kind's. data.issues names every problem by its place in the config, including a field the setting does not have and text Tale cannot store, such as a NUL character.
SECRET_ARGUMENT_REFUSEDThe change carries a secret. data.places says where.
SETTINGS_TALE_ONLYThe change is made in Tale alone, for example a credential with a key.
FORBIDDEN, ORG_FORBIDDEN, FORBIDDEN_DEVELOPER_SETTINGSThe person's role cannot make this change in Tale either. Retrying does not help.
EMBEDDING_CORPUS_NOT_EMPTYThe embedding model changes only while the knowledge base is empty. data names how many documents and websites it holds.
BRANDING_IMAGE_UNKNOWNA branding file name names no image uploaded to the organization.
PROVIDER_IN_USE, CREDENTIAL_IN_USECredentials still name the provider, or the embedding model uses the credential. Change those first.

The settings reference lists every code. The MCP endpoint page describes the tools' arguments and answers.