portveil-mcp
This server lets an AI assistant view, control, and administer Portveil VPN devices and their exit locations.
Read-only: list devices, list available locations, get one device's state, view account plan/usage, and list recent activity.
Control: move a device to a country/city/location, rotate it to the next location, start or stop scheduled rotation (every 5–10080 minutes), reconnect its tunnel, or disconnect it (destructive).
Admin: add devices, rename devices, toggle remote control, and remove devices (destructive).
Verification & safety: moves wait for the exit server to confirm the switch; partial names are matched case-insensitively; destructive tools are flagged; actions are logged by API token.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@portveil-mcpMove my scraper box to Finland."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Portveil MCP server
Let an AI assistant see the devices on your Portveil account and move them between VPN locations.
"Move my scraper box to Finland." "Rotate every agent to a new location." "Which of my devices aren't protected right now?" "Rotate the scraper between the US and Finland every 15 minutes."
Moves are verified: a tool only reports success after the device has switched and the exit server in the new location confirms it sees that device.
Tools
Tool | What it does | Needs |
| Every device: protected or not, where it exits, live speed (↓/↑ Mbps), remote control on/off | read |
| The locations you can move to | read |
| One device's current state, including live speed and any rotation | read |
| Plan and devices used | read |
| Recent moves, reconnects and changes, and which token made them | read |
| Move a device to a country or city ("Finland", "US", "Helsinki") | control |
| Move a device once to the next location | control |
| Move a device automatically every N minutes (5–10080), optionally among chosen locations. Portveil runs the schedule, so the assistant can close | control |
| Turn scheduled rotation off | control |
| Re-establish a device's tunnel | control |
| Turn a device's VPN off (flagged destructive: a hint that tells well-behaved assistants to check with you first) | control |
| Add a device. Phones and laptops (WireGuard app): creates it and saves its tunnel files locally, key never shown in chat. Linux servers and agent machines: gives the exact commands to run on that machine, which makes its own key and registers itself | admin (phones/laptops) |
| Rename a device and/or turn its remote control on or off | admin |
| Remove a device for good (flagged destructive) | admin |
Tool names changed in 0.3.0 to one verb_noun pattern: device_status → get_device, account_info → get_account, recent_activity → list_activity, set_rotation → start_rotation.
Devices can be named loosely ("scraper" finds "Scraper box"); an ambiguous name returns the choices instead of guessing.
Related MCP server: Fleet MCP
Setup
In the Portveil dashboard, create an API token. Choose control scope to let the assistant move devices, or read to let it only look. Don't give it your account key.
Note your account ID (
acct_…).Add the server to your assistant:
Claude Code
claude mcp add portveil -e PORTVEIL_ACCOUNT_ID=acct_… -e PORTVEIL_TOKEN=clt_… -- npx -y portveil-mcpClaude Desktop (claude_desktop_config.json), Cursor (.cursor/mcp.json) and most other clients:
{
"mcpServers": {
"portveil": {
"command": "npx",
"args": ["-y", "portveil-mcp"],
"env": { "PORTVEIL_ACCOUNT_ID": "acct_…", "PORTVEIL_TOKEN": "clt_…" }
}
}
}Devices must be running the Portveil app or the Portveil agent with remote control on. Devices using the plain WireGuard app are shown but can't be moved.
Security
Use a scoped API token. Every action it takes is recorded in your account's activity log with the token that made it, and you can revoke it in the dashboard at any time.
The server talks only to
https://api.portveil.com(override withPORTVEIL_API). It stores nothing.
Development
npm install
npm test # builds, then runs the tests against a fake Portveil APIAvailable Tools
14 toolsadd_deviceAdd deviceA
Add a new device to the account. kind "phone_or_computer" (iPhone, Android, Mac, Windows using the WireGuard app): creates the device now and saves one WireGuard tunnel file per location, with a private key made locally, into a folder on the machine running this MCP server; the key is never shown in the reply. Import a file in the WireGuard app to connect. These devices are view-only: they can't be moved remotely. kind "linux_machine" (a server or the machine an agent runs on): returns the exact commands to run as root on that machine; it makes its own key and registers itself, and can then be moved, rotated and switched with the other tools. Uses one device slot (see get_account). Needs an admin-scope token for phone_or_computer.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | phone_or_computer: WireGuard app on a phone or laptop. linux_machine: a Linux server or agent machine running the Portveil agent | |
| name | Yes | Display name for the new device, e.g. "Miguel iPhone" or "scraper-box" | |
| folder | No | phone_or_computer only: folder to save the tunnel files in. Default ~/Portveil/<name> | |
| split_tunnel | No | linux_machine only: default true, so a remote server keeps its SSH session. false sends all of its traffic through Portveil | |
| temporary_minutes | No | phone_or_computer only: delete the device automatically after this many minutes (5 to 43200, i.e. 30 days). Omit for a permanent device |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only readOnlyHint=false, but the description goes further: it states the device is created immediately, a WireGuard tunnel file is saved per location with a locally generated private key, the key is never shown in replies, and linux_machine devices self-register and can later be moved/rotated. It also discloses the device-slot consumption and the admin token need. This is thorough disclosure beyond annotations with no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat long but every clause earns its place—two device kinds, file handling, key security, device-slot cost, and token requirement. It is logically organized by kind, with prerequisites and outcomes stated clearly. Not overly terse, but justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the essential operational facts: what each kind produces (files vs. commands), the key generation and privacy, the view-only constraint for phone_or_computer, and the admin token requirement. It omits the exact return shape, but since no output schema exists, a brief note on the return (e.g., the commands or success message) would have been slightly more complete. Still, it covers the critical usage context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description enriches each parameter: it maps 'kind' to concrete device types, explains 'folder' as the save location with a default, clarifies 'split_tunnel' behavior (keeps SSH for remote servers), and defines 'temporary_minutes' with automatic deletion semantics. This adds meaning the schema alone doesn't convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Add a new device to the account') and then splits into two clearly defined kinds ('phone_or_computer' and 'linux_machine') with distinct behaviors, outcomes, and prerequisites. This distinguishes it from sibling tools like move_device or rotate_device, which address different lifecycle operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit conditions for each kind: phone_or_computer for WireGuard apps on mobile/desktop, linux_machine for servers or agent machines. It also notes the admin-scope token requirement and that these devices are view-only until switched. It doesn't explicitly name alternatives like update_device or remove_device, but the use context for this creation tool is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disconnect_deviceDisconnect deviceADestructiveIdempotent
Turn off a device's VPN tunnel. Its traffic stops going through Portveil (and loses VPN protection) until it reconnects. The device stays on the account. Confirm with the user first. Needs a control-scope token and a Portveil-agent device.
| Name | Required | Description | Default |
|---|---|---|---|
| device | Yes | Which device: its name, a unique part of its name (e.g. "scraper"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint and idempotentHint annotations, the description explains the security impact (loses VPN protection), that the device remains on the account, and the prerequisites (control-scope token, Portveil-agent device). It also instructs to confirm with the user, which is critical operational guidance not covered by annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each carrying distinct, necessary information: the action, the effect on traffic, persistence of the device, user confirmation, and prerequisites. No redundancy, and the primary action is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter mutation with no output schema, the description covers the action, its consequence, the device's persistence, the need for user confirmation, and authentication prerequisites. Nothing essential for an agent to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully documents the 'device' parameter with type, description of accepted formats (name, partial, ID), case-insensitivity, and reference to list_devices. Schema coverage is 100%, and the tool description does not add parameter-specific details beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Turn off' and the resource 'device's VPN tunnel', and distinguishes it from remove_device by noting 'device stays on the account' and from reconnect_device with 'until it reconnects'. The purpose is unambiguous and well-differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: it is for temporary disconnection (traffic stops until reconnect) and instructs to confirm with the user first, which is important for a destructive action. It does not explicitly name alternative tools, but the 'stays on the account' note clarifies it is not removal, giving clear guidance without explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_accountGet accountARead-only
Get the account's plan and how many devices it uses out of its limit. Use it when asked about the plan or before suggesting adding devices. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already marks this as safe, and the description's 'Read-only' restates that rather than adding new behavioral context. It does not disclose auth requirements, rate limits, or response shape details, but with annotations covering the safety profile, a mid score is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences deliver the purpose, output summary, usage trigger, and safety trait without any wasted words. The key scoped information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read-only tool with annotations already covering safety, the description fully states what the agent will learn (plan and device usage against limit) and when to call it. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema coverage is 100%, so there is no parameter ambiguity. The description adds useful context about what the result will contain, which is sufficient for an empty-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb, resource, and output: getting the account's plan and device usage against its limit. It is clearly distinct from the sibling tools, which all operate on devices or activities.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use the tool: when asked about the plan or before suggesting adding devices. This gives the agent actionable selection criteria without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_deviceGet deviceARead-only
Get one device's current state: online or offline, the location it exits from, whether that exit server confirms the tunnel, its live speed, any rotation schedule, and when it last reported. Use it to check a device before or after an action. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| device | Yes | Which device: its name, a unique part of its name (e.g. "scraper"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint true, the description discloses that the state is current and 'live', that tunnel confirmation is from the exit server, and that the report includes a last-reported timestamp, which warns of potential staleness. It does not cover error behavior (e.g., unknown device), but the annotations already cover the safety profile, so the added field-level context earns a 4.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A compact two-sentence description, front-loaded with the operation and scope. Every clause adds value: the field list, the use context, and the read-only note. No redundancy (though 'Read-only' echoes the annotation, it's one word and harmless).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only tool with 100% schema coverage and no output schema, the description provides a full inventory of returned information. The combination of annotations, schema, and field list leaves no critical gap for an agent deciding to call it. The only missing piece is detailed error semantics, which is low-value here.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema's device parameter description is thorough: name, unique part of name, or dev_ ID, case-insensitive, and where to get values (list_devices). The tool description adds no additional parameter semantics, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Get one device's current state' — a specific verb ('Get') plus a clear resource and scope ('one device'). It enumerates the exact state fields (online/offline, exit location, tunnel confirmation, speed, rotation schedule, last reported), which clearly differentiates this from siblings like list_devices or get_account. The 'Read-only' tag reinforces its role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use it to check a device before or after an action,' giving a concrete when-to-invoke context. It stops short of naming alternatives or stating when not to use it, but the singular-device framing and read-only note imply it's for inspection rather than enumeration or modification.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_activityList activityARead-only
List recent actions on the account (moves, reconnects, rotations, renames, tokens created), newest first, with the token that made each. Use it to answer "what changed?" or to audit an assistant's actions. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many entries to return, newest first (1–100, default 20) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, and the description adds useful behavioral context: results are newest first, each entry is attributed to the token that performed the action, and the scope is recent account-level events. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences carry all the essential information with no filler. The first sentence defines the output and ordering, and the second provides actionable use cases, keeping the definition tight and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only listing tool with one optional parameter and no output schema, the description covers what is returned, the ordering, the attribution, and when to use it. An agent has enough detail to invoke and interpret the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%; the only parameter, limit, is fully documented with range, default, and ordering semantics. The description does not add extra parameter nuance, but none is needed given the schema's completeness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource ('actions on the account') and enumerates the kinds of activity covered: moves, reconnects, rotations, renames, and token creation. It also clarifies ordering and attribution, so an agent can distinguish it from the device/location/account siblings, none of which are audit-style tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit use cases: answering 'what changed?' and auditing an assistant's actions. It does not state exclusions or alternative tools, but no sibling serves the same purpose, so the explicit context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_devicesList devicesARead-only
List every device on the Portveil account, one line each: whether it's protected (connected AND confirmed by the exit server), which country it exits from, its live download/upload speed while connected, and whether it accepts remote control. Use this first to see what's there or to find a device's exact name; use get_device for one device. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the read-only nature is known. The description adds value by disclosing the output content (one line per device with protected status, exit country, speeds, remote control acceptance) and confirming it is read-only, which goes beyond the annotation's generic safety signal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no fluff. The first sentence states the purpose and scope, the second provides usage guidance. All information is front-loaded and every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with no parameters and no output schema, the description covers the essential aspects: what it lists, the fields returned, and when to use it. It does not mention edge cases like pagination or authentication, but these are not critical for a simple listing operation and are not expected given the annotation coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema coverage is trivially 100%. With no parameters to describe, the baseline is 4; the description does not need to add parameter semantics since there are none.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'List' and the resource 'every device on the Portveil account', and enumerates the specific fields returned (protected status, country, speeds, remote control). It also distinguishes itself from get_device by explicitly naming it for single-device lookups, so an agent can tell them apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit guidance: 'Use this first to see what's there or to find a device's exact name; use get_device for one device.' This names the alternative and the condition that selects it, leaving no ambiguity about when to invoke this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_locationsList locationsARead-only
List the exit locations (country, city and location ID) that devices can be moved to. Use it before move_device or start_rotation when you're unsure what's available. Every plan can use every location. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the description's 'Read-only' aligns without adding much there. However, it adds useful context beyond annotations: the exact contents of the list (country, city, location ID) and the fact that all plans can use all locations – a domain-level behavioral detail not captured in structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose, then the usage guidance and read-only note. Every word earns its place; no filler or repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only listing tool, the description fully covers what an agent needs: what the list contains, when to call it, and that it's safe. No output schema exists, but the description names the returned fields explicitly, so nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema is trivially 100% covered. No parameter explanation is needed; the description correctly focuses on the output and usage. Baseline of 4 applies for no-param tools, and the description adds no redundant param noise.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List'), a specific resource ('exit locations'), and the exact fields returned (country, city, location ID). Also explicitly ties its purpose to the siblings move_device and start_rotation, making it easy to distinguish from other listing tools like list_devices.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs when to use it ('before move_device or start_rotation when you're unsure what's available') and adds a universal applicability note ('Every plan can use every location'). This gives clear direction and removes ambiguity about prerequisites or validity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
move_deviceMove deviceAIdempotent
Move a device's traffic to exit from a chosen location. Waits until the device switches and the new exit server confirms it (usually 10–30 s), and says plainly if that didn't happen. Safe to repeat: moving to where it already is does nothing. Only works on machines running the Portveil agent with remote control on (phones using the WireGuard app switch on the device itself). Needs a control-scope token. To just go somewhere different, use rotate_device.
| Name | Required | Description | Default |
|---|---|---|---|
| device | Yes | Which device: its name, a unique part of its name (e.g. "scraper"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices. | |
| location | Yes | Where to exit: a country, city or region ("Finland", "US", "Helsinki") or a location ID from list_locations (e.g. srv-eu-1) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal idempotency and non-destructiveness; the description reinforces this with 'moving to where it already is does nothing' and adds timing, success/failure reporting, and prerequisites such as the agent requirement and token scope. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence serves a purpose: action, wait/result behavior, idempotency, prerequisites, alternative. The main action is front-loaded, and no filler exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers prerequisites, expected behavior, failure reporting, idempotency, and alternative routing. The input schema documents both parameters fully, and no output schema exists, so the description's statement about clearly saying if the switch didn't happen is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed descriptions for both device and location, so the description doesn't need to add parameter-level detail. It adds the high-level semantic that location is the desired exit, which maps to the schema's 'Where to exit' description, but provides no additional syntax or formatting clues.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Move a device's traffic to exit from a chosen location') and explicitly differentiates from rotate_device, so an agent can distinguish purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when the tool works ('Only works on machines running the Portveil agent with remote control on'), what it needs ('control-scope token'), and names rotate_device as the alternative for simply choosing a different location.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reconnect_deviceReconnect deviceAIdempotent
Tell a device to re-establish its VPN tunnel at its current location, without moving it. Use when it shows connected but not confirmed, or traffic seems stuck. Traffic may pause for a few seconds. Needs a control-scope token and a Portveil-agent device.
| Name | Required | Description | Default |
|---|---|---|---|
| device | Yes | Which device: its name, a unique part of its name (e.g. "scraper"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses a transient side effect ('Traffic may pause for a few seconds') and required preconditions ('control-scope token' and 'Portveil-agent device'). This is exactly the kind of behavioral context a calling agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four concise sentences, each carrying necessary information: what it does, when to use it, what to expect, and what prerequisites are required. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with complete schema coverage and helpful annotations, the description covers the action, conditions, side effects, and requirements. Nothing essential is missing for an agent to decide whether and how to call it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage for the only parameter is 100%, and the schema already richly explains the device field. The description doesn't add much to parameter semantics, but it doesn't need to because the schema handles it fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear, specific action: 're-establish its VPN tunnel at its current location.' This distinguishes the tool from siblings like move_device, disconnect_device, and rotate_device, making its unique purpose immediately obvious.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use the tool: 'when it shows connected but not confirmed, or traffic seems stuck.' It also clarifies a key boundary by adding 'without moving it,' which helps an agent avoid confusing this with move_device.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_deviceRemove deviceADestructive
Permanently remove a device from the account: its VPN key stops working at every exit and its slot is freed. It can't be undone; the device would have to be set up again. Confirm with the user first, naming the device. Needs an admin-scope token.
| Name | Required | Description | Default |
|---|---|---|---|
| device | Yes | Which device: its name, a unique part of its name (e.g. "scraper"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true, but the description adds meaningful specifics: the VPN key stops working at every exit, the slot is freed, the action cannot be undone, and the device must be set up again. It also adds confirmation and auth requirements not present in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: the operation and its effects, irreversibility, and required user confirmation/auth. No filler or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter destructive tool with no output schema, the description covers the essential operational context: consequences, irreversibility, confirmation, and auth scope. Nothing an agent needs to decide to call it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the device parameter thoroughly (name, unique part, ID, case-insensitivity, source via list_devices), so the description does not need to repeat it. The description's 'naming the device' note aligns with the parameter but adds no new semantic detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('permanently remove') and resource ('device from the account'), and clarifies it is a destructive operation distinct from siblings like disconnect_device or update_device. The consequence ('VPN key stops working... slot freed') reinforces what the tool uniquely does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to confirm with the user first and to name the device, and notes the admin-scope token requirement. It does not name alternative tools or state when not to use it, but the context is clear enough for an agent to apply it to permanent removal scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rotate_deviceRotate deviceA
Move a device once to the next location in the list, so its traffic exits from somewhere new. Same checks and waiting as move_device. Each call moves again, so it isn't idempotent. For repeated automatic moves use start_rotation instead. Needs a control-scope token.
| Name | Required | Description | Default |
|---|---|---|---|
| device | Yes | Which device: its name, a unique part of its name (e.g. "scraper"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=false, readOnlyHint=false, and destructiveHint=false, but the description adds meaningful context by explaining non-idempotence ('Each call moves again, so it isn't idempotent') and the token requirement, which is beyond annotation coverage. It references sibling behavior ('Same checks and waiting as move_device') but does not detail those checks, which is a minor gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three concise sentences with the core scoping information ('Move a device once to the next location') front-loaded. Every sentence adds value: behavior, non-idempotence, alternative, and auth requirement. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with no output schema, the description covers purpose, usage distinction, behavioral caveats, and auth needs. It is sufficiently complete for an agent to invoke it correctly without additional documentation, especially given the high schema coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already fully documents the 'device' parameter (name, unique part, ID, case-insensitive). The description does not add new parameter-level meaning beyond what the schema provides, so it meets the baseline of 3 but does not exceed it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Move a device once to the next location in the list, so its traffic exits from somewhere new,' which is a specific verb, resource, and behavioral scope. It clearly differentiates from siblings like move_device (which likely moves to a specified location) and start_rotation (repeated automatic moves) by explicitly contrasting them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance: 'Same checks and waiting as move_device' and 'For repeated automatic moves use start_rotation instead.' It also notes the authentication requirement ('Needs a control-scope token'), giving clear when-to-use and when-not-to-use context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_rotationStart rotationAIdempotent
Make Portveil move a device to the next location automatically every N minutes, optionally cycling through chosen locations only. Portveil runs the schedule itself, so the assistant doesn't need to stay running. Calling it again replaces the schedule. Stop it with stop_rotation. Needs a control-scope token and a Portveil-agent device.
| Name | Required | Description | Default |
|---|---|---|---|
| device | Yes | Which device: its name, a unique part of its name (e.g. "scraper"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices. | |
| locations | No | Locations to cycle through, e.g. ["US", "Finland"]; at least two. Omit to cycle through every location. | |
| every_minutes | Yes | Minutes between moves: 5 to 10080 (one week) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations. It discloses that the tool is a mutating operation (readOnlyHint=false), but also that it is idempotent (idempotentHint=true) by explicitly stating 'Calling it again replaces the schedule'. It also adds important behavioral details: the requirement for a control-scope token and a Portveil-agent device, and that the schedule runs independently of the assistant. This is valuable context not captured in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences long, each adding essential information: the core action, the autonomy of the scheduler, the replaceable nature, and the stopping mechanism plus requirements. It is front-loaded with the primary purpose and contains no filler or redundant phrasing. Every sentence earns its place, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with three parameters, no output schema, and relatively simple behavior, the description covers the essential context: purpose, scheduling behavior, replacement semantics, stopping, and prerequisite requirements. It does not detail error handling or what happens with invalid inputs, but these are minor gaps. The description is complete enough for an agent to correctly invoke the tool in most scenarios, though it could optionally mention the distinction from immediate move tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides comprehensive descriptions for all three parameters (device, locations, every_minutes), with 100% coverage. The tool description does not add additional parameter-specific meaning beyond what the schema provides. For example, the schema already explains the range for every_minutes and the optional nature of locations. Therefore, the description adds no extra semantic value for parameters, matching the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Make Portveil move a device to the next location automatically every N minutes'. It specifies the verb (move), resource (device), and the automation aspect (every N minutes). It also distinguishes itself by mentioning 'Calling it again replaces the schedule' and 'Stop it with stop_rotation', which sets it apart from immediate move tools. The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on when to use the tool: for scheduling periodic moves. It explains that Portveil runs the schedule itself, so the assistant doesn't need to stay running, and that calling again replaces the schedule. It also names stop_rotation as the way to stop. However, it does not explicitly contrast with sibling tools like rotate_device or move_device, leaving some ambiguity for an agent choosing between them. Thus, it has clear context but lacks explicit exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop_rotationStop rotationAIdempotent
Turn off a device's automatic rotation. The device stays at its current location. Safe to call when no rotation is set. Needs a control-scope token.
| Name | Required | Description | Default |
|---|---|---|---|
| device | Yes | Which device: its name, a unique part of its name (e.g. "scraper"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses that the device stays at its current location, that calling it when no rotation is set is safe, and that a control-scope token is required. These are meaningful behavioral and prerequisite details not present in the annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: the action, the location behavior, the safety condition, and the auth requirement. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with rich schema coverage and annotations covering idempotency and destructiveness, the description adds the missing auth requirement and clarifies the no-op behavior. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents the device parameter. The description does not add parameter-specific meaning, but it does not need to; the baseline of 3 applies because the schema carries the semantic weight.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Turn off a device's automatic rotation.' This clearly distinguishes it from siblings like start_rotation and rotate_device, and the added 'device stays at its current location' disambiguates it from move_device.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when the tool is appropriate, including that it is safe to call when no rotation is set and that a control-scope token is required. It does not explicitly name alternatives or when-not-to-use conditions, but the usage context is clear enough for an agent to select it correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_deviceUpdate deviceAIdempotent
Rename a device and/or turn remote control on or off for it. Turning remote control off stops move, rotate, reconnect and disconnect for that device until it's turned back on. Change only what's given; safe to repeat. Needs an admin-scope token.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | New display name, 1–64 characters | |
| device | Yes | Which device: its name, a unique part of its name (e.g. "scraper"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices. | |
| remote_control | No | true lets tokens move and control this device; false blocks it |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by explaining that turning remote control off stops move, rotate, reconnect, and disconnect until turned back on. It also discloses partial-update semantics ('Change only what's given') and the admin-scope requirement, adding meaningful operational context that annotations do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences with no filler. It front-loads the core purpose, then adds the most important behavioral caveat, idempotency reassurance, and auth requirement. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter mutation tool with rich annotations and a fully documented input schema, the description covers everything an agent needs: required device identification, optional fields, side effects, repeatability, and access level. No return schema exists, but none is necessary for this kind of update operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents each parameter. The description adds value by clarifying partial-update behavior for the optional parameters and explaining the real-world effect of remote_control=false. This enriches the bare schema definitions without repeating them.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs and resources: 'Rename a device and/or turn remote control on or off for it.' This clearly distinguishes it from siblings like remove_device, move_device, and disconnect_device, which have different actions even though they also target devices.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: to rename a device or toggle remote control. It also states the admin-token requirement and notes the operation is safe to repeat. It does not explicitly name sibling alternatives or state when not to use it, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.4.1- Added
add_device
14 tool updates
v0.3.0- Removed
account_info - Removed
device_status - Changed
disconnect_device1 field changed- changed
Input schema / properties / device / descriptionPrevious value: -"Device name (or part of it, e.g. \"scraper\") or its device ID (dev_…)"New value: +"Which device: its name, a unique part of its name (e.g. \"scraper\"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices."
- Added
get_account - Added
get_device - Added
list_activity - Changed
move_device2 fields changed- changed
Input schema / properties / device / descriptionPrevious value: -"Device name (or part of it, e.g. \"scraper\") or its device ID (dev_…)"New value: +"Which device: its name, a unique part of its name (e.g. \"scraper\"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices." - changed
Input schema / properties / location / descriptionPrevious value: -"Where to exit: a country or city (\"Finland\", \"US\", \"Helsinki\") or a location ID (srv-eu-1)"New value: +"Where to exit: a country, city or region (\"Finland\", \"US\", \"Helsinki\") or a location ID from list_locations (e.g. srv-eu-1)"
- Removed
recent_activity - Changed
reconnect_device1 field changed- changed
Input schema / properties / device / descriptionPrevious value: -"Device name (or part of it, e.g. \"scraper\") or its device ID (dev_…)"New value: +"Which device: its name, a unique part of its name (e.g. \"scraper\"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices."
- Added
remove_device - Changed
rotate_device1 field changed- changed
Input schema / properties / device / descriptionPrevious value: -"Device name (or part of it, e.g. \"scraper\") or its device ID (dev_…)"New value: +"Which device: its name, a unique part of its name (e.g. \"scraper\"), or its device ID (dev_…). Case-insensitive. Get names and IDs from list_devices."
- Added
start_rotation - Added
stop_rotation - Added
update_device
9 tool updates
v0.1.1- First observed
account_info - First observed
device_status - First observed
disconnect_device - First observed
list_devices - First observed
list_locations - First observed
move_device - First observed
recent_activity - First observed
reconnect_device - First observed
rotate_device
TDQS
Scored across 14 tools
Each tool maps to a distinct resource-action pair: device, account, activity, location, and rotation each have dedicated operations. The only close pair is move_device vs rotate_device, but their descriptions explicitly separate choosing a location from picking the next one.
All tool names follow a consistent verb_noun snake_case pattern, with verbs like get, list, add, update, remove, move, rotate, start, stop, reconnect, and disconnect. This makes the full surface predictable and easy to navigate.
Fourteen tools is well within the ideal range and appropriate for a VPN/device-management domain. Each tool covers a meaningful operation without redundant utilities or excessive granularity.
The toolset covers the full device lifecycle (add, get, list, update, remove) plus operational controls (move, rotate, reconnect, disconnect, start/stop rotation) and account/location/activity reads. No obvious dead ends or missing operations for the apparent domain.
Maintenance
Related MCP Connectors
Device intelligence for AI agents: Fingerprint events, smart signals, and API key management.
Give AI agents secure access to RevDesk calling, SMS, phone numbers, caller IDs, and usage.
- mcp-serverOAuthcom.make
Give your AI agents the tools to build, manage, and run automation workflows.
- mcpOAuthcom.vibgrate
Query your team's drift, vulnerability, and upgrade data from any AI assistant. OAuth 2.1, 51 tools.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables AI assistants to control mobile and desktop devices with natural language, including running automation tasks, taking screenshots, and managing devices.65 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Fleet Device Management for device management, security monitoring, and compliance enforcement through the Model Context Protocol.5MIT
- AlicenseAqualityBmaintenanceEnables AI agents to securely interact with Tailscale tailnets for device inventory, ACL review, key hygiene, and more, with token-efficient output and write-gated mutations.19MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage agents, webhooks, and P2P connectivity on the Anycast network, allowing operations like listing agents, creating tokens, and viewing connection stats.7 npmMIT