Connect AI Agents (MCP)#
The beauty of the Babel fish was that it made everyone understandable without teaching anyone a new language. MCP (Model Context Protocol) does the same job: an application like Claude Desktop can ask your VeriTeknik account a question, look at your servers, or open a support ticket, without ever learning VeriTeknik.
You put the fish in your ear, and you take it out again. You make the connection, you draw its boundaries, and you revoke it with one click.
What is it good for?#
Once the connection exists, you can say things like this in Claude Desktop:
- "List my VeriTeknik servers - which ones are running?"
- "What were the disk and memory figures for web-01?"
- "Do I have any unpaid invoices?"
- "When does
yourcompany.comexpire, and what are its DNS records?" - "Open a support ticket for this error and summarise the logs in it."
Claude carries the question to VeriTeknik, reads the answer and explains it back to you. No second panel, no second password, no copy-paste round trip in between.
What exactly is MCP?
A common protocol applications use to talk to a service. On our side it lives at https://veriteknik.com/api/mcp; Claude Desktop, claude.ai and other MCP clients that run inside a browser can all connect to it. So this is not a "Claude Desktop integration" but a standard door - Claude Desktop just happens to be the guest knocking on it most often right now.
Before You Start#
Three things need to be true:
- MCP access must be on for your company. The feature is enabled per company and is off by default. A company owner or admin turns on Enable MCP access on the Settings > Agent Connections > AI Agent Access (MCP) card. Every active member can see the card; only an owner or an admin can change the switch, and the card says so with a read-only hint.
- Your account must belong to a company. A connection is always made on behalf of one company; if your account is not linked to one yet, the consent screen will politely turn you away.
- Two-factor authentication - optional, but strongly recommended. With 2FA on, every connection that goes through the consent page - including the first one you make - asks you for a fresh code, and so do widening a connection and approving an irreversible action. Once verified, you are not asked again for two hours.
Turning the switch off does not delete anything
Turning Enable MCP access off blocks every connected app immediately. Turning it back on restores access without a new approval. It is a fuse, not a demolition button.
Setup: clients#
The connection URL is the same for every client, and the Connection details block on the Settings > Agent Connections > AI Agent Access (MCP) card hands it to you:
https://veriteknik.com/api/mcp
Most clients that read their configuration from a file accept this shape (Claude Code insists on the type line, Cursor and the others ignore it):
{
"mcpServers": {
"veriteknik": {
"type": "http",
"url": "https://veriteknik.com/api/mcp"
}
}
}
Whichever client you use, the order is the same: you declare the URL, your first tool call opens the VeriTeknik consent page in the browser (company, permission groups, monthly cap, 90 days), and once you approve it the same connection is reused until it expires or you revoke it.
The client must support OAuth
VeriTeknik issues no long-lived static tokens. The client has to support OAuth 2.1 with dynamic client registration (DCR) - Claude Desktop, Claude Code and Cursor do. A client without it cannot connect today: there is no key to copy into a box.
Where: Settings > Connectors.
- Open Claude Desktop and go to Settings > Connectors.
- Choose Add custom connector and paste the URL:
https://veriteknik.com/api/mcp - Sign in and approve the connection when prompted.
On the third step your browser opens the VeriTeknik consent page. If you are already signed in, you land straight there; if not, you sign in first.
Where: the terminal.
claude mcp add --transport http veriteknik https://veriteknik.com/api/mcp
Or put it in .mcp.json at the project root (this is the block the hub's connection card copies for you; Claude Code rejects it without the type line):
{
"mcpServers": {
"veriteknik": {
"type": "http",
"url": "https://veriteknik.com/api/mcp"
}
}
}
Then start a session, type /mcp and sign in to veriteknik; the consent page opens in your browser. Claude Code runs the OAuth flow for you and never asks for a token.
Where: Settings > Connectors > Create.
Developer mode has to be on first (Settings > Security and login); in a business workspace an admin turns it on. Creating a connector asks for a name, a description and the MCP server URL; put https://veriteknik.com/api/mcp in the URL field.
Custom connectors are not available on every plan (the free plan has none). OpenAI renamed these menus during 2026, so if your screen does not match, search the settings for "connector" or "MCP".
Where: ~/.cursor/mcp.json (all projects) or .cursor/mcp.json in the project root.
{
"mcpServers": {
"veriteknik": {
"url": "https://veriteknik.com/api/mcp"
}
}
}
After saving, Cursor marks the server Needs login; click it and the consent page opens in your browser.
Where: .vscode/mcp.json in the project root.
{
"servers": {
"veriteknik": {
"type": "http",
"url": "https://veriteknik.com/api/mcp"
}
}
}
The key is servers, not mcpServers, and it takes "type": "http". The first agent-mode call asks you to sign in.
Where: ~/.codeium/windsurf/mcp_config.json (also reachable from Cascade > MCP).
{
"mcpServers": {
"veriteknik": {
"serverUrl": "https://veriteknik.com/api/mcp"
}
}
}
For remote servers the field is serverUrl, not url. Windsurf supports OAuth on every transport; the first call opens the consent page.
Where: Settings > Tools > AI Assistant > Model Context Protocol (MCP) > Add, then paste JSON into the dialog.
{
"mcpServers": {
"veriteknik": {
"url": "https://veriteknik.com/api/mcp"
}
}
}
Remote servers declared by URL need 2025.3 or later. Note: JetBrains' own documentation says nothing about an OAuth sign-in flow for remote MCP servers; if AI Assistant cannot open the consent page in a browser, the connection cannot be made, because we hand out no token to paste. If you have tried it, tell us how it went.
Where: Settings > Agent Behaviour > MCP Servers, or ~/.config/kilo/kilo.jsonc directly (.kilo/kilo.jsonc for one project).
{
"mcp": {
"veriteknik": {
"type": "remote",
"url": "https://veriteknik.com/api/mcp"
}
}
}
When the server supports OAuth, Kilo Code starts the flow by itself on connect.
Roo Code does not start the OAuth flow against a protected remote MCP server (open enhancement #8119; the repository went read-only in May 2026). Since we issue no static tokens, it cannot connect to VeriTeknik today.
Kilo Code, from the same family and still maintained, does support OAuth; its tab gives you the same setup.
Where: the terminal, or ~/.config/devin/mcp_config.json.
devin mcp add veriteknik https://veriteknik.com/api/mcp
devin mcp login veriteknik
The login command opens the VeriTeknik consent page in your browser. To configure it by hand instead:
{
"mcpServers": {
"veriteknik": {
"url": "https://veriteknik.com/api/mcp",
"transport": "http"
}
}
}
Devin falls back to SSE when it sees a 4xx; our endpoint speaks standard Streamable HTTP, so no fallback is needed.
Where: ~/.gemini/settings.json.
{
"mcpServers": {
"veriteknik": {
"httpUrl": "https://veriteknik.com/api/mcp"
}
}
}
The field is httpUrl, not url. Then sign in to the veriteknik server with /mcp auth inside a session; Gemini CLI does dynamic client registration and stores the token itself.
Where: the terminal, or ~/.codex/config.toml.
codex mcp add veriteknik --url https://veriteknik.com/api/mcp
codex mcp login veriteknik
To write it by hand instead:
[mcp_servers.veriteknik]
url = "https://veriteknik.com/api/mcp"
The same config.toml is shared by the Codex CLI, the IDE extension and the desktop app. Verify the connection with /mcp.
To add it from the app instead: open the account menu at the top right, then Settings > Plugins > Add (top right) > Add MCP server. In the form, set Type to Streamable HTTP, put https://veriteknik.com/api/mcp in URL, and click Save. The name is yours to choose; it is what you will see in the server list.
Leave the bearer token and header fields empty. This server does not use a key you carry around: press Authenticate next to the row on the MCPs tab, and your browser opens, signs you in to VeriTeknik and asks which permissions you are granting. The app starts seeing tools once you approve.
Where: Integrations in the right sidebar > Install > edit mcp.json.
{
"mcpServers": {
"veriteknik": {
"type": "http",
"url": "https://veriteknik.com/api/mcp"
}
}
}
Save, then press Authenticate next to the server: your browser opens, you go through the consent screen, and you land on "Authentication Successful".
LM Studio added OAuth for remote MCP servers in 0.4.10 (April 2026); on an older build, update first.
Where: the MCP Servers icon in the Cline panel > Configure > Configure MCP Servers.
{
"mcpServers": {
"veriteknik": {
"type": "streamableHttp",
"url": "https://veriteknik.com/api/mcp"
}
}
}
The type value is camelCase: write streamable-http and Cline falls back to SSE and gets a 405. Cline's documentation says nothing about an OAuth sign-in for remote servers; if you have tried it, tell us how it went.
For a client that is not listed, start with the generic shape above (mcpServers + url). If it asks for a transport, choose Streamable HTTP: https://veriteknik.com/api/mcp is a single HTTP endpoint, and there is no separate SSE address.
The one requirement is OAuth: a client that cannot open the consent page in a browser cannot connect, because we hand out no static token to paste.
Clients we tested#
| Client | Status |
|---|---|
| Claude Desktop | Tested by us |
| MCP Inspector | Tested by us |
| Devin | Verified by a user (user report, September 2026) |
| Claude Code | Tested by us (all 26 tools, September 2026) |
| ChatGPT | Written from their documentation, tell us how it went |
| Cursor | Written from their documentation, tell us how it went |
| VS Code / GitHub Copilot | Written from their documentation, tell us how it went |
| Windsurf | Written from their documentation, tell us how it went |
| JetBrains AI Assistant | Written from their documentation, OAuth support unclear |
| Kilo Code | Written from their documentation, tell us how it went |
| Roo Code | Per their documentation: no OAuth, cannot connect today |
| Gemini CLI | Written from their documentation, tell us how it went |
| Codex (app and CLI) | Tested by us (September 2026) |
| LM Studio | Tested by us (September 2026) |
| Cline | Written from their documentation, OAuth support unclear |
These clients rename their menus about once a month. If a step does not match what you see, open a support ticket: we will get you connected and fix this page.
The Consent Page: You Draw the Envelope#
The consent page is more than an "accept" button. This is where you draw that connection's security envelope: what it may touch, how much it may spend in a month, and how long it lives.
Company#
Pick the company the connection is made for under Select company. One connection belongs to one company; a second company means a second connection.
Permission groups#
Permissions are handed over in meaningful groups, not one by one:
| Group | What it grants | Default |
|---|---|---|
| Servers: view | View VPS, server, and monitoring status, and read a server's live health: uptime, load, memory, disks, which services are running or failed, containers and listening ports | On |
| Servers: manage | Start, stop and reboot a server, and take snapshots | Off |
| Server investigation | Read server logs and files, list directories, search file contents, and see the backup inventory (read-only) | Off |
| Servers: create and delete | Order a server from balance and delete an MCP-created server with exact hostname confirmation | Off |
| Servers: execute tasks | Install SSL, publish static sites, and run safe commands | Off |
| Servers: admin commands | Changing commands such as installing packages, configuring and restarting services, writing files; the server's own BIOS, classification and autonomy rules apply, the destructive class never runs, a notification after every batch | Off |
| Domains: view | View domains and DNS records | On |
| DNS: manage | Add, edit, and delete DNS records | Off |
| Domains: register and manage | Register a new domain from balance | Off |
| Billing: view | View invoices, contracts, and quotes | On |
| Support: view your own tickets | View tickets you opened | On |
| Support: open and reply to tickets | Open a ticket and reply to existing ones | On |
| Team: view | View team members | On |
The list shows the groups that actually have a tool behind them today. A capability with no tool behind it is not on the consent page at all: asking you to approve something the connection cannot use makes the envelope look wider than it is. The day a capability reaches MCP, its group comes back to the list by itself - that is how Servers: create and delete and Domains: register and manage arrived.
Under every switch, the names of the tools that group switches on are printed as small labels (stop_vps, register_domain and so on).
The labels come from the same source as the tool list your application will see; a group with no labels under it has all of its tools switched off right now, and turning it on gains you nothing.
A group your role does not hold arrives locked, with "Your current role does not have this permission" beside it. Nobody can hand an application a permission they do not have themselves - the envelope can never exceed your own role's ceiling.
You cannot continue without selecting any group at all: "Select at least one permission group. A connection that can do nothing is not worth making."
Monthly spend cap#
Monthly spend cap (USD) is the ceiling for what this connection may spend in a calendar month. The default is 20.00 USD.
Spent this month reads the gross USD price recorded on orders created through this connection since the start of the UTC calendar month. A refund restores wallet credit but does not reduce that monthly total. Wallet and cost tools only read data; server creation and deletion require the separate lifecycle permission.
90 days#
A connection is valid for 90 days from the moment you approve it, then expires on its own. Reconnecting the same application resets the clock and puts the envelope back in front of you for a fresh approval. We are not handing out a permanent key; we are handing out a renewable appointment.
The "not identity-verified" warning#
Some applications register with us anonymously. For one of those, the consent page carries this notice: "This application registered anonymously on {date} and its identity was not verified. Only allow an application you recognize."
The warning is information, not an accusation: we have no way to verify who that application is. If you started the connection yourself, all is well. If a consent page appeared that you did not ask for, hit Deny.
Deny builds no connection: the application gets an "access denied" answer, no connection or grant is created on your account, and not a single row of your data is read. The decision itself is written to the audit log - refusing is a security event too.
What Your Agent Can Do Today#
The catalogue holds 45 tools; a connection sees only those its envelope allows. A tool belonging to a group you did not grant does not even appear in the application's list.
Servers
- List your servers; read one server in full (IP addresses, operating system, CPU/RAM/storage/bandwidth)
- List snapshots and take a new one
- A snapshot that could not be taken (the server already has 3, or its node has no snapshot storage) is reported as an error with the reason, never as a success; power commands may return an empty
taskId, which is not a failure - read the state back withget_vps_details - Start, stop and restart a server
- Read one server's CPU, memory, network and disk usage over time
- Read bandwidth consumption against the included quota, and any overage
- Read one server's uptime monitoring: whether it is up right now, 24-hour / 7-day / 30-day uptime, average ping and recent events
- Live up/down status of monitored servers and domains
- The catalogue of dedicated (physical) servers for sale, with prices
Domains and DNS
- List your domains with status and expiry dates
- Check whether a name is available, and what an extension costs
- Register a new domain from balance (own section below)
- Read a domain's DNS zone and all of its records
- List your domain monitors and read one monitor's status, certificate lifetime included
Billing
- Read your invoices and the line items of a single invoice
- Read your contracts, their items and renewal terms
Support
- List your tickets and read one ticket's conversation history
- Open a new ticket and reply to an existing one
Team
- List your company members, their roles and their status
Inside your server (see the section below)
- A live health snapshot of one server: load, memory, disks, running and failed services, containers, listening ports
- The last lines of a known log, and a search within it
- The contents of a directory, and a window of lines from a text file
- A text search under a directory
- Backup status: when the newest backup was taken, how much space it uses, whether a schedule exists
Wallet and VPS cost#
| Tool | What it returns | Permission group |
|---|---|---|
get_balance |
Available balance, reserved advance, uninvoiced usage, currency, connection budget and the server clock (serverTime, UTC) |
Billing: read |
estimate_cost |
Monthly cap, hourly USD price, setup, tax, required advance and whether the wallet covers it | Servers: read |
For a quote, provide vcpu, ram in MB, disk in GB and optionally ips (default: 1), using values from the current VPS catalog.
The quote uses your company's billing currency and tax profile and creates no order.
balanceCovers checks the required advance against the available wallet balance; remainingUsd separately describes the connection's remaining order budget.
balance is the spendable amount: the advance reserved for running servers has already been moved out of it and is shown as reservedBalance (creating a server lowers the balance by the advance at once); uninvoicedUsage is the part of that advance consumed so far, not an additional charge. The whole wallet is balance + reservedBalance.
New MCP VPS orders reserve the monthly cap and setup as an advance; no monthly invoice is issued at creation.
The hourly rate is the monthly price divided by 720; started hours round up, the monthly cap applies, and setup is added once.
Each resource-period net amount rounds up to a cent once, followed by tax calculation.
Usage is grouped by company and currency at the end of the UTC calendar month, with a 10 USD invoice threshold.
The mandatory invoice deadline overrides the threshold; deleting a service may require an invoice before month end.
Existing monthly services keep their current model.
An existing connection may need Billing: read approved again to see its wallet balance.
During the final 48 hours of a period, a warning is prepared once for that period if the available balance cannot cover the next advance; the daily check provides a warning opportunity while running normally. You can top up your balance in the panel. You are notified after insufficient funds actually cause a suspension; once enough balance is available, the server resumes at the next daily check and you receive a separate notification. These notifications link to the server, not an invoice. Exchange-rate failures are reported to the technical team without sending the customer a low-balance notification.
Discover VPS order options#
Ask your agent to call list_vps_catalog before estimating or creating a server.
It reads the same catalog as the VPS page and requires Servers: read.
Omit kind for the whole catalog, or select plans, images, or applications.
| Section | What it returns |
|---|---|
plans |
Selectable vcpu, ram (MB), disk (GB), and ips arrays. Retired sizes are excluded. Additional disk is currently fixed at zero for MCP orders. |
images |
OS name, version, id to send as osImageVersionId, and minimumRamMb. Select enough RAM for the chosen OS. |
applications |
Application name, slug, category and availability. Only availability: "mcp" entries can be ordered with applicationSlug. |
hub_configuration_required applications need the form on the VPS page; unavailable applications are not ready for ordering.
Choose exactly one OS image or application, then call estimate_cost with resource values from plans and review the quote before create_vps.
Catalog values and image IDs can change; the order revalidates them.
If a requested catalog source fails, the tool reports an error rather than treating the failure as an empty catalog.
Register a domain#
Approve Domains: register and manage; the register_domain tool comes with it. The staff tool switch must also be enabled.
| Tool | Behaviour |
|---|---|
register_domain |
Takes domainName and an optional period (1 to 10 years). Ask search_domain first for availability and price. A multi-year term is priced as one first year at the registration price plus the remaining years at the renewal price; a promotion covers the first year only. The fee is paid from balance only; a card is never charged. If the registrar refuses, the amount returns to the balance. |
Registrant details are never invented: name, e-mail and verified phone come from the ordering user, address and country from the company billing profile, and all four contacts (registrant, admin, technical, billing) are the same person.
If the billing address has no postal code the agent may pass postalCode, or add it to the address; any other missing field comes back as a profile-completion precondition in the hub, and no order is created.
For a .tr name the registrant identity (national ID for individuals, tax number and tax office for companies) is read from the company profile; if it is missing you are sent to the hub the same way.
A registered domain is delegated to VeriTeknik nameservers, so add_dns_record works on it right away.
If another order is still running on the same connection (a server creation, say), the second waits for it; that is how the monthly spend cap sees every order on its own.
Create and delete a VPS#
Approve Servers: create and delete to use create_vps and delete_vps. The staff tool switch must also be enabled.
| Tool | Behaviour |
|---|---|
create_vps |
Takes hostname, vcpu, ram (MB), disk (GB), optional ips, and exactly one OS version or application slug. The monthly cap and setup are reserved from balance only; usage is invoiced later. Morpheus access (the door the server tools connect through) is on by default and is set up automatically once the server has booted; the company must have accepted the CogMem-AI addendum once, otherwise the accept_cogmem_contract step is returned before any money moves. morpheusAccess: false creates the server without Morpheus. |
get_vps_details |
Fills a pending IP from Solus. MCP-created servers include createdViaMcp and refundIfDeletedNow from the same deletion refund authority. Every server carries morpheus.access, whether the server tools can reach it: active, pending (automatic setup after creation still running), failed (not completed within a day, enable it in the hub), not_enabled (never switched on), unreachable (a credential exists but the server cannot be reached right now), disabled (the credential was disabled; re-enable it in the hub). |
delete_vps |
First send vpsId for the hostname and refund preview. Then send the exact confirmHostname with a new requestId to delete permanently. |
Every create/delete call requires a UUID requestId. Repeating a completed call within ten minutes returns its first result.
If creation returns ipAddress: null and provisioning: true, call get_vps_details for the address.
monthlyUsd is the monthly USD cap; hourlyUsd is the hourly USD rate.
reservedFromBalance is the advance; the compatibility field chargedFromBalance returns the same amount in the company's currency.
This amount does not represent usage invoiced at creation.
Missing prerequisites return a hub action: top_up, complete_company, verify_phone. Do not send payment-card data.
MCP can delete only a server created through MCP for the same company. Another authorized connection can delete it even after its originating connection is revoked. Delete panel-created servers in the hub. A hostname mismatch returns a fresh confirmation preview; no separate hub approval click is required. Deleting a new hourly service releases only its unused advance; consumed usage remains for grouped invoicing. Releasing the advance does not reopen the connection's gross monthly order budget. To change configuration or recreate an hourly service, order a new server with the required specifications.
An uncertain creation returns review_order or reconciliationRequired. Do not reorder with a new requestId; ask support to inspect the server/order identifiers.
New orders through that connection wait until the review is completed. Wallet reads and eligible server deletion remain available.
Looking Inside Your Server#
When an application misbehaves, the real question is usually not "is my server up" but "what happened on my server". These six tools let Claude look inside your server, read-only: it reads logs, reads files, checks service status, counts your backups. None of them changes anything, stops a service, or writes to a file.
The health snapshot (is the service up, how much disk is left, what is listening) rides on Servers: view, the group you almost certainly granted already. The other five - reading a log, reading a file, listing a directory, searching file contents, the backup inventory - return file CONTENT, so they need Server investigation, which is off unless you switch it on.
In an app that supports it, the health snapshot opens as an interactive panel inside the chat, with its own Refresh button. In an app that does not, the same data arrives as plain text, the way it always has. Which apps support the panel is up to the client, not us.
You have to switch Morpheus SSH access on first
These tools connect to your server over SSH, and you open that door: go to Sunucular (Servers) > the server > Morpheus in the hub and hit Morpheus'u Etkinleştir (Enable Morpheus). The hub's menu is in Turkish whatever language you read this page in, so the labels here are the ones you will actually see. On servers created by a one-click application (app) install, you also need to run the bootstrap command shown on screen, once, on the server itself.
A server you create through the connected app with create_vps opens this door for you: Morpheus access is set up once the server has booted (usually a few minutes), and morpheus.access in get_vps_details goes from pending to active. A server tool called in the meantime answers "being set up automatically, retry in a minute". The one requirement is that your company has accepted the CogMem-AI addendum once.
If access is not on, the tool tells you so in a plain sentence and names the switch. It does not try anything and it does not guess.
Once connected, you can write things like this in Claude Desktop:
- "Is MySQL running?"
- "Show me the last 200 lines of the nginx error log"
- "Find where 'TypeError' appears under /var/www/app"
Where it may look, and where it may not#
The readable places are fixed and the list is short: /var/log, /var/www, /srv, /opt, /home, and the web, PHP and database configuration directories (/etc/nginx, /etc/apache2, /etc/httpd, /etc/php, /etc/mysql, /etc/postgresql). /etc as a whole is not on the list.
Some files are refused even inside those directories:
.envand all its variants (.env.local,.env-production,app.env)- private keys and keystores:
*.pem,*.key,*.p12,*.pfx,*.ppk,*.kdbx,*.jks,*.keystore, theid_rsafamily - password and account files:
shadow,.htpasswd,.netrc,.pgpass,.my.cnf,debian.cnf,.git-credentials,.npmrc,.pypirc,credentials,secrets.yml/.yaml/.json - database files:
*.sqlite,*.sqlite3,*.db - and the entire contents of these directories:
.ssh,.gnupg,.aws,.docker
Claude will see them in a directory listing - describing your server as it actually is - and refuse to open them. The search tool behaves the same way: if a search under /var/www matches a line inside a .env file, those lines are not returned to you; it only tells you how many it withheld.
wp-config.php stays readable on purpose - it is the classic "why is my site down" file. The passwords inside it are the masker's job.
On top of that:
- When you ask for a log, the answer says which file it read. The same log lives in different places on different distributions (
/var/log/apache2/error.logon Debian,/var/log/httpd/error_logon RHEL); Claude tries them in order and reports what it found, not what it tried. If none of them exist, it says that too. - Every line that comes back passes through a masker: anything shaped like a password, an API key, a token or a private key arrives as
[REDACTED:...], and you are told how many values were masked. The masker is a pattern list, so it is best effort - do not paste a credential file into a chat to test whether it catches it. That is exactly why those files are never opened in the first place. - A backup file is never opened.
check_backupsonly counts, weighs and looks at dates. - An answer never exceeds 64 KB, and says so plainly when it was cut.
- The health snapshot says which host firewall service is active (
firewall) and, when a database or cache port is bound to every interface (MySQL 3306, PostgreSQL 5432, Redis 6379 and the like), writes it towarnings: "verify that the firewall blocks it" when a firewall is active, "reachable from the internet unless an upstream filter exists" when none is - it looks at the host's own firewall and cannot see a cloud security group or an upstream firewall. It does not read the rules themselves either; askrun_commandforsudo -n firewall-cmd --list-allfor that. - The name you ask a service by does not matter:
sshandsshd,apache2andhttpd,mysqlandmariadb,php-fpmandphp8.x-fpmare tried together, and the answer says which unit replied (unit). - A call never runs longer than 30 seconds; if it does, you get what it had plus an "incomplete" warning.
Your autonomy level does not block these reads
The autonomy level on the Sunucular (Servers) > Morpheus tab is yours and stays exactly as you set it - but every command these six tools emit is read-only, so they work even at the strictest level (confirm_all, and observe_only too). A code is asked for commands that change something, and these change nothing. The hub chat already ran these reads without a code; now the connected application does too.
One exception, and it is about your account rather than the channel: if your server is on confirm_all or safe_auto, your account must have two-factor authentication enabled. That rule is channel-independent - the hub chat asks for the same thing on the same server - and on full_auto it is never asked at all.
What it cannot do#
Some things were deliberately kept off MCP:
- Paying invoices, topping up a balance and managing cards. Use the hub for these. MCP can order a VPS using the existing wallet balance within the connection’s spending cap.
- Reinstalling a server, resetting a root password and resizing one. These remain panel-only. Deletion is available only for a VPS created through MCP for the same company, with an exact hostname match; a VPS created through the panel cannot be deleted through MCP.
- Acting with staff authority. Today's connections work with customer identity only.
Review connection permissions for new capabilities
The consent page shows only groups with an available tool. Servers: create and delete, DNS: manage and server tasks are now offered; these groups are not selected by default. Earlier releases removed permissions with no tool from old connections; explicitly widen the connection’s envelope for a new capability. Existing log/file read permission does not grant access to server tasks. Live standalone permissions on an older connection appear as separate chips on the Connected Apps (MCP) card, and Edit preserves them. To remove those standalone permissions, revoke the connection and connect again.
The Guardrails You Will Notice#
The same request going out twice never creates a second action. Every state-changing call carries a request id (the application generates it; nothing is asked of you). A request repeated because the network dropped returns the first call's answer; no second ticket, no second snapshot. That protection lasts ten minutes.
Server deletion checks provenance and the exact hostname. Only a VPS created through MCP for the same company can be deleted. If the hostname is missing or different, the application shows the correct name and refund preview before deletion; a call with the exact confirmation deletes it. This tool does not send an additional hub/e-mail approval link. The general approval gate remains available for other irreversible tools; no tool in today’s catalogue uses that general gate.
Pending approvals are capped. One connection may keep at most three approvals waiting. An indecisive application has no business filling your inbox.
Changing the envelope takes effect at once. Switch a group off and the application's very next call meets the narrower envelope; nobody waits for a session to end or a token to die.
Connections end after 90 days. An expired connection does not quietly keep working; it tells the application that this connection has expired and it should reconnect.
An approval link is single use and lives 15 minutes
The approval link you receive can be spent exactly once, and it expires after 15 minutes. Deliberately short: an approval should not sit in your pocket as an open cheque. If it lapsed, ask the application for the same job again and a new approval arrives. The link is useless in anyone else's hands - opened under a different account it behaves like a page that never existed.
Managing Your Connections#
The Settings > Agent Connections > Connected Apps (MCP) card shows every connected application:
- The application name and whether its identity was verified (the Not identity-verified badge)
- The permission groups you granted
- Monthly cap: {amount} USD and Spent this month: {amount} USD
- Valid until {date}
There are two actions:
Edit - change the groups and the cap, then hit Save. Narrowing applies immediately and asks nothing. Widening (granting a new group or raising the cap) asks for a fresh two-factor code on accounts with 2FA on; after that you are not asked again for two hours.
Revoke access - invalidates the connection and its tokens immediately.
Don't Panic: revoking breaks nothing
Hit Revoke access and the application is stopped at the door on its next attempt and asked to reconnect. Your server keeps running, your invoices keep being issued, your domain keeps resolving - the only thing you revoked is one application's right to ask questions on your behalf. Change your mind and you reconnect from your MCP client, walk through the consent page, and carry on where you left off.
When Something Goes Wrong#
When the application hits a problem it gets a plain sentence back. The most common ones:
| Message you see | What it means | What to do |
|---|---|---|
| MCP access is disabled for this company | MCP access is off for your company | Ask a company owner or admin to enable it on the AI Agent Access (MCP) card |
| This connection has expired | The 90 days ran out | Reconnect from your MCP client; the consent page starts a fresh 90 days |
| step_up_required / "You need to verify your identity before continuing" | Widening or approving needs a fresh verification | Enter your two-factor code; you will not be asked again for two hours |
| This connection lacks the permission ... | That group is not in the envelope | Open the group on the Connected Apps (MCP) card with Edit |
| Monthly cap ... USD | The monthly ceiling was reached | Raise it with Edit |
| requestId already used with different arguments | The application reused one request id for a different call | That is a flaw on the application side; restart the request, and open a ticket with us if it keeps happening |
| Identity arguments are never accepted over MCP | The application tried to name the company it speaks for | Nothing for you to do; the company always comes from the connection itself, never from what the application says |
| Morpheus SSH access is not enabled on this server | Morpheus SSH access is off for that server | Switch it on under Sunucular (Servers) > the server > Morpheus; on app-installed servers run the bootstrap command once |
| The Morpheus DevOps agent is switched off for this server | The agent is disabled on the server | Switch it on from the same Morpheus tab |
| That path is a credential ... and is never readable | A file or directory that is never opened was requested (.env, a key, a password or database file, or anything under .ssh, .gnupg, .aws, .docker) |
This is the correct behaviour; if you need the content, look at it on the server yourself |
| This server's autonomy level ... / two-factor authentication | The server asks for a code before commands, and your account has none | Enable two-factor authentication under Ayarlar (Settings) > Güvenlik (Security), or set the server's autonomy level to full_auto |
The server has no file utility |
The tool cannot tell text from binary on that machine, so it refuses to read anything | Install the file package on the server and try again |
| The server could not be reached | The machine did not answer | Check that it is running and that Morpheus SSH access is still enabled; try again shortly |
If the application cannot connect at all, check these in order: is MCP access on for your company, did you paste the address correctly (https://veriteknik.com/api/mcp), and is your VeriTeknik session open in the browser.
The messages are English: the whole MCP surface - tool names, descriptions, error sentences - speaks one language, and your agent relays them to you in yours. The one exception is a generic failure or a quota message, where only the tool itself knows the reason; there its own sentence is carried through unchanged, because it is the only information there is.
Connected apps do not outlive an archived account
When a customer account is archived, its connected applications are revoked with it. A connected application is not a session - it can keep working for months without anyone clicking anything, so closing the account has to close the connection too.
If anything is unclear, open a support ticket. We answer - and without the seven and a half million year wait.
Running server tasks#
Select Servers: execute tasks separately on the connection.
An existing consent to read logs and files does not grant task execution.
setup_ssl verifies that your authoritative A record points to the VPS primary IP before installing nginx and a certificate.
deploy_static_site writes under /var/www/<domain>/, checks and reloads nginx, and preserves an existing managed TLS configuration.
These templates use Debian/Ubuntu and sudo; the server's Morpheus, BIOS, autonomy and OTP policies still apply.
| Tool | Input |
|---|---|
add_dns_record |
zoneName, name, type, content; optional ttl, priority |
update_dns_record |
The same fields plus the exact previousContent to replace |
delete_dns_record |
The exact content to remove; confirm:true for high-impact deletion |
setup_ssl |
vpsId, domain; optional email (default: the e-mail of the user who authorized the connection) |
deploy_static_site |
vpsId, domain, files:[{path,content}] |
run_command |
vpsId, command, optional timeoutSec (1-60) |
DNS tools require the DNS management group; company ownership and managed-change policies remain enforced.
File paths must be relative; traversal, absolute paths and NUL are refused.
Send up to 50 UTF-8 text files, at most 512 KiB each and 5 MiB combined; binary files are not supported.
run_command accepts only commands classified as safe, limits each output stream to 16 KiB, and reports truncated.
A command that ran and exited non-zero is an answer, not an error (systemctl status exits 3 for a stopped service); the result carries exitCode, and only a command that returned no result at all is reported as an error.
Firewall and socket reads are accepted too: firewall-cmd --state / --list-* / --get-*, nft list ..., iptables -L -n, ufw status, ss -tlnp. They need root, so they may be prefixed with sudo -n; sudo is accepted only by the families that need root (see the list below).
ss filter expressions pass too: ss -tnp state established (who is connected), ss -tn sport = :22 or dport = :443, ss -tn dst 10.0.0.5, ss -tn sport lt :1024; parentheses, quotes, brackets and the </> signs (shell redirection) are refused - compare with =, == or the words eq neq lt gt le ge.
On Ubuntu, ufw says more than iptables -L shows: read the effective policy with sudo -n ufw status verbose, and on nftables-based systems with sudo -n nft list ruleset; iptables -L shows only the legacy tables, and an empty listing there does not mean the firewall is off.
Task tools require a requestId; inspect server state before repeating failed work with a new request.
The free command field is limited to a diagnostic vocabulary; every family is the read verbs of one program: files (ls, cat, head, tail, df, du, stat, wc, find with tests only, grep on named files with a bare pattern (no recursive -r; content search is the search_server_files tool), tree), system (top -bn1, vmstat 1 3, iostat, nproc, lscpu, lsblk, free, uptime, hostnamectl, date, w, who, last -n, dmesg), journal (journalctl with -u/-n/-p/-b/-k/--since/--until/-o; no -f), services (systemctl status/is-active/is-enabled/show/list-units/list-timers/cat/--failed), network (ip addr/route/link/neigh, ss with filters, netstat, lsof -i, dig, host, nslookup, ping -c 1..5, traceroute, mtr -rw -c N, curl -sSI / curl -sS -m N with one http(s) URL, no redirect following, a localhost URL answers HEAD (-I) only), firewall, configuration and versions (nginx -t/-T, apachectl -t, certbot certificates, crontab -l, php -v/-m, node -v, python3 -V, mysql --version, which, getent), containers (docker ps/images/logs --tail N NAME/stats --no-stream/version/info/top, docker compose ps/logs), packages (apt list --installed, apt-cache policy, dpkg -l, rpm -qa, dnf list installed, snap list).
Reads that need root take a sudo -n prefix (journalctl, dmesg, netstat, lsof, firewall reads, nginx -t, certbot certificates, crontab -l -u, docker).
Wildcards in find -name and grep patterns are written backslash-escaped (find /var/www -name \*.log); the command line runs unquoted, so a bare * would be expanded by the shell and is refused.
find, tree and du walk only under the readable roots (/var/log, /var/www, /srv, /opt, /home and the web, PHP and database configuration directories, minus the agent's own directories); a walk from / or from the working directory is refused. Credential files (.env, id_rsa, *.pem, credentials...) are refused by name, exactly as in the file-reading tools.
Not accepted: env/printenv (credential dumps), docker inspect and docker compose config (container environments carry secrets), php -i, journalctl -f, find -exec/-delete, curl with a body, method, header, output file or credentials, link-local or metadata URLs; quoting, pipes, redirection, substitution and any program not on the list.
Admin commands (run_admin_command)#
Approve Servers: admin commands separately on the connection; the existing task consent does not include it.
run_admin_command {vpsId, commands:[...], intent, timeoutSec} runs up to 10 commands in order, stops at the first non-zero exit and reports which line failed (failedIndex) and how many ran (ran).
Installing packages, configuring and restarting services, cloning and building an application, writing files and adding firewall rules are done with it; prefix root work with sudo -n.
The server's own policy decides what runs: the BIOS rules on its Morpheus tab, the safety classification and the autonomy level.
The destructive class (mass deletion, disk formatting, user removal, reinstall) never runs over this connection at any level; the answer is PANEL_ONLY and you do that work in the hub.
If the autonomy level wants a code for moderate commands (the default confirm_all), the tool answers PRECONDITION_REQUIRED and nothing runs: a connected app cannot ask you for a code.
Both ways out are in the hub, on Sunucular (Servers) > the server > Morpheus: enter your verification code on the Komut kilidi (command lock) card and tell the agent to retry, or raise the Yetki seviyesi (autonomy level) on the same tab (only the company owner or an admin can change the level).
A server created with create_vps by a connection holding this group is born fully autonomous: changing commands flow without a code.
Each line is one program: ;, &&, ||, | and command substitution are refused (even inside quotes); put the next step on the next line.
Quotes and redirection are allowed; write a system file with sudo -n tee /etc/x <<< "content" (a shell redirect into /etc, echo ... > /etc/x, is the classifier's destructive class and is refused).
Every batch is written to the server's command log under the connection's id, and the company is notified: which server, which intent, how many commands, the last exit code.
No per-call approval is asked; you see and confirm the command in your client (Claude Desktop).
If the catalog is missing#
When you approve a new group on the consent page, or we publish a new tool, the server sends your connected client a "tool list changed" notification, and clients that understand it refresh the list by themselves.
In a client that does not, reload the tool list by hand or remove and re-add the connection; that is the most common reason an approved capability does not show up as a tool, not a closed gate on the server.
In clients that load the list when a chat starts, such as claude.ai, opening a new chat is enough.
If a tool has no label under its switch on the consent page, staff have switched that tool off; reconnecting will not help there, open a support ticket instead.
For a support investigation, share the test time and the X-App-Version header from the /api/mcp response; do not share your access token.
The header identifies the serving application's commit; the number of tools shown by a client does not identify its version.
An invalid image or resource choice returns INVALID_ARGUMENT without creating an order.
Get current choices from list_vps_catalog and submit corrected order arguments with a new requestId.
Install applications that require an extra form through the hub.
File search applies includeGlob to file names while keeping credential and minified files excluded.
redactions counts masking replacements in collected command output before filtering and truncation, so it can differ from the number of markers displayed.
You can also filter contracts by customer_signed, fully_signed, and cancelled.