Working with an AI agent
Once the MCP adapter is connected, the agent is one more operator of the server, one that works through an automation token and asks before it changes anything. This page is about the conversation: how it goes, what to ask, what the agent refuses, and how to keep it safe. The examples show Claude Desktop with an Admin token for a virtual site called main; everything applies equally to Claude Code, Cursor, Visual Studio Code or any other client, and to a SuperAdmin token.
Giving the agent its bearings
The adapter already instructs the agent: it manages the server and never touches files, it prefers update_* over replace_*, every write is a preview followed by a confirmation, it reads syncplify://schema/<Object> before building an object, and it pages long lists with limit and offset. What only you can add is the context: which server this is, how careful to be, and what the names mean. Put it where your client keeps standing instructions (the project instructions of Claude Desktop, CLAUDE.md for Claude Code, the rules file of Cursor), for example:
You manage the Syncplify Server! virtual site "main" through the syncplify MCP server.
This is the production server. Before any change, show me the preview the tool returned
(the diff and the dependents) and wait for my explicit yes; never confirm on your own,
and change one object per confirmation. A user's ID is their sign in name. When you are
unsure how a field works, read syncplify://schema/<Object> or the manual index at
syncplify://manual before asking me.How a conversation goes
A question
How many users does this site have, how many are disabled, and which disabled ones still have a public key on file?
The agent calls list_users, perhaps in pages, and receives every answer in the same shape: the HTTP status, the body, and the headers that matter, such as the total of a list:
{
"status": 200,
"total": 143,
"body": [
{ "_id": "alice", "status": "Enabled", "email": "alice@example.com", "sshPubKeys": [ "..." ], "...": "..." },
{ "_id": "bob", "status": "Disabled", "sshPubKeys": [ "..." ], "...": "..." }
]
}It then answers in words: one hundred forty three users, eleven disabled, three of them with a key. A question changes nothing, whatever the token may do; a read only token is enough for everything in this section.
A change
Disable bob's account. He left the company today.
The agent calls update_user with the ID and the fields to change ({"status": "Disabled"}) and, because it did not pass confirm, the adapter answers with a preview instead of doing it. The preview is the server's own dry run: the write was validated and the difference computed, and nothing was stored.
{
"status": "confirmationRequired",
"tool": "update_user",
"preview": {
"valid": true,
"action": "update",
"objectType": "user",
"objectId": "bob",
"errors": [],
"diff": {
"added": {},
"changed": { "status": { "from": "Enabled", "to": "Disabled" } },
"removed": {}
},
"dependents": [],
"message": "Dry run completed; nothing was persisted",
"messageCode": "webrest.dryRun.completed"
},
"etag": "W/\"3f2a9c...\"",
"confirmToken": "v1.1763633527.Vy8iM2...",
"expiresAt": "2026-11-20T10:22:07Z",
"next": "Review the preview with the user, then call update_user again with the same arguments plus confirm set to confirmToken. The token is valid for ten minutes and only for these exact arguments."
}The agent reports: "This would change bob's status from Enabled to Disabled and nothing else. Shall I apply it?" You read the diff (only what you asked for), the dependents (nothing else is touched) and say yes. The agent calls update_user again with the same arguments plus the confirmation, and the adapter executes the write with If-Match set to the ETag of the preview and an idempotency key:
{ "status": 200, "body": { "_id": "bob", "status": "Disabled", "...": "..." }, "etag": "W/\"9c1d04...\"" }On the server the change is recorded as made by the token, with its owner, exactly like a change made in the console. If someone changed bob between the preview and your yes, the server answers 412 and the agent is told to preview again; nothing is overwritten.
A change the server would refuse
Create a user called "new user" with a password of "a".
The dry run says valid: false and lists the errors with the field and the reason code of each: an ID with a space, a password below the policy. The adapter returns the refusal and no confirmation token, so there is nothing the agent could confirm. It fixes the arguments (or asks you) and previews again.
A destructive change
Delete the VFS called legacy-share.
delete_vfs is marked destructive in the agent's tool list. Its preview carries, in dependents, the users whose home or virtual folders reference that VFS. A well instructed agent stops there and shows you the list; the standing instruction above is what makes it stop. Decide with that list in front of you, and remember that a confirmation is bound to the exact arguments of the preview: the agent cannot confirm something other than what you saw.
Something only a service token may do
Kick mallory's session.
list_sessions finds the session (a read, Dashboard permission). Terminating it is a service action: terminate_session is offered only when the token has the serviceActions scope. With it, the tool runs through the same two steps; because that route has no server side dry run, the preview shows the request that would be sent and asks you to review it. Without the scope the tool is not in the list at all, and the agent tells you it cannot do that.
On the SuperAdmin plane
Is the cluster healthy, and is there an update?
With an sa token the agent calls get_cluster_status, get_update_status and, if you ask it to look right now, check_for_update, which runs at once (it persists nothing but the record of what the signed channel offers). Installing the update is apply_update: a service action, previewed and confirmed, after which the server runs its own update sequence, one node at a time in a cluster.
Prompts that work well
Questions and reviews, which need a read only token:
- "Which users can sign in with a password but are not forced to use a second factor?"
- "Which users have more than one public key on file?"
- "Which VFS does nobody reference?" (
report_vfs_users) and "Which users reference the VFS archive?" (report_user_vfs). - "Show the current Shield bans and the strikes behind them, grouped by network."
- "Compare the site's security settings with what the server suggests and list the differences." (
get_site_confignext tosuggest_security_config.) - "Who is connected right now, from which addresses, over which protocols?"
- "Which log events are about certificates, and what does reason code
webrest.token.readOnlymean?" (Thesyncplify://eventsandsyncplify://reason-codesresources.)
Changes, which need an Edit permission and go through the preview:
- "Disable bob."
- "Create a read only account for the auditor, public key only, with access to the VFS reports." (The agent reads
syncplify://schema/Userfirst.) - "Add a webhook that sends every failed sign in to
https://hooks.example.com/syncplify." (The agent finds the event block in the catalog.) - "Move alice's home to the VFS projects and keep her permissions."
What the agent cannot do, by design
- Files. It never lists folders, reads, moves or deletes files. An agent that must move files signs in over SFTP with a user account, like any other client.
- Operators and credentials. Nothing about Admin or SuperAdmin accounts, passwords, second factors, passkeys, operator SSO providers, backup and restore, or tokens. The server refuses those routes to every token and the adapter does not offer them.
- More than its token. A tool that is not offered is a right the token lacks; a 403 means the same and makes the tool disappear from the list.
- Confirming for you, with one honest caveat. The adapter cannot see whether the agent showed you the preview; it only knows that the tool was called twice. The instruction to wait for your yes is part of the agent's instructions, and the agent's model is what honours it. The guard that needs no trust at all is the read only token: give an agent write rights only once you have watched it ask.
- Bulk changes in one go. One confirmation changes one object. An agent asked to disable forty accounts previews and confirms forty times, which is exactly right for forty decisions and wrong for a migration; for the latter use a script against the REST API with safe writes.
Keeping it safe
- Start read only; add Edit permissions one at a time, when the agent has shown it asks first.
- One token per agent and per machine, named after both, with an expiry and, where possible, an address allow list. Revoke it the moment the machine is lost or the agent misbehaves; every node of a cluster refuses it within seconds.
- Watch what it does. Every change carries
actorKindtokenin the audit trail. A webhook subscribed to the 7000 block (object changes) tells a chat channel about every change an agent makes, as it happens. - Keep the token out of the conversation. The agent never needs it; it is in the environment of the adapter. If it ever appears in a chat, revoke it.
