# Approve MCP tools

> Choose which MCP tools a project approves and verify the next recorded call.

Source: https://docs.synkro.sh/guides/mcp-approvals

MCP approvals name a server and tool that your project permits. An approval
removes that tool's unapproved-MCP notice or refusal. Other Rules, Controls and
[one-action consent](/guides/consent) still apply, including checks on arguments.

For an unapproved tool, **observe** mode records a flag and shows a notice while
allowing the call; **enforce** mode blocks it. A project denial removes approval
and applies that same gate. It does not turn observe mode into enforce mode.

## Approve the scope you intend

Ask your agent to identify the exact server, tool, project and reason for access.
Review that scope before approving it. Run these commands in the project:

```sh
synkro approve mcp github read_issue
synkro approvals mcp github read_issue
synkro lock
```

Use the server and tool names from the refused action. Omitting the tool approves
**every tool on that server**, so do this only when you intend that broader scope:

```sh
synkro approve mcp linear-server
```

All approval commands accept `--path DIR` to select a project. For example:

```sh
synkro approve mcp github read_issue --path /path/to/project
```

An agent must wait for your approval before changing declarations. A refusal
under a limited agent connection does not authorize the agent to substitute
your credentials or approve more tools.

## Project decisions and package defaults

The default edit target is the project's `synkro.toml`. This section approves one
tool; omitted `approved` means `true`:

```toml
[[approvals.mcp]]
server = "github"
tool = "read_issue"
```

A package can supply approve-only defaults in its `synkro-package.toml`:

```toml
[[approvals.mcp]]
server = "github"
tool = "*"
```

The project's decisions take precedence. For each call, resolution is:

1. Project exact server/tool entry.
2. Project server wildcard (`tool = "*"`).
3. An approval from any declared package.
4. Unapproved, when no declaration applies and the defaults are available.

Only `synkro.toml` may deny. This project entry removes approval for `delete_issue`,
even if a package approves all GitHub tools:

```toml
[[approvals.mcp]]
server = "github"
tool = "delete_issue"
approved = false
```

To edit a declared local package named `team`, select its alias explicitly:

```sh
synkro approve mcp github read_issue --package team
synkro approvals mcp --package team
```

These defaults affect projects that use that package. Git dependencies are
read-only here: change their source repository, then update the project's
dependency. Listing reads the locked revision without fetching.

## List and revoke

```sh
synkro approvals mcp
synkro approvals mcp github
synkro approvals mcp github read_issue
synkro revoke mcp github read_issue
synkro lock
```

Listing names the project or package that supplies each decision: `(synkro.toml)`
or `(package ALIAS default)`. A project entry is labelled an `override` only when
it shadows a package default. An exact-tool query also finds a covering server
wildcard. Project entries take precedence even when you use `--package` to narrow
the listed defaults.

Project revocation removes the declaration when nothing else approves the scope.
If a package default or project wildcard still approves it, revocation writes
`approved = false`. If package defaults are unreadable, it writes an explicit
project denial and reports the missing defaults.

With `--package`, revocation removes a package default. Omitting the tool removes
all approvals for that server in the selected package. To remove one tool from
a package's whole-server approval, remove the wildcard and approve the desired
tools individually; packages cannot deny. Another package can still approve
the same tool, so check the effective listing afterward.

## Existing package approval files

A package with an empty or absent `[[approvals.mcp]]` section uses its
`approvals.toml` fallback (`schema_version = 1`, `[[mcp]]` entries). A nonempty
manifest section wins; commands report that the fallback file is ignored.

The first package edit moves active fallback entries into the manifest and
removes the file, keeping private backups. An edit that would remove the last
manifest entry while an ignored fallback file exists is refused: remove that
file first so it cannot silently become active again.

Listing reports unavailable or invalid packages. Project approvals and denials
still apply, as do approvals from valid packages. Only coordinates decided by
neither fail open with a recorded package failure: an unreadable package might
have approved them. Independent Rules and Controls still apply.

## Verify the next call

Upgrade both CLI and service before declaring manifest approvals. The normal
hook publication carries the change; `synkro lock` records its digest. Neither
a successful listing nor a lock update proves the running service loaded it.

After your agent makes the intended native MCP call, inspect its recorded verdict:

```sh
synkro events --type verdict --limit 5 --details
```

Match the server, tool and action to that call. Check the reason and matched
Rules or Controls if it is still refused. An approved tool can still need
one-action consent or violate a Rule; widening its MCP approval will not fix that.
See [Events](/guides/events) for selecting a specific recorded action.
