twingate-mcp
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., "@twingate-mcplist all resources and their remote network names"
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.
twingate-mcp
A read-only MCP server that lets Claude (or any MCP client) answer questions about a Twingate network: users, groups, resources, remote networks, connectors, devices, and who can access what. It never creates, changes, or deletes anything.
One server process talks to one Twingate network with one API token.
1. Create a read-only API token
In the Twingate Admin Console go to Settings → API, generate a token, and choose the Read-only permission. Treat it like a password.
Related MCP server: Google Ads MCP Server
2. Install
git clone <this repo> && cd twingate-mcp
uv sync
cp .env.example .env # then fill in TWINGATE_NETWORK and TWINGATE_API_KEY
uv run twingate-mcp versionTWINGATE_NETWORK is everything before .twingate.com: for acme.twingate.com use acme; for a regional tenant such as acme.us1.twingate.com use acme.us1.
Variable | Default | Notes |
| required | Host before |
| required | Read-only token recommended |
|
| 1–100 |
|
| Items per tool call when |
|
| Hard cap per tool call |
|
| Per request |
|
| |
| unset | Required for non-loopback HTTP |
| unset | Extra comma-separated hostnames accepted in |
|
|
|
3. Use with Claude Desktop (stdio)
Add this to claude_desktop_config.json:
{
"mcpServers": {
"twingate": {
"command": "uv",
"args": ["run", "--directory", "/path/to/twingate-mcp", "twingate-mcp", "serve", "--transport", "stdio"],
"env": {
"TWINGATE_NETWORK": "acme",
"TWINGATE_API_KEY": "<your read-only token>"
}
}
}
}4. Streamable HTTP
uv run twingate-mcp serve --transport http # 127.0.0.1:8000, endpoint /mcpBinding to anything other than a loopback address fails unless TWINGATE_MCP_HTTP_TOKEN is set.
With it set, every request must send Authorization: Bearer <token>. DNS-rebinding protection only
accepts Host headers matching the bind address.
Security caveat: the bearer token is a single shared secret, not user authentication. Anyone holding it can read everything the Twingate API token can read. Use HTTPS in front of it (a reverse proxy) and don't expose it to the internet.
5. Docker
The image runs as a non-root user and contains only the runtime virtualenv. .env and the schema
are excluded from the build context.
docker build -t twingate-mcp:local .stdio (Claude Desktop): use docker as the command:
"twingate": {
"command": "docker",
"args": ["run", "-i", "--rm", "--env-file", "/path/to/twingate-mcp/.env", "twingate-mcp:local"]
}HTTP (Compose): add TWINGATE_MCP_HTTP_TOKEN to .env (generate one with
openssl rand -hex 32), then:
docker compose up -d # http://localhost:8000/mcp, published on 127.0.0.1 onlyInside the container the server binds 0.0.0.0, so the bearer token is mandatory. It accepts
localhost and 127.0.0.1 Host headers; put a TLS reverse proxy in front before exposing it beyond
the local machine.
Tools
All tools are read-only. List tools take an optional limit (default TWINGATE_DEFAULT_LIMIT,
capped at TWINGATE_MAX_LIMIT) and return {items, total_returned, truncated}.
Tool | Input | Returns |
|
| id, email, first/last name, role, state |
|
| One user or null |
|
| id, name, type, active, member count |
|
| id, name, address, remote network name, active |
|
| id, name, location, active, connector count |
|
| id, name, remote network, state, last heartbeat |
|
| id, name, OS, user email, trust status, last seen |
|
| Groups and service accounts with access |
|
| The user's groups and resources reachable through them |
From a terminal: uv run twingate-mcp call list_users --arg limit=5.
Contributing: data-safety rules
This repo must never contain company or tenant data.
Test data is synthetic: seeded polyfactory/Faker factories (
tests/factories.py) usingsafe_*providers, or small hand-written JSON intests/fixtures/with values likealice@example.comand theacme-testnetwork. Never use Faker's plainemail(),domain_name(), orhostname().Never record or paste real API responses. No VCR/cassette/record-mode libraries.
No real network names, emails, hostnames, or IDs anywhere: code, tests, docs, commit messages.
.envandschema/twingate.graphqlare gitignored. Pull the schema from a personal or trial tenant, never an employer tenant.Log operation names, durations, and status codes only, never bodies or headers.
gitleaksruns in pre-commit (uv run pre-commit install).tests/test_data_safety.pyfails on non-example.*domains or non-allowlisted network names.Only
queryoperations are allowed inqueries/; a test enforces it.
Quality gates: uv lock --check, uv run ruff check ., uv run ruff format --check .,
uv run pyright, uv run pytest --cov=twingate_mcp --cov-fail-under=85, the pip-licenses
command in the spec, and gitleaks detect --no-banner.
License
MIT, see LICENSE.
Available Tools
9 toolsget_resource_accessARead-onlyIdempotent
Show which groups and service accounts have access to one resource (by resource id
from list_resources). If truncated is true the principal list is incomplete.
| Name | Required | Description | Default |
|---|---|---|---|
| resource_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| resource | Yes | |
| truncated | Yes | |
| principals | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint and non-destructiveness, so safety is covered. The description adds real behavioral value beyond them by disclosing the truncation condition and that 'truncated' being true means the principal list is incomplete — a caveat an agent must act on. It stops short of noting permission requirements or that only groups/service accounts (not users) appear.
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, no filler, with the core purpose front-loaded and the truncation caveat appended where it belongs. 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?
An output schema exists, so return structure needn't be explained, and the description still flags the truncated field's meaning. What remains unsaid is that principals here are limited to groups/service accounts and that get_user_access covers the user-centric view — minor, but useful routing context for an access-audit workflow.
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 0%, so the description carries the burden for the single parameter, and it does: resource_id is identified as a resource identifier sourced from list_resources. That is the meaningful semantic detail the bare string schema lacks; only format/example syntax is absent.
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 ('Show'), resource ('which groups and service accounts have access'), and scope ('one resource'), which is distinct from the sibling get_user_access (which pivots on a user) and from list_resources. An agent can pick this tool without opening the schema.
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 tells the agent where the required resource_id comes from ('by resource id from list_resources'), which is the key prerequisite. It does not explicitly name get_user_access as the alternative when starting from a principal rather than a resource, so the inverse-use case is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_userARead-onlyIdempotent
Look up one Twingate user by exact email. Returns null if no user has that email.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds the not-found contract ('Returns null if no user has that email'), which is meaningful behavior an agent must handle and which is not expressed in 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, both front-loaded and informative — the lookup scope first, then the not-found behavior. No filler and nothing repeated from the schema or annotations.
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 lookup with an output schema, the description covers identity, matching semantics, and not-found behavior, which is nearly everything needed. Minor gaps are permissions or error behavior, which are less critical for a read-only lookup.
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 0%, so the description needs to carry parameter meaning. It does the single most important thing: it specifies exact-match semantics for the email parameter, telling the agent it cannot pass partial or fuzzy values.
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?
Specific verb ('look up') plus a precise resource ('one Twingate user') and a scoping constraint ('by exact email'). The singular 'one user by email' implicitly separates it from the sibling list_users tool, which returns many users.
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 tool implies its use case ('look up one user by exact email'), but there is no explicit statement about when to use it versus list_users or get_user_access. The 'exact email' constraint hints that partial-match cases need a different tool, but that is inference, not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_accessARead-onlyIdempotent
Show a user's groups and the resources reachable through those groups.
Use to answer "what can this person reach?". If truncated is true lists are partial.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| Yes | ||
| groups | Yes | |
| resources | Yes | |
| truncated | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=true, idempotent=true, destructive=false, so safety is covered. The description adds real value beyond that by disclosing truncation behavior ('If `truncated` is true lists are partial'), which an agent otherwise wouldn't know from the schema alone.
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, front-loaded with the core operation, then the selection cue, then the truncation caveat. Nothing redundant.
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?
With an output schema present, return values need not be explained, and the truncation note usefully covers partial results. The only missing piece is email semantics for the lone required parameter, a minor but real gap for a 1-param tool.
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 0% for the single required `email` parameter, so the description must compensate. Saying 'a user's groups' implies the email identifies the user, but it never states the format, case sensitivity, or whether it must be an exact registered address, leaving a real gap.
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 ('Show') and resource ('a user's groups and the resources reachable through those groups'), making it distinguishable from siblings like get_user (profile) and get_resource_access (reverse direction). The phrase 'reachable through those groups' precisely bounds the scope.
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 frames the use case: 'Use to answer "what can this person reach?"', which gives a clear selection signal versus get_user or list_* tools. No explicit when-not-to-use clause or named alternative, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_connectorsARead-onlyIdempotent
List connectors: id, name, remote network, state (online/offline), last heartbeat.
Use to check connector health.
Results are capped by limit; if truncated is true, more existed than were
returned, so do not treat the list as complete.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum items to return (server default if omitted). |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| truncated | Yes | |
| total_returned | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive behavior, but the description adds meaningful operational context: results are capped by `limit` and a `truncated` flag means the list is incomplete. It does not explain how to retrieve additional results, but the truncation warning is valuable beyond 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?
The description is three efficient sentences: purpose and return fields first, then usage context, then the truncation caveat. Every sentence earns its place and the most important 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 simple read-only list tool with an output schema and full schema coverage, the description provides sufficient context: what it lists, when to use it, and how to interpret truncated results. Nothing essential is missing for correct invocation.
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% and the `limit` parameter is already documented in the schema. The description adds semantic value by explaining the consequence of `limit` and how the `truncated` result should be interpreted, going beyond the raw parameter definition.
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 (list connectors) and enumerates the fields returned, so an agent can understand what it does without opening the schema. It does not explicitly distinguish itself from sibling tools like list_remote_networks or list_devices, but the resource name is distinct enough for clear selection.
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 to use the tool to check connector health, giving a clear usage context. It does not name alternatives or exclusions, which keeps it below the top score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_devicesARead-onlyIdempotent
List devices: id, name, OS, owning user's email, trust status, and last seen time.
Results are capped by limit; if truncated is true, more existed than were
returned, so do not treat the list as complete.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum items to return (server default if omitted). |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| truncated | Yes | |
| total_returned | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, so safety is covered. The description adds genuinely useful behavior beyond that: results are capped by `limit` and `truncated=true` means the list is incomplete, a caveat an agent would otherwise miss.
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 tight sentences: the first front-loads the field inventory, the second delivers the truncation caveat. No wasted wording and no repetition of schema or annotations.
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?
With annotations covering the safety profile, an output schema present, and the sole parameter fully documented, the main remaining gap an agent needed was the truncation caveat, which is provided. Nothing essential is missing, though it could note what 'trust status' values mean.
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 baseline is 3, but the description goes further by explaining what the limit does in practice (caps results) and tying it to the truncated signal. That clarifies the meaning of an otherwise generic 'Maximum items to return' parameter.
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 ('List devices') and enumerates the fields returned (id, name, OS, owner email, trust status, last seen), so an agent knows exactly what it gets. It doesn't explicitly contrast with siblings like list_users or get_user, but the resource noun makes selection 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?
Usage is only implied by the verb 'List' and the field list; there's no statement of when to prefer this over get_user or when-not to call it. Adequate for a simple sibling list but no explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_groupsARead-onlyIdempotent
List Twingate groups: id, name, type, whether active, and member count.
Results are capped by limit; if truncated is true, more existed than were
returned, so do not treat the list as complete.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum items to return (server default if omitted). |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| truncated | Yes | |
| total_returned | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so safety is covered. The description adds the genuinely useful disclosure that the result set may be silently capped and how to detect it via `truncated` — behavior an agent could not infer from 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?
Two tight sentences: the first enumerates content, the second front-loads the truncation caveat. No filler, nothing repeated from structured fields beyond a brief field list.
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-optional-parameter read tool with full annotation coverage and an output schema, this is enough: the only non-obvious risk (incomplete results) is explicitly called out, and return-value details are delegated to the output schema.
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% and `limit` is already documented there as 'Maximum items to return (server default if omitted).' The description reinforces the capping semantics but adds no syntax or default details beyond the schema, so the documented-schema baseline of 3 applies.
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?
Opens with a specific verb+resource ('List Twingate groups') and names the fields returned (id, name, type, active, member count), which immediately separates it from the sibling list_users / list_resources / list_connectors tools. An agent can select it without opening the schema.
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 clear operational guidance: results are capped by `limit`, and if `truncated` is true the caller must not treat the list as complete. It stops short of naming alternatives or stating exclusions (e.g. when to use list_users instead), so it's clear context without explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_remote_networksARead-onlyIdempotent
List remote networks: id, name, location, whether active, and connector count.
Results are capped by limit; if truncated is true, more existed than were
returned, so do not treat the list as complete.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum items to return (server default if omitted). |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| truncated | Yes | |
| total_returned | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered; the description adds real value beyond that by disclosing result capping and the meaning of `truncated` — a behavioral trait no annotation conveys. It stops short of saying how to retrieve the remainder, but the truncation warning is the key operational fact.
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 what is returned, then the truncation caveat. Every clause carries information; nothing is repeated from the schema or annotations.
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?
An output schema exists, so field-level return documentation isn't required, and the description still summarizes the key fields while covering the one optional parameter's effect. The only gap is that it doesn't suggest what to do when `truncated` is true (e.g., raise `limit`), so an agent must infer the next step.
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% and `limit` is already documented there as 'Maximum items to return', so baseline would be 3. The description goes further by explaining the consequence of `limit` (results are capped) and the resulting `truncated` signal, which gives the parameter meaning the schema doesn't.
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?
Names a specific verb (List) and resource (remote networks) and even enumerates the fields returned (id, name, location, active, connector count). It doesn't differentiate from list_resources/list_connectors beyond the name, but the resource noun is distinct enough that an agent can tell them apart.
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?
Usage is only implied — an agent gathers that this is the way to enumerate remote networks. The description does give actionable guidance on interpreting results (limit capping, truncated flag), but never states when to prefer this over sibling list_* tools or any prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_resourcesARead-onlyIdempotent
List Twingate resources: id, name, address, remote network name, and whether active.
Use get_resource_access with an id to see who can reach one.
Results are capped by limit; if truncated is true, more existed than were
returned, so do not treat the list as complete.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum items to return (server default if omitted). |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| truncated | Yes | |
| total_returned | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this as a safe, read-only, idempotent operation, so the description does not need to restate safety. It adds meaningful behavioral detail by explaining the `limit` cap and the `truncated` signal, warning that the list may be incomplete. It does not mention authentication or rate limits, but those are not essential here.
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 compact sentences, front-loaded with the resource and returned fields, then the sibling alternative, then the truncation caveat. Every sentence adds distinct information.
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 tool has an output schema, so the description need not explain return values in depth. It covers the key operational risk (truncated results) and points to the correct sibling for access inspection, making it complete for this simple list 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 `limit` parameter is already documented. The description adds value by linking `limit` to truncation behavior and warning not to treat a truncated result as complete.
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: "List Twingate resources," and enumerates the returned fields (id, name, address, remote network name, active status). It also distinguishes this tool from the sibling get_resource_access by routing access-inspection questions there.
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 names the alternative tool for a different task: "Use get_resource_access with an id to see who can reach one." It also provides a clear caution about interpreting the list when `truncated` is true, which is essential usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_usersARead-onlyIdempotent
List Twingate users: id, email, first/last name, role, and state.
Use to browse who is in the network; use get_user to look up one email.
Results are capped by limit; if truncated is true, more existed than were
returned, so do not treat the list as complete.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum items to return (server default if omitted). |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| truncated | Yes | |
| total_returned | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so safety is covered; the description adds the genuinely non-obvious behavior that results are capped and that truncated=true means the list is incomplete. It stops short of mentioning any pagination mechanism or how to retrieve the remainder, which is the one behavioral 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?
Three short sentences, front-loaded with what is returned, then routing, then the truncation caveat. No filler and every sentence carries an actionable fact.
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?
With one optional parameter, full schema coverage, an output schema, and safety annotations, the only thing left for prose to carry is the truncation gotcha — and it does. Nothing an agent needs to call this correctly or interpret the result 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 coverage is 100% and the limit param already documents the server default, so the baseline is 3. The description adds meaning by tying limit to the truncation signal, telling the agent how a small limit manifests in the response — a genuine increment over the schema text.
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 ("List Twingate users") and enumerates the fields returned (id, email, name, role, state), so the agent knows exactly what surface it gets. It also names the sibling get_user as the single-record alternative, making the distinction explicit.
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?
"Use to browse who is in the network; use get_user to look up one email" gives both the positive case and the alternative route, which is exactly the routing decision an agent needs. The caveat about truncated results further constrains how to use the output, not just when to call.
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.
9 tool updates
v0.1.0- First observed
get_resource_access - First observed
get_user - First observed
get_user_access - First observed
list_connectors - First observed
list_devices - First observed
list_groups - First observed
list_remote_networks - First observed
list_resources - First observed
list_users
TDQS
Scored across 9 tools
Each tool targets a distinct resource or a distinct direction of an access query: list_* tools each cover one entity type, get_user is the single-email lookup complement to list_users, and get_user_access (user→resources) is clearly the inverse of get_resource_access (resource→principals). Descriptions explicitly cross-reference each other to steer selection, leaving no realistic misselection risk.
Uniform verb_noun snake_case throughout: list_* for enumerations (groups, resources, users, remote_networks, connectors, devices) and get_* for targeted lookups (user, user_access, resource_access). No camelCase or vague verbs intrude.
Nine tools is well within the ideal 3-15 range and each earns its place by covering a distinct Twingate entity or access relationship. Nothing looks padded or redundant.
The read-only/audit surface is coherent and covers the main entities plus access relationships, but it is entirely queries: there are no create, update, or delete operations for users, groups, resources, or connectors, and no get_group/get_resource/get_connector single-item lookups. An agent can investigate but cannot remediate anything it discovers.
Maintenance
Related MCP Connectors
Query metrics, targets, entities, and team data in your Steep workspace via MCP.
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
XFA's remote MCP server — query device posture, compliance, policies & CVEs. Read-only.
Read-only MCP for identity resolution and write guardrails.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceProvides read-only access to TrustLayer's public API, enabling users to query and retrieve data about parties, documents, projects, and other TrustLayer entities through MCP-compatible tools.MIT
- AlicenseNot gradedqualityCmaintenanceProvides read-only access to Google Ads account data including campaigns, ad groups, keywords, and performance reports. Enables querying via GAQL through an MCP interface.MIT
- FlicenseNot gradedqualityBmaintenanceProvides read-only access to Aruba Fabric Composer inventory, network state, and VMware vCenter/vSphere visibility through MCP tools over streamable HTTP.-
- FlicenseNot gradedqualityCmaintenanceProvides read-only access to Microsoft Intune through the Microsoft Graph API, enabling MCP clients to query managed devices, apps, compliance policies, and configuration profiles.-