AST MCPast-mcp
Reference

Configuration

Layered project, global, environment, and default configuration.

Files and precedence

The effective value of each field is selected in this order:

  1. environment override
  2. project ast-mcp.toml
  3. global ast-mcp.toml
  4. built-in default

The project file is the nearest ast-mcp.toml from the selected workspace root up to its Git boundary. The global file is ${XDG_CONFIG_HOME:-~/.config}/ast-mcp/ast-mcp.toml on POSIX and %APPDATA%\ast-mcp\ast-mcp.toml on Windows. Project selection prefers roots advertised by the MCP client, then AST_MCP_PROJECT_ROOT, legacy AST_MCP_ROOTS, and finally the process working directory.

Objects merge by field and arrays replace the lower-precedence array, except that global and project [[paths]] rules are both retained for policy evaluation. Workspace roots, path-rule anchors, dprint configuration, and relative executable paths resolve from the TOML file that declares them. Use an absolute embedding local_path to avoid process-working-directory ambiguity. Unknown sections or keys, unsupported versions, malformed TOML, and invalid values fail with the source path and dotted key instead of being ignored.

Schema

Version 2 is the long-term schema. Omitting version retains version 1 compatibility and emits deprecation diagnostics; ast-mcp never rewrites configuration automatically.

version = 2

[cli.output]
interactive = "human"
non_interactive = "json"

[workspace]
roots = [".", "../shared"]
worktrees = "include" # include | request | ignore

[files.read]
modes = ["ast", "text"]

[files.patch]
strategies = ["ast", "aider_block"]
aider_matchers = ["exact", "whitespace", "relative-indentation", "diff-match-patch"]

[formatting]
enabled = false
fallback = "preserve"

[telemetry]
enabled = true # default; set false to opt out

[safety]
filesystem = "restricted" # restricted | unrestricted
require_hash = true

[[paths]]
id = "workspace-source"
path = "."
policies = { read = "allow", write = "request" }
follow_symlinks = false
includes = ["**/*"]
excludes = [".git/**"]

[safety.hook]
enabled = true
allow_tools = []
block_tools = []

[http]
host = "127.0.0.1"
port = 3768
session_timeout_ms = 1800000
session_sweep_interval_ms = 60000

[mcp.configuration]
enabled = true
require_approval = true

[intelligence.storage.placement]
kind = "global" # global | local | parent | explicit

[intelligence.federation]
enabled = false

[intelligence.retrieval]
semantic = false

[intelligence.retrieval.embedding]
model_id = "onnx-community/granite-embedding-30m-english-ONNX"
revision = "a141ffafe5810d8ee499de14086b5259527ed6ff"
dimensions = 384
dtype = "q8"
pooling = "mean"
workers = 1

[intelligence.generation]
enabled = false

Complete version 2 reference

The tables list every accepted version 2 field. Defaults apply when all configuration layers omit a field. Required fields apply only when their containing entry or provider is configured. TOML cannot represent null; omit optional fields to use their defaults.

Workspace, output, and file methods

FieldDefaultAccepted values and behavior
versionv1 compatibility when omittedSet 2 for this schema.
cli.output.interactive"human"human, json, yaml, or toml.
cli.output.non_interactive"json"Same output formats for non-TTY stdout.
workspace.rootsSelected host rootsNonempty array of paths; relative paths resolve from the declaring TOML file.
workspace.worktrees"include"include, request, or ignore; see linked-worktree behavior below.
files.read.modes["ast", "text"]At most two entries; an empty list disables both explicit read methods.
files.patch.strategies["ast", "aider_block"]At most two entries; an empty list disables both patch strategies.
files.patch.sql.dialectOmittedOptional lowercase selector, 1–128 characters. A configured dialect alone does not request validation.
files.patch.sql.policy"advisory"advisory, required, or skip; required validation can block a patch.
files.patch.sql.variantOmittedOptional lowercase selector, 1–128 characters.
files.patch.sql.versionOmittedOptional version selector, 1–128 characters.
files.patch.aider_matchersAll four matchersexact, whitespace, relative-indentation, and diff-match-patch; at most four entries.

Safety and path rules

FieldDefaultAccepted values and behavior
safety.filesystem"restricted"restricted enforces file boundaries; unrestricted bypasses file path and symlink policies after required activation approval.
safety.require_hashtrueRequire mutation hashes; supplied hashes are checked even when false.
safety.hook.enabledtrueEnable the host routing hook. This is separate from server file authorization.
safety.hook.allow_tools[]Additional allowed tool names; at most 128.
safety.hook.block_tools[]Additional blocked tool names; at most 128. A name cannot appear in both lists, ignoring case.
paths[].idRequiredRule identifier, 1–128 characters. At most 256 rules per file.
paths[].pathRequiredExact file or directory anchor, 1–4096 characters. Use selectors for globs.
paths[].policies.readRequiredallow, request, or deny.
paths[].policies.writeRequiredallow, request, or deny.
paths[].policies.deleteInherits writeallow, request, or deny.
paths[].follow_symlinksfalseRequire authorization for both the link and its resolved target when true.
paths[].includes["**/*"]Up to 256 glob selectors, each 1–4096 characters.
paths[].excludes[]Up to 256 glob selectors; exclusions win within the rule.
mcp.configuration.enabledtrueEnable grouped configuration edits; tools remain registered when false.
mcp.configuration.require_approvaltrueRequire approval for ordinary grouped edits; changes to this configuration surface always require approval.

Hook names contain letters, digits, underscores, dots, colons, or hyphens, with 1–200 characters each. File access modes do not grant operating-system permissions. See Safety for activation and protected configuration files.

Formatting and dependency binaries

FieldDefaultAccepted values and behavior
formatting.enabledfalseMaster switch for formatting candidates.
formatting.fallback"preserve"preserve, reject, or dprint; applies to unmatched files and formatter failures.
formatting.dprint_configProject-root dprint.jsonNonempty path; relative paths resolve from the declaring file. No bundled configuration is installed.
formatting.formatters[].idRequiredIdentifier, 1–128 characters; at most 64 entries.
formatting.formatters[].commandRequiredExecutable name or path, 1–4096 characters; invoked without a shell.
formatting.formatters[].args[]At most 64 arguments, each at most 4096 characters; supports documented placeholders.
formatting.formatters[].enabledEnabled unless falsePer-entry switch, subordinate to the master switch.
formatting.formatters[].mode"stdout"stdout or staged in_place.
formatting.formatters[].extensions[]At most 64 extensions beginning with a dot, such as .ts.
formatting.formatters[].globs[]At most 64 selectors, each 1–4096 characters.
formatting.formatters[].timeout_ms30000Integer from 1 to 120000 milliseconds.
dependencies.dprint_binaryAutomatic installed-binary discoveryNonempty executable path override for dprint compatibility.

Each formatter requires at least one extension or glob. Selectors use OR matching; the first enabled matching entry runs. See Optional formatting for valid complete entries.

Intelligence storage, retrieval, and generation

FieldDefaultAccepted values and behavior
intelligence.storage.placement.kind"global"global, local, parent, or explicit.
intelligence.storage.placement.levelsRequired for parentInteger from 1 to 32; rejected for other placement kinds.
intelligence.storage.placement.pathRequired for explicitPath, 1–4096 characters; relative paths use the server working directory. Prefer an absolute path. Rejected for other kinds.
intelligence.federation.enabledfalseOpt into cross-repository federation.
intelligence.retrieval.semanticfalseOpt into embedding-based retrieval.
intelligence.retrieval.embedding.model_id"onnx-community/granite-embedding-30m-english-ONNX"Model identifier, 1–512 characters.
intelligence.retrieval.embedding.revision"a141ffafe5810d8ee499de14086b5259527ed6ff"Pinned model revision, 1–512 characters.
intelligence.retrieval.embedding.dimensions384Integer from 1 to 65536; must match model output.
intelligence.retrieval.embedding.dtype"q8"fp32, fp16, q8, or q4.
intelligence.retrieval.embedding.pooling"mean"mean or cls.
intelligence.retrieval.embedding.device"cpu"auto, cpu, gpu, wasm, or webgpu; backend support depends on platform.
intelligence.retrieval.embedding.workers1Integer from 1 to 32.
intelligence.retrieval.embedding.batch_size8Integer from 1 to 256.
intelligence.retrieval.embedding.max_queue256Integer from 1 to 100000.
intelligence.retrieval.embedding.local_pathNo overrideNonempty local model-artifact path; prefer an absolute path.
intelligence.generation.enabledfalseEnable optional model generation.
intelligence.generation.provider.kindNo providerhttp or mcp; each kind accepts only its own fields.
intelligence.generation.provider.modelRequired for either providerModel identifier, 1–512 characters.
intelligence.generation.provider.endpointRequired for httpValid URL, at most 4096 characters.
intelligence.generation.provider.api_key_envOmittedHTTP-only environment-variable name, 1–256 characters; keep the secret out of TOML.
intelligence.generation.provider.server_id"host"MCP-only server identifier, 1–512 characters.

Storage placement and generation providers are discriminated choices. Configure only the fields permitted for the selected kind:

version = 2

[intelligence.storage.placement]
kind = "parent"
levels = 1

[intelligence.generation]
enabled = true

[intelligence.generation.provider]
kind = "http"
endpoint = "https://models.example.com/v1/chat/completions"
model = "your-model"
api_key_env = "MODEL_API_KEY"

For MCP sampling, replace the provider table with kind = "mcp", model = "your-model", and optional server_id = "host". Enabling generation requires a provider. Omitting a provider keeps the resolved provider empty.

Transport and telemetry

FieldDefaultAccepted values and behavior
http.host"127.0.0.1"Nonempty bind address.
http.port3768Integer from 1 to 65535.
http.session_timeout_ms1800000Positive integer milliseconds for legacy HTTP session expiry.
http.session_sweep_interval_ms60000Positive integer milliseconds between legacy session sweeps.
telemetry.enabledtrueGlobal opt-out is a ceiling; project configuration can suppress but cannot re-enable it.

CLI output

Configure interactive and non-interactive stdout independently:

[cli.output]
interactive = "human"
non_interactive = "json"

Each value accepts human, json, yaml, or toml. Defaults are human output when stdout is a TTY and JSON otherwise. Global and project values merge by field. For example, a project can override non_interactive while retaining the global interactive setting. Version 1 and version 2 accept this section.

An explicit --output <format> or --output=<format> overrides configuration. It applies to configuration, installer, and skills commands. MCP and hook protocol commands reject the option. See command output formats for serialization behavior and examples.

Intelligence storage and models

All index state uses LanceDB. Global placement shares content-addressed artifacts across repositories and revisions. Local placement stores data under one repository. Parent placement requires levels; explicit placement requires path. Relative explicit storage paths use the server process working directory, so prefer an absolute path. Cross-repository federation remains disabled unless intelligence.federation.enabled = true.

Semantic retrieval is optional. The default pinned Granite embedding profile is small and CPU-oriented. Override the model, revision, dimensions, dtype, pooling, device, workers, queue, batch size, and local artifact path together. Generation is disabled by default and never blocks structural tools. MCP providers use the active host sampling capability; HTTP providers require an explicit endpoint, model, and optional environment-variable name for the API key.

Client roots and AST_MCP_PROJECT_ROOT provide the host baseline but are not authorization. Server-side top-level paths rules remain authoritative. A request spanning multiple advertised roots is accepted only when their effective safety, formatting, and dependency policies agree.

workspace.worktrees defaults to include. Linked git worktrees of each configured root join the filesystem baseline and inherit relative [[paths]] directory anchors. request keeps those remapped rules but requires approval for sibling worktree paths. ignore restores the previous behavior, denying sibling worktrees unless an explicit absolute rule covers them. The selected projectRoot stays on the checkout that bears ast-mcp.toml.

File methods

[files.read].modes filters the agent-selectable ast and text modes. [files.patch].strategies filters ast and aider_block; it does not auto-select a strategy. Version 2 enables every supported Aider matcher shown above by default. Repositories may narrow the list when they intentionally require stricter matching; ambiguity still fails closed. file_capabilities reports intrinsic and effective methods for each target.

Optional SQL candidate validation

[files.patch.sql] stores optional defaults for policy, dialect, version, and variant. Configuration alone does not invoke validation. A dialect/version/variant default only guides an explicit per-file request; policy = "required" opts in for each SQL patch. Default policy is advisory, so unsupported dialects or extensions do not grammar-block changes.

file_patch accepts the same optional sql object on each SQL file entry. This per-operation object can override a required default with policy: "skip" without changing configuration. Set SQL options during preview; the receipt binds them to the candidate and validation decision. Create a new preview to change the selection. A receipt commit intentionally carries no patch operations, strategy, or SQL options.

The current adapter checks PostgreSQL 18 core SQL (variant = "sql"). It does not parse procedural DO or function bodies, PL/pgSQL, extensions, catalog semantics, or execution. Unsupported SQL remains patchable with advisory policy or an explicit skip. The adapter limits each source to 512 KiB, all outstanding source data to 2 MiB, and total requests to eight including the active request. One worker runs at a time, up to seven requests wait. A five-second end-to-end deadline covers queueing, lazy initialization, parsing, and result handling. Bounded worker retirement keeps capacity reserved until termination is confirmed.

Generic run({ lang: "sql" }) searches structural SQL syntax without selecting a database dialect. It is separate from file_patch validation. New patch operations must select ast or aider_block explicitly; AST failure never triggers a text replacement automatically.

Telemetry

Telemetry defaults to enabled. Set enabled = false in global configuration to prevent SDK initialization and analytics network activity, or in project configuration to suppress events for that project. The global setting is a ceiling, so project configuration cannot re-enable telemetry when global telemetry is off. An omitted setting defaults to true; unresolved request policies and configuration errors suppress reporting. See the telemetry and error reporting guide for collected fields, exclusions, and privacy behavior.

Formatting

Formatting is disabled by default, and the master switch overrides individual formatter entries. When enabled, configure an already-installed external formatter; ast-mcp does not download one during file operations. Configure a command, argument array, mode, timeout, and extension or glob selectors. The first enabled matching formatter runs. In stdout mode, candidate content enters stdin and stdout becomes the formatted result. In in_place mode, ast-mcp stages the candidate beside the target, gives the formatter the staged path as {file}, reads its output, and removes the stage; the live target is never passed to the formatter. {source_file} names the logical target and {project_root} names the selected project. The default fallback = "preserve" keeps candidate content when a formatter fails or times out. fallback = "reject" stops the write, while fallback = "dprint" tries dprint. Staging cleanup failures always stop the write. See the optional formatting guide for dprint, Prettier, oxfmt, Biome, and other formatters.

Safety

Configure file access explicitly under [safety]:

version = 2

[safety]
filesystem = "restricted" # restricted | unrestricted
require_hash = true
ControlRestrictedUnrestricted
File path boundaries and [[paths]] policiesEnforcedBypassed after required activation approval
File symlink restrictionsEnforcedBypassed
Project activation approvalPath grants may require approvalRequired once per trusted session and effective safety configuration
Global modeHost configurationHost configuration
OS permissions and immutable revisionsEnforcedEnforced
Mutation hashes and atomic operationsRetainedRetained; require_hash still controls whether callers must supply hashes
Intelligence workspace roots, indexing, and storageUnchangedUnchanged

Unrestricted mode does not disable protected configuration-file approval or mutation capability checks. It does not disable deletion reference checks or configured formatting. Hook routing remains a separate host integration.

File access defaults to filesystem = "restricted". Restricted mode applies the host baseline, top-level [[paths]] rules, and symlink checks. Global configuration can select filesystem = "unrestricted" as a host setting. Project configuration requires session-scoped host approval tied to the canonical project and effective safety configuration. Modern stateless HTTP has no trusted caller session for host approval, so approval-required operations fail closed; explicit global permissions remain usable. Use stdio or a legacy HTTP session for approval flows. Unrestricted mode bypasses ast-mcp path policies, boundaries, and symlink restrictions for file operations while preserving OS permissions, hash guards, atomic operations, and immutable revision protection. It does not change intelligence workspace roots, indexing, or storage. See the filesystem access guide.

In restricted mode, each top-level [[paths]] rule anchors an exact file or directory; globs belong in includes and excludes, with exclusions winning. Policies are allow, request, or deny, and omitted delete inherits write.

Exact files outrank directories; otherwise the deepest anchor and longest include literal prefix wins. Equal specificity resolves deny before request before allow. Rename needs source delete and destination write; metadata uses write; hashing and intelligence use read. Both a symlink and its resolved target must be authorized, and the winning rule must enable follow_symlinks.

Project rules that broaden beyond the host baseline are reduced from allow to request. Once/session approvals bind connection, generation, rule, operation, and canonical path. Modern stateless HTTP has no trusted caller session for host approval, so approval-required operations fail closed. Persistent approvals create the narrowest user-global rule. Active configuration files are protected targets for file_write and file_patch and always require explicit approval for those mutations. Grouped config_core / config_paths edits follow [mcp.configuration] instead. Clients without elicitation fail closed with approval_required remediation.

require_hash = false makes expectedSha256 optional for guarded mutations, but supplied hashes are always checked. Hook allow/block settings affect only the host hook and never weaken server-side path, symlink, approval, or hash enforcement.

MCP configuration tools

[mcp.configuration] is enabled by default and requires host approval by default. Set enabled = false to fail closed on config_core and config_paths (the tools stay registered). Set require_approval = false to skip elicitation for ordinary grouped edits; changing [mcp.configuration] itself always requires approval, including turning the surface off or disabling approval. Direct file_write and file_patch of active configuration files remain protected targets.

Agents must use the grouped tools rather than rewriting ast-mcp.toml as a whole file:

  • config_core updates cli.output, workspace, telemetry, safety, files, formatting, intelligence, http, dependencies, and mcp.configuration. Batch every key that belongs to those sections in one call. It does not change [[paths]] or [[formatting.formatters]].
  • config_paths adds, updates, or removes [[paths]] rules in one operations batch. A single path rule can be fully specified in one add or update; partial policies updates merge with the existing rule. It does not change core sections.
  • target is project or global and defaults to project. Version 1 files must be migrated first.

A successful write validates version 2 schema, replaces the file atomically, invalidates the process-wide registry, and returns the new generation so later tool calls use the updated snapshot without restarting the MCP server. Elicitation-capable stdio and legacy HTTP hosts receive a standard request approval. Modern stateless HTTP has no trusted caller session for host approval, and hosts without elicitation also fail closed with approval_required.

Version 1 compatibility fields

Version 1 accepts the shared output, workspace, dependency, HTTP, telemetry, hook, and filesystem settings. Its formatter entries have no id, enabled, or mode; migration adds these fields. Version 2 introduces explicit path rules, file methods, formatting fallback, intelligence, and MCP configuration-tool controls.

These additional safety fields are accepted only in version 1:

FieldV1 defaultVersion 2 replacement
safety.allow_any_pathfalseExplicit catch-all path rule during migration; review it or select safety.filesystem deliberately.
safety.allow_external_rootsfalseExplicit external [[paths]] grants.
safety.allow_temp_directorytrueExplicit OS temporary-directory rule; version 2 grants no implicit temporary access.
safety.follow_symlinksfalsePer-rule paths[].follow_symlinks.

Version 2 rejects these legacy keys. See configuration migration before removing or translating them.

Environment compatibility

VariableConfiguration field
AST_MCP_EMBEDDING_MODELintelligence.retrieval.embedding.model_id
AST_MCP_ROOTSworkspace.roots
AST_MCP_ALLOW_ANY_PATHv1 deprecated compatibility
AST_MCP_ALLOW_EXTERNAL_ROOTSv1 deprecated compatibility
AST_MCP_ALLOW_TEMP_DIRECTORYv1 deprecated compatibility
AST_MCP_DPRINT_CONFIGformatting.dprint_config
DPRINT_BINARYdependencies.dprint_binary
AST_MCP_HTTP_HOSThttp.host
PORThttp.port
AST_MCP_SESSION_TIMEOUT_MShttp.session_timeout_ms
AST_MCP_SESSION_SWEEP_INTERVAL_MShttp.session_sweep_interval_ms

Boolean environment values accept 1, 0, true, or false. Invalid explicit overrides are errors.

Inspect and refresh

ast-mcp config validate
ast-mcp config show
ast-mcp config migrate          # preview
ast-mcp config migrate --check  # 0 current, 2 required, 1 invalid
ast-mcp config migrate --write  # atomic write plus .v1.bak

The config_status tool returns redacted effective configuration, including telemetry and mcp.configuration, provenance, generation, formatter order, and health. policy_check reports side-effect-free decisions. A process-wide registry watches global and discovered project configuration, debounces atomic reloads, and periodically reconciles fingerprints. Ordinary tool calls use immutable in-memory snapshots. Passive reloads preserve the generation when configuration identity is unchanged; changed identity advances it. Explicit invalidation advances the generation even when configuration is unchanged, revoking generation-bound approvals and workspace bindings. config_core and config_paths invalidate the registry after a successful write so later calls use the new snapshot. Invalid reloads mark the root unhealthy and fail closed while retaining the last valid snapshot only for diagnostics.

Local installer definitions omit environment fields and use project ast-mcp.toml. Global definitions remain project-neutral. AST_MCP_PROJECT_ROOT, AST_MCP_ROOTS, and --root remain deprecated for one release.

Extension policy

The strict top-level namespaces separate workspace selection, safety, formatting, dependency binaries, and transport settings so later hook, formatter, safety, and plugin features can extend their owning section without weakening validation. Keys are added only when runtime behavior exists; the loader does not accept misleading no-op placeholders.

On this page