Skip to main content
Glama
brynj-digital

laravel-forge-readonly-mcp

laravel-forge-readonly-mcp

A read-only MCP server for the Laravel Forge API.

Point an AI assistant at your Forge infrastructure to answer questions — which server hosts a site, when it last deployed, what's in the error log, which certificates are about to expire — without giving it the ability to change anything.

It cannot deploy, restart, provision, restore, or delete. Not because it's asked not to: there is no tool for it and no code path for it. The HTTP client only issues GET, and the verb isn't a parameter anywhere.

Built on Forge's current API (https://forge.laravel.com/api). The older /api/v1 is deprecated and Forge discontinues it on 31 August 2026.

Install

npm install -g laravel-forge-readonly-mcp

Create a token in Forge → account dashboard → API. Recommended scopes are below.

Claude Code

claude mcp add forge -e FORGE_API_TOKEN=your-token -- npx -y laravel-forge-readonly-mcp

Claude Desktop / any MCP client

{
  "mcpServers": {
    "forge": {
      "command": "npx",
      "args": ["-y", "laravel-forge-readonly-mcp"],
      "env": {
        "FORGE_API_TOKEN": "your-token",
        "FORGE_ORGANIZATION": "your-org-slug"
      }
    }
  }
}

FORGE_ORGANIZATION is optional but worth setting if you have one organisation: tools can then omit the slug, and the assistant doesn't need a lookup call first.

Related MCP server: Forge MCP Server

Options

Flag

Environment variable

Default

--api-token <token>

FORGE_API_TOKEN

required

--organization <slug>

FORGE_ORGANIZATION

none — pass organization per call

--base-url <url>

FORGE_BASE_URL

https://forge.laravel.com/api

--requests-per-minute <n>

FORGE_REQUESTS_PER_MINUTE

60, matching Forge

--unsafe-allow-secrets

FORGE_UNSAFE_ALLOW_SECRETS

off — see below

Credentials come only from flags or the environment, never from a tool argument, so nothing the model says can change which token, base URL or default organisation is used.

Tools

24 named tools for the common reads, plus one escape hatch. Forge publishes 133 GET endpoints; mapping them 1:1 would cost 30–50k tokens of JSON schema in your context window before you asked anything, so the frequent paths get real tools and forge_get covers the rest against the same allowlist.

Tool

What it answers

list_organizations

Which orgs can this token see?

list_servers / get_server

Provider, region, size, PHP version, IPs, provisioning state

list_server_events

Recent Forge activity on a server — the closest thing to an audit trail

get_server_php

Installed PHP versions and the default — find servers on an EOL version

list_sites / get_site

Every site across all servers: domain, repo, PHP, deploy state

list_domains / list_certificates

Domains, aliases and SSL expiry

list_deployments / get_deployment

Deployment history: commit, author, status, duration

get_deployment_script

The commands each deploy runs

get_site_logs

Application, Nginx access or Nginx error log

get_deployment_log

Why a deploy failed — the deploy script's output. Needs site:manage-deploys

get_command_output

Output of a command run from the Commands panel

get_scheduled_job_output

Output of a cron job's last run — is the schedule actually succeeding?

get_server_event_output

Output of a Forge server event (provisioning, service restart)

get_background_process_log

Queue worker / daemon log. Needs server:create-daemons

list_scheduled_jobs

Cron jobs for a server or one site, with last-run state

list_background_processes

Daemons and queue workers, and whether they're running

get_site_integration

Is Horizon/Octane/Reverb/Pulse/Inertia/scheduler on? In maintenance mode?

list_site_commands

History of commands run from the Commands panel

list_databases

Database schemas, or users and their grants (never contents)

list_backup_configs

Is this server actually being backed up?

forge_get

Any other documented Forge GET — monitors, firewall rules, Nginx templates, recipes, teams, providers…

List tools take page_size, cursor, sort, include and filter. Cursors are never followed automatically — see rate limiting.

  • Pages hold at most 30 items. Forge caps page[size] at 30 and silently returns 30 for anything larger, so page_size is limited to 30 rather than accepting a number Forge will ignore.

  • Every list response starts with a page line, such as 30 items on this page, and MORE PAGES exist. Pass cursor "…", or 2 items. This is the last page. Forge puts the cursor at the end of the response, which on a long page is where a reader stops.

  • list_sites takes filter: {"name": "acme.com"} to find one site without paging.

  • Sites on revoked servers are marked. Forge keeps listing a revoked (archived) server's sites as installed. With include="server", list_sites and get_site add server_revoked: true to those sites, so a stale namesake is not mistaken for the live site.

  • list_deployments is newest first unless you pass sort. Forge's own default is oldest first, the wrong way round for "did my push deploy?".

Log and output tools return the tail

Forge offers no range parameter and applies no limit: one real site's application log measured 274,503 characters over 500 lines — about 69,000 tokens in a single response. So every log/output tool returns the last 200 lines by default (failures are at the end), raisable via tail_lines, and is additionally capped by character count because line counts lie — that log averaged ~550 characters per line, and one PHP stack-trace line can exceed a thousand. Anything dropped is stated at the top of the output, so a truncated log never reads as a complete one.

Forge also returns HTTP 200 in three cases where there is no log to give, each of which reads as a broken tool unless explained. All three are detected and described in the response:

  • The server's Forge access was revoked. Forge reads logs over SSH at request time, so a revoked server yields Permission denied (publickey) as the log body. The tools point you at revoked on the server.

  • The deployment's output file was pruned. Forge stores each deployment's output on the server and deletes older ones per the site's deployment_retention, so historical deployments return cat: …: No such file or directory. The deployment record itself still works.

  • The log is empty (=== Empty log file ===).

Token scopes: the part worth reading

Forge has genuine view-only scopes, so a token can be minted that is incapable of writing. These five reach 76 of the 120 endpoints this server exposes (plus 13 more that need no scope at all) with zero write capability:

organization:view  server:view  user:view  team:view  recipe:view

Two other view scopes are not worth granting. credential:view unlocks exactly one endpoint this server exposes (a VPC lookup) — its other three are cloud-provider credentials, which are withheld — so it buys nothing while widening what a leaked token could read. resources:view currently gates no endpoint at all; add it when Forge ships the managed-database and object-storage API.

The wrinkle: 30 reads sit behind manage scopes, so getting the read also buys the write. Two are worth it, and the rest mostly aren't:

Scope

Reads it unlocks

Writes it also grants

Suggested

site:meta

8 — all domains and certificates

add / modify / delete a domain

Add — this is SSL and domain visibility

server:manage-logs

4 — application and Nginx logs, server logs

clearing logs, nothing else

Add — smallest blast radius, biggest payoff

site:manage-redirects / -notifications / -project

6

redirect rules, webhooks, healthcheck

Optional

site:manage-nginx

2 — Nginx config

rewrite the Nginx config

Skip unless needed

server:manage-network

2 — firewall rules

change the firewall

Skip unless needed

site:manage-security

2

basic-auth rules

Skip

site:manage-deploys

1 — the deployment log

deploy the site, rewrite the deploy script (8)

Your call — see below

server:create-daemons

1 — queue worker log

create daemons, enable Horizon/Octane/Pulse (8)

Your call — see below

server:create-backups

2 — backup instances

restore a backup

Don't

storage:manage

2

delete storage providers

Don't

Suggested token — seven scopes:

organization:view  server:view  user:view  team:view  recipe:view  site:meta  server:manage-logs

That reaches 101 of the 120 endpoints this server exposes, and the token cannot deploy, restore a backup, change a firewall, or rewrite an Nginx config. Its only write powers are clearing a log and modifying a domain.

For a token with literally no write capability, drop site:meta and server:manage-logs: 89 endpoints, but no logs and no domain or certificate visibility.

The two log scopes that also grant writes

get_deployment_log and get_background_process_log are the only tools whose scopes grant real write power — deploy, and enabling Horizon/Octane/Pulse respectively. There is no alternative source: a deployment object carries only commit, status and timings, with no output field, and Forge gates the log behind the same scope as deploying.

Worth being precise about what granting them does and doesn't change. It does not give this server, or a model talking to it, any ability to deploy: no write tool exists, the client only issues GET, the deploy-hook endpoint stays excluded and deployment_url stays redacted. What it changes is the token's capability if the token itself leaks. Whether that trade is worth a failed deploy's output is a judgement about your threat model, not something this package should make for you — so both tools ship regardless, and simply return a 403 naming the scope when you haven't granted it.

Every scope-gated endpoint stays available in this package regardless of what you grant — your token's scopes decide, not us. A 403 says which scope was missing, and whether that scope would also hand over write access:

Forge denied access to /orgs/acme/servers/1/sites/2/nginx (403). This endpoint requires the
"site:manage-nginx" scope, which your token does not have. Note that "site:manage-nginx" also
grants the matching write permissions — this package deliberately does not require you to hold
it, and will simply not serve this read if you would rather keep the token read-only.

What it deliberately won't read

A GET being read-only doesn't make it safe to put in front of a language model. Thirteen of Forge's reads are withheld by default, for two different reasons.

They'd leak a secret:

  • …/sites/{site}/environment — Forge documents this as "Get .env content": database passwords, APP_KEY, every third-party API key the app holds

  • Composer and npm registry credentials

  • Cloud provider credentials (/server-credentials)

  • SSH keys and deploy keys

They'd leak a write capability:

  • …/deployments/deploy-hook returns, in Forge's words, "the deployment trigger URL" — a URL that triggers a deploy with no authentication. Handing that string to a model defeats the entire point of a read-only server, however much the verb was GET.

That last one is why this package doesn't implement read-only as "allow all GETs". Refusals explain themselves rather than looking like a bug:

/orgs/acme/servers/1/sites/2/deployments/deploy-hook is a read this server deliberately
withholds: the deployment trigger URL — an unauthenticated deploy capability, so reading it
would hand out the ability to deploy. Exposing it would grant a write capability, which
defeats the purpose of a read-only server.

…and one field, wherever it appears

Withholding an endpoint is worthless if the thing it guards is duplicated into a payload you do serve. Forge returns the deploy trigger URL inline on ordinary site reads:

{ "attributes": { "deployment_url": "https://forge.laravel.com/servers/1/sites/2/deploy/http?token=…" } }

That's the same unauthenticated deploy capability as the deploy-hook endpoint, arriving through get_site and list_sites. So every response is also filtered field-by-field, and deployment_url comes back as:

[withheld: deploy trigger URL — an unauthenticated capability to deploy the site, not a read]

The key is preserved so you can see something was withheld, and a null value passes through untouched — that legitimately means quick-deploy is off. The general lesson, learned by probing the live API rather than reading its docs: for a read-only surface over someone else's API the unit of danger is a field, not an endpoint. Fields travel.

…and secrets inside log text

The same lesson recurs a layer down, and this one cannot be solved cleanly. This server withholds .../environment to keep .env out of model context — but a deployment log is the output of a deploy script that may echo environment variables, composer auth tokens turn up in build output, and get_command_output replays whatever a human chose to run, cat .env included. Field-level redaction can't help, because the secret is inside a blob of text.

So log and command output additionally passes through a best-effort scrubber for credential-shaped substrings: KEY=/SECRET:/PASSWORD= assignments, Authorization: Bearer …, ?token=…, AWS AKIA… ids, https://user:pass@host, and PRIVATE KEY blocks. Redactions keep the key name so the line still reads as a log line and you can see what was withheld.

This is best-effort and not a guarantee. Pattern matching over arbitrary log output cannot be complete, and it is deliberately narrow — a greedy scrubber that mangled ordinary log lines would push people to disable it wholesale, which loses far more than it gains. Treat log output as potentially containing secrets regardless. get_command_output deserves the most caution of the set.

--unsafe-allow-secrets re-enables all thirteen endpoints and this field. It's off by default and named to be hard to turn on by accident. If you enable it, those values will appear in model context and in transcripts and logs wherever they're kept.

How read-only is enforced

Four independent layers, so no single mistake is sufficient:

  1. No write tool exists. Only reads are implemented, so there is nothing to disable.

  2. The client can only GET. The verb is a literal in one place and is never threaded through from configuration or arguments.

  3. Every path is matched against an allowlist of Forge's documented GET templates before a request is built. This is what makes forge_get safe: the model picks a path, but only from a set already reviewed. Denials are checked before allowances, because an excluded literal path (…/deployments/deploy-hook) collides with a legitimate template (…/deployments/{deployment}) — in a deny-by-default boundary the denial must win.

  4. Every response is filtered field-by-field on the way out, because the endpoint allowlist alone let the deploy trigger URL through inline on ordinary site reads. Log and command text is additionally scrubbed for credential shapes, and bounded in size.

  5. Your token's scopes, if you mint it view-only — defence in depth rather than the primary control.

The allowlist is generated from Forge's OpenAPI spec (npm run generate:paths), so a typo can't silently create a hole. npm run check:drift — run in CI on every PR and weekly — fails if a new GET appears unreviewed, if one we rely on disappears, if a read moves behind a write-granting scope, or, most importantly, if a withheld path is renamed such that its exclusion silently stops protecting anything.

Rate limiting

Forge allows 60 requests per minute per token. This package keeps a local sliding window and also honours X-RateLimit-* and Retry-After, retrying a 429 twice before giving up with advice to narrow the request.

Cursors are never followed automatically. A single "check every site" call must not be able to spend the whole minute, so pagination is explicit: read the page line (or meta.next_cursor) and pass the cursor back as cursor.

Development

npm install
npm run lint            # tsc --noEmit
npm test                # unit tests (no network)
npm run build
node scripts/smoke.mjs  # drives the built binary over stdio; no network needed
npm run generate:paths  # regenerate the path table from Forge's spec
npm run check:drift     # fail if the package has drifted from Forge's API

FORGE_SPEC_FILE=/path/to/spec.json makes the generator and drift check read a local spec instead of fetching.

Using this behind an MCP gateway

Tool names are intentionally un-prefixed (list_servers, not forge_list_servers), because aggregating gateways add their own namespace and a self-prefixed name becomes forge__forge_list_servers downstream.

Annotations split by kind: this package sets readOnlyHint and idempotentHint (facts about the tool, true everywhere) plus a plain title. A gateway is free to override the top-level title with its own house convention.

main and bin are the same built entry, so a gateway can require.resolve() the package and run it under its own Node rather than needing a global install.

Licence

MIT. Not affiliated with or endorsed by Laravel. "Laravel" and "Laravel Forge" are trademarks of Taylor Otwell; this is an independent client for their public API.

Available Tools

25 tools
forge_getForge API Read (any endpoint)A
Read-onlyIdempotent

Perform an arbitrary GET against the Forge API for endpoints the named tools do not cover — monitors, firewall rules, Nginx templates, recipes, teams, PHP config, heartbeats, providers and so on. Pass a path relative to the API base with real ids substituted, e.g. "/orgs/acme/servers/12345/monitors". Only documented Forge GET endpoints are permitted: writes are impossible, and a small set of reads that would expose secrets (.env contents, registry and provider credentials, SSH and deploy keys) or hand over a deploy capability (the deployment trigger URL) are refused with an explanation. Query parameters go in query, not in the path — e.g. {"page[size]": 50}.

NameRequiredDescriptionDefault
pathYesAPI path with ids filled in, starting with "/" and with no query string, e.g. /orgs/acme/servers/12345/monitors
queryNoQuery parameters, e.g. {"page[size]": 50, "sort": "-created_at"}.
tail_linesNoReturn only the last N lines, where failures appear (default 200). Output is additionally capped by character count, so a very long single line cannot flood the response.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotentHint/openWorldHint, yet the description adds substantial non-derivable behavior: writes are impossible, only documented GET endpoints are permitted, and a specific deny-list (.env contents, registry/provider credentials, SSH and deploy keys, deployment trigger URL) is refused with an explanation. That is exactly the failure-mode disclosure an agent needs before composing an arbitrary path.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, all front-loaded: scope/routing first, then path semantics, then the refusal policy and query-param placement. Every sentence carries information that changes how the tool is called; no filler or restatement of the name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an open-world passthrough tool with no output schema, the description covers the crucial risks: what is allowed, what is refused and why, how to format the path and query, and concrete examples. The only unaddressed item, rate limits, is secondary; an agent has enough to call this safely and correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description still adds real semantic value by explaining that `path` must be relative to the API base with real ids substituted (with a worked example) and that query parameters belong in `query`, not in the path. It does not discuss `tail_lines`, but the schema documents that field thoroughly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (arbitrary GET) and resource (the Forge API), and immediately frames itself as the escape hatch for endpoints the named sibling tools do not cover, listing concrete resource families (monitors, firewall rules, Nginx templates, recipes, teams, PHP config, heartbeats, providers). An agent can distinguish it from get_server/list_sites etc. without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing: use this only for endpoints the named tools do not cover, with the alternative (the named per-resource tools) implied as the default choice. It also tells the agent when the tool will refuse (secret-exposing reads, deploy trigger URL), which is actionable usage guidance rather than general prose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_background_process_logGet Background Process LogA
Read-onlyIdempotent

The log of a daemon or queue worker — what a stuck or crashing queue is actually printing. Get the id from list_background_processes. Requires the server:create-daemons scope; that scope ALSO grants creating daemons and enabling Horizon/Octane/Pulse, so a strictly read-only token will get a 403 here while list_background_processes still works.

NameRequiredDescriptionDefault
serverYesServer id from list_servers.
tail_linesNoReturn only the last N lines, where failures appear (default 200). Output is additionally capped by character count, so a very long single line cannot flood the response.
organizationNoOrganisation slug. Optional when the server has a default configured.
background_processYesProcess id from list_background_processes.

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and openWorldHint, but the description goes well beyond them by disclosing the required server:create-daemons scope, warning that the same scope also grants daemon creation and Horizon/Octane/Pulse enablement, and predicting the 403 outcome for read-only tokens. That auth-failure behavior is exactly the kind of context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first clause and the auth caveat is consolidated into a single dense second sentence. The 'what a stuck or crashing queue is actually printing' framing is slightly colorful padding, but the remainder earns its length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter read tool with 100% schema coverage and no output schema, the description supplies purpose, id sourcing, and the non-obvious permission behavior. Nothing critical is missing, though a brief note on how the output is shaped or bounded would round it out.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the tail_lines default, character cap, and the origin of both id parameters, so the schema already does the heavy lifting and baseline 3 applies. The description only lightly reinforces the id source already documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (the log of a daemon or queue worker) and frames the use case sharply with 'what a stuck or crashing queue is actually printing,' which separates it from generic output tools like get_command_output. It doesn't explicitly name which log sibling it is not (get_scheduled_job_output, get_deployment_log), but the resource and routing pointer to list_background_processes make the target unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear triggering situation (diagnosing a stuck or crashing queue) plus an explicit prerequisite chain: get the id from list_background_processes first. It also tells the agent that a strictly read-only token will 403 here while list_background_processes still works, which is real routing guidance, though it doesn't discuss when a different log tool is the right call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_command_outputGet Command OutputA
Read-onlyIdempotent

The output of a command previously run from a site's Commands panel. Get the command id from list_site_commands. NOTE: this replays whatever a human chose to run, so it is the tool most likely to contain deliberately-dumped secrets — credential-shaped text is scrubbed on a best-effort basis, but do not treat the result as sanitised.

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
serverYesServer id the site is on.
commandYesCommand id from list_site_commands.
tail_linesNoReturn only the last N lines, where failures appear (default 200). Output is additionally capped by character count, so a very long single line cannot flood the response.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover safety traits (readOnly, idempotent, open-world); the description goes well beyond that by warning that this replays whatever a human chose to run, that it is the most likely place for deliberately-dumped secrets, and that scrubbing is only best-effort. That sanitisation caveat is exactly the kind of context structured fields cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences; the identification of what is returned comes first and the security caveat is clearly flagged as a NOTE. Slightly fragmentary opening, but no sentence is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of characterising the return value, and it does reasonably well by describing the content's provenance and its untrusted nature. It still omits anything about the response shape (plain text vs structured, multi-command aggregation), which is the remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so site, server, command, tail_lines and organization are all already documented in the schema (including the tail_lines cap and organisation-slug fallback). The description only repeats the command-id provenance, adding no syntax or format detail of its own.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (the output of a command run from a site's Commands panel) and points at list_site_commands as the source of the id, which separates it from sibling list tools. It does not, however, differentiate itself from the other output-fetching siblings such as get_scheduled_job_output or get_background_process_log, which return similarly-shaped data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a concrete prerequisite workflow ('Get the command id from list_site_commands') and scopes the tool to commands issued from the Commands panel, which is enough context to pick it correctly. It stops short of stating when NOT to use it or naming the alternative output tools explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_deploymentGet DeploymentA
Read-onlyIdempotent

One deployment in detail: commit, author, status, timings and any failure information. Note that the deployment OUTPUT log needs the site:manage-deploys scope, which also grants the ability to deploy — so a read-only token will get a 403 for the log while this summary still works.

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
serverYesServer id the site is on.
deploymentYesDeployment id from list_deployments.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint, idempotentHint, and openWorldHint. The description adds value by noting that the deployment output log requires a broader scope (site:manage-deploys) and that read-only tokens will get a 403 for the log while the summary works. This behavioral insight goes 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with two sentences. The first sentence immediately states the purpose, and the second adds critical scope information. Every sentence is valuable and there is no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the absence of an output schema, the description lists the key fields returned (commit, author, status, etc.) and includes a scope-related caveat. It is fairly complete for a single-item retrieval tool, though it could mention error handling or not found scenarios.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage with descriptions for all parameters. The description does not add additional meaning beyond the schema, so it meets the baseline expectation. No extra parameter guidance is provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns detailed information about a single deployment, listing fields like commit, author, status, timings, and failure info. This distinguishes it from sibling tools like list_deployments (list) and get_deployment_script (script).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when needing detailed deployment information but does not explicitly contrast with alternatives. It does mention a scope requirement for the log, providing some usage context, but lacks direct guidance on when to use this versus other tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_deployment_logGet Deployment LogA
Read-onlyIdempotent

The output of a deployment — the deploy script's stdout/stderr, which is what actually tells you why a deploy failed. Get the deployment id from list_deployments. Requires the site:manage-deploys scope; be aware that scope ALSO grants the ability to deploy, so a strictly read-only token will get a 403 here while list_deployments and get_deployment still work.

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
serverYesServer id the site is on.
deploymentYesDeployment id from list_deployments.
tail_linesNoReturn only the last N lines, where failures appear (default 200). Output is additionally capped by character count, so a very long single line cannot flood the response.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation it discloses the critical auth nuance: the required site:manage-deploys scope also grants deploy rights, so a strictly read-only token gets a 403 here even though list_deployments and get_deployment succeed. That is exactly the operational trap an agent needs warned about, and it is not derivable from 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each carrying distinct payload: what it returns, where the id comes from, and the scope/403 caveat. Nothing is padding and the most consequential warning is not buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly describes the return value (deploy script stdout/stderr), covers the prerequisite scope and its failure mode, and the schema fully documents parameters — nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all five parameters and the tail_lines cap are already documented in the schema. The description confirms the deployment id comes from list_deployments but adds no syntax or format detail beyond the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

It names a specific verb+resource (the deployment's stdout/stderr log) and immediately distinguishes it from sibling reads by explaining it 'is what actually tells you why a deploy failed', which separates it from get_deployment (metadata) and get_deployment_script (the script itself). An agent can pick it out without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage context (diagnosing failed deploys) and tells the agent where to source the id ('Get the deployment id from list_deployments'). It stops short of explicitly naming the neighbouring reads it is not, so the when-not guidance is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_deployment_scriptGet Deployment ScriptA
Read-onlyIdempotent

The site's deployment script — the commands Forge runs on each deploy. Read-only: this cannot change the script.

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
serverYesServer id the site is on.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint, openWorldHint, and idempotentHint. The description reinforces the read-only nature but adds no further behavioral context beyond what annotations offer.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two precise sentences with no wasted words. The purpose is front-loaded, and every sentence contributes meaningful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only retrieval tool with no output schema, the description adequately explains what it returns and that it is safe. It could mention return format but is sufficient for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents parameters. The description adds no additional semantics beyond mentioning 'site' implicitly, meeting baseline without extra value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool returns the deployment script (specific verb and resource) and distinguishes it as read-only. It differentiates from siblings like get_deployment by specifying it retrieves the script commands.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states 'Read-only: this cannot change the script,' indicating safe usage. However, it does not mention when to avoid using this tool or suggest alternatives among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_scheduled_job_outputGet Scheduled Job OutputA
Read-onlyIdempotent

The output of the most recent run of a scheduled (cron) job — server-level, or site-level if you pass site. Use it to see whether a schedule is actually succeeding rather than just firing. Get the job id from list_scheduled_jobs.

NameRequiredDescriptionDefault
jobYesJob id from list_scheduled_jobs.
siteNoPass this only for a site-level scheduled job; omit for a server-level one.
serverYesServer id from list_servers.
tail_linesNoReturn only the last N lines, where failures appear (default 200). Output is additionally capped by character count, so a very long single line cannot flood the response.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, open-world behavior, so the safety profile is covered. The description adds genuinely useful behavioral detail beyond that: it returns only the most recent run (not history), and it can be scoped to server or site level. It doesn't discuss permissions or response format, but for a read tool that 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences with the resource and scoping constraint front-loaded, followed by the usage rationale and the id source. Every sentence carries distinct information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only log-retrieval tool with no output schema, the description conveys what is returned (latest run output), how it is scoped, and where the id comes from, which is enough to call it correctly. Only the exact response shape is left implicit, which is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents every parameter including the site-level vs server-level distinction and the tail_lines cap. The description mostly restates the server/site scoping rule and adds little syntax or format detail beyond it, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('the output of the most recent run of a scheduled (cron) job') and immediately disambiguates scope: server-level, or site-level when `site` is passed. It also distinguishes itself from the adjacent listing tool by pointing at list_scheduled_jobs for the job id.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear motivating use case ('to see whether a schedule is actually succeeding rather than just firing') and tells the agent where the required id comes from. It stops short of naming an alternative tool or an explicit condition for when not to use it, so it is clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_serverGet ServerA
Read-onlyIdempotent

Get one server in full: provider and region, sizes, PHP and database versions, IP addresses, tags and provisioning state.

NameRequiredDescriptionDefault
serverYesServer id from list_servers.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal readOnly, openWorld, idempotent. Description adds value by listing what data is returned. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single, efficient sentence. Front-loaded with purpose, no fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool, description covers return fields, parameters are documented in schema, sibling tools exist. No output schema needed given description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with good descriptions. Tool description adds no extra parameter meaning beyond what schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Get one server in full' and lists specific fields (provider, region, sizes, PHP/db versions, IPs, tags, provisioning state), distinguishing it from list_servers (list all) and get_server_php (specific).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies use when detailed single-server info is needed; references required param from list_servers. Does not explicitly state when not to use or mention alternatives, but sibling tools context helps.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_server_event_outputGet Server Event OutputA
Read-onlyIdempotent

The output of a Forge server event — a provisioning step, service restart or configuration change. Get the event id from list_server_events. Useful for finding out why a Forge-side operation failed.

NameRequiredDescriptionDefault
eventYesEvent id from list_server_events.
serverYesServer id from list_servers.
tail_linesNoReturn only the last N lines, where failures appear (default 200). Output is additionally capped by character count, so a very long single line cannot flood the response.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld, so the safety profile is covered structurally. The description adds diagnostic framing ('finding out why a Forge-side operation failed') but says nothing about truncation, pagination, or how much output is returned that isn't already in the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with what the tool returns and immediately followed by the prerequisite and the motivating use case. No filler, though the first sentence is a noun phrase rather than a directive verb.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only diagnostic tool with no output schema and fully documented parameters, the description supplies purpose, prerequisite, and use case. It is nearly complete; only return-shape/pagination expectations remain unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and tail_lines already documents the default, cap, and truncation behavior in the schema itself. The description only echoes the event-id provenance, adding little beyond the structured fields. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (the output of a Forge server event) and enumerates what an event represents (provisioning step, service restart, config change). It is clearly separable from log/output siblings like get_command_output or get_scheduled_job_output by resource, though it never names those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete prerequisite ('get the event id from list_server_events') and a clear use case, debugging Forge-side failures. No explicit when-not or named alternative tool, 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.

get_server_phpGet Server PHP VersionsA
Read-onlyIdempotent

The PHP versions installed on a server, which is the default, and their patch levels. Useful for spotting servers left on an end-of-life version.

NameRequiredDescriptionDefault
serverYesServer id from list_servers.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, and open-world behavior. The description adds transparent details about the output (versions, default, patch levels) without contradicting annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no wasted words. The first sentence immediately states the tool's functionality, and the second adds a practical use case. Perfectly concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description adequately describes what is returned (versions, default, patch levels). It does not specify structure, but for a simple list this is sufficient. Parameter handling is clear from the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so parameters are fully described in the schema. The description does not add extra meaning beyond stating it's for a server, which is already covered. Baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool returns the PHP versions installed on a server, including the default version and patch levels. This distinguishes it from sibling tools like get_server (general server info) and list_servers (list servers).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear use case ('spotting servers left on an end-of-life version'), implying when to use. It does not explicitly state when not to use, but the purpose is narrowly defined, and alternatives are evident from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_siteGet SiteA
Read-onlyIdempotent

Get one site in full: domain and aliases, web directory, PHP version, repository and branch, quick-deploy state and which server it lives on. Note that Forge addresses a single site at organisation level, so no server id is needed.

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is clear. Description adds behavioral context about org-level addressing, which is valuable beyond annotations. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler. First sentence efficiently lists return fields, second sentence provides critical context. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given rich annotations (read-only, idempotent) and full schema coverage, the description sufficiently covers what the tool returns and clarifies a potential organizational confusion. No output schema needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so description does not repeat parameter descriptions. However, it adds value by clarifying that 'site' comes from list_sites and that organization is optional with default context, which aids correct usage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description uses specific verb 'Get' and resource 'site', lists exact fields returned (domain, aliases, etc.), and clearly distinguishes from sibling list_sites by emphasizing full detail.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states that no server ID is needed because Forge addresses at organization level, which provides clear usage context. However, it does not explicitly mention when to use this versus alternatives or when not to use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_site_integrationGet Site Integration StatusA
Read-onlyIdempotent

Whether a first-party Laravel integration is enabled for a site: Horizon, Octane, Reverb, Pulse, Inertia, the scheduler, or maintenance mode. "laravel-maintenance" answers "is this site in maintenance mode?".

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
serverYesServer id the site is on.
integrationYesWhich integration to check.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations (readOnlyHint, openWorldHint, idempotentHint) already indicate safe, non-destructive behavior. The description adds useful clarification, especially for the 'laravel-maintenance' integration, without contradicting annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose, and a secondary sentence clarifying an enum value. No unnecessary words. Highly concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only status check with 4 parameters (3 required), the description covers purpose and key clarification. No output schema is present, but expected return is boolean. Lacks mention of authentication or prerequisite (e.g., server existence), but annotations cover safety. Overall adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds meaning for the 'integration' parameter by clarifying that 'laravel-maintenance' answers the maintenance mode question. However, it does not elaborate on 'server', 'site', or 'organization' beyond schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool checks whether a specific first-party Laravel integration is enabled, listing the possible integrations. This distinguishes it from sibling tools like get_site (which retrieves general site info) and list_certificates, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context but does not explicitly guide when to choose this tool over alternatives. No exclusions or prerequisites are mentioned. Sibling tools include many list operations, but no comparative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_site_logsGet Site LogsA
Read-onlyIdempotent

Tail a site's logs: the Laravel/application log, or the Nginx access or error log. The first place to look when a site is throwing errors. Returns the END of the log by default (that is where failures are) — raise tail_lines for more. Requires the server:manage-logs scope, whose only write power is clearing logs. Note that Forge reads logs from the server over SSH at request time, so a server whose Forge access has been revoked returns an SSH error instead of a log.

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
typeYesWhich log to read.
serverYesServer id the site is on.
tail_linesNoReturn only the last N lines, where failures appear (default 200). Output is additionally capped by character count, so a very long single line cannot flood the response.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover only the read/idempotent/safety profile; the description adds substantial context beyond them: the required server:manage-logs scope and its sole write power (clearing logs), the fact that logs are read over SSH at request time, and the specific failure mode when Forge access is revoked.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence is front-loaded and earns its place: purpose, primary use case, default behavior with rationale, permission scope, and the SSH failure mode. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, 5-parameter tool with full annotations and no output schema, the description covers purpose, defaults, permissions, and operational caveats. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 adds real meaning: it explains why the END of the log is returned by default (that is where failures are) and frames tail_lines as the lever to raise. It does not add syntax detail for site/server/organization beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Tail a site's logs') and enumerates the three log types (Laravel/application, Nginx access, Nginx error). This is concrete enough that an agent understands exactly what is retrieved 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear use context ('The first place to look when a site is throwing errors') and explains how to expand output via tail_lines. It does not, however, route the agent away from or toward the log-oriented siblings (get_deployment_log, get_background_process_log, get_server_event_output) or state when-not-to-use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_background_processesList Background ProcessesA
Read-onlyIdempotent

Daemons and queue workers on a server — command, user, process count and status. Use it to check queue workers are running and correctly sized.

NameRequiredDescriptionDefault
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
serverYesServer id from list_servers.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds the scope of returned data, but says nothing about pagination limits, permission requirements, or rate constraints beyond what the schema's page_size note already explains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both load-bearing: the first defines the resource and payload, the second gives the use case. No preamble, no restating of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully names the returned fields, and pagination is covered by the schema's page_size note. However, for a 7-parameter, nested-object tool it omits any mention of the server scoping requirement, pagination follow-through, and how it relates to the neighboring log tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each of the 7 parameters (sort, cursor, filter, server, include, page_size, organization) is documented in the schema itself, so the baseline is 3. The description adds no extra parameter semantics — the fields it lists are output fields, not inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the resource (daemons and queue workers) scoped to a server and enumerates the key fields returned (command, user, process count, status), so the agent knows exactly what it gets. It is clear, but it never contrasts itself with close siblings such as get_background_process_log or list_scheduled_jobs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Use it to check queue workers are running and correctly sized" gives a concrete decision context rather than vague filler. There are no exclusions or named alternatives (e.g. when to prefer the per-process log tool), which keeps it 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_backup_configsList Backup ConfigurationsA
Read-onlyIdempotent

Database backup configurations on a server — schedule, retention, destination and which databases are covered. Answers "is this server actually being backed up?". Listing individual backup INSTANCES needs the server:create-backups scope, which also grants restore, so it is not exposed here.

NameRequiredDescriptionDefault
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
serverYesServer id from list_servers.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, openWorld), so this adds a genuinely new behavioral trait: the scope restriction on instance-level listing and why it is deliberately omitted. It doesn't disclose pagination limits or permission requirements for this endpoint, but the auth-scoping note is real value 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: what it returns first, then the practical question it answers, then the scope caveat. No filler, and the most decision-relevant content is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description helpfully enumerates the returned fields (schedule, retention, destination, databases covered), and all 7 parameters are covered by the schema. It is essentially complete, missing only pagination behavior, which the schema's cursor/page_size descriptions already handle.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter is fully documented in the schema and the description adds no syntax or filter semantics of its own. The baseline of 3 applies since the structured data does all the parameter work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (list) and resource (backup configurations) and enumerates the salient fields returned — schedule, retention, destination, covered databases. It also distinguishes itself from the un-exposed instance-level listing, so an agent knows exactly which layer of backups this exposes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a concrete use case ("is this server actually being backed up?") and explicitly notes the alternative route (individual backup instances) is not available here because it needs the create-backups scope. No sibling in the toolset competes, so the guidance is clear, though it does not spell out prerequisites for this call itself.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_certificatesList Site CertificatesA
Read-onlyIdempotent

A site's SSL certificates with their type, status and expiry — the read to use for certificate-expiry checks. Requires the site:meta scope.

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
serverYesServer id the site is on.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent and openWorld, so the safety profile is covered. The description adds the site:meta scope requirement, which is genuinely useful auth context beyond the annotations, though it doesn't discuss pagination behavior (which the schema itself already handles).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence that front-loads the resource and returned fields before the usage hint and scope requirement. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully lists the key returned fields and the auth scope, which is most of what an agent needs. It could say more about pagination, but the schema's page_size/cursor descriptions already carry that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all 8 parameters (including sort, cursor, filter, include, page_size) are fully documented in the schema. The description adds no additional parameter meaning, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (a site's SSL certificates) and enumerates the salient returned fields (type, status, expiry). An agent can immediately tell this is the certificate-listing read and not confuse it with generic site or deployment reads among the siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit use case — 'the read to use for certificate-expiry checks' — and states the required site:meta scope. It stops short of naming alternatives or when-not conditions, but the intended context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_databasesList DatabasesA
Read-onlyIdempotent

Database schemas on a server, or the database users and the schemas they can access. Names and grants only — this never reads database contents.

NameRequiredDescriptionDefault
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
serverYesServer id from list_servers.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
resourceNo"schemas" (default) for databases, "users" for database users.
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: the output is 'names and grants only' and it 'never reads database contents' — important scoping information for an agent deciding whether it can answer a question with this tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with zero filler; the resource scope is front-loaded and the data-access constraint follows immediately. Nothing to trim.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter tool with no output schema, the description adequately conveys what is returned (names and grants) and the two output modes. It does not need to explain return values since it already characterizes them, though pagination/filter behavior is left to the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description's schemas/users distinction loosely maps to the 'resource' enum, but it adds no syntax, defaults, or field-level meaning beyond what the schema already documents for the 8 parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resources returned (database schemas, or database users and their accessible schemas) and clearly distinguishes this from siblings like list_servers or list_domains. The verb is implicit from the tool name, but the scope is specific enough that an agent knows what it gets back.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It implicitly covers two usage modes distinguished by the 'resource' parameter (schemas vs users), but offers no explicit when-to-use/when-not guidance or alternatives among the many sibling list_* tools. Adequate but inferential.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_deploymentsList DeploymentsA
Read-onlyIdempotent

A site's deployment history — commit, author, status, duration and timestamps. Use it to find when a site last shipped, or to identify a failed deployment to inspect with get_deployment. Newest first unless you pass sort (Forge's own default is oldest first).

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
serverYesServer id the site is on.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, idempotentHint, openWorldHint), so the description correctly focuses elsewhere and adds real behavioral context: default ordering is newest-first and this diverges from Forge's own oldest-first default. It doesn't mention pagination/auth details, but those are secondary for a safe read tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences, front-loaded with the resource and its returned fields, then routing guidance, then the ordering caveat. Every clause earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 100% schema coverage on all 8 parameters and no output schema, the description need not restate pagination, filter, or include semantics. It supplies the routing, the returned-field summary, and the ordering behavior an agent needs to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 adds meaning the schema does not: it discloses the default sort direction and the underlying Forge default, which clarifies how the sort parameter behaves. That is a genuine semantic addition over the schema's mechanical 'comma-separated fields' description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('A site's deployment history') and enumerates the returned fields (commit, author, status, duration, timestamps). It clearly distinguishes itself from the sibling get_deployment by being the list/history view rather than a single record.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete contexts ('find when a site last shipped', 'identify a failed deployment to inspect with get_deployment') and explicitly names the alternative tool with the condition that selects it. It lacks an explicit when-not-to-use statement, so it falls just short of 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_domainsList Site DomainsA
Read-onlyIdempotent

The domains attached to a site, including aliases and their certificate state. Pair with list_certificates to audit SSL expiry.

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
serverYesServer id the site is on.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true and openWorldHint=true, so safety and idempotency are covered. The description adds content-level context (results include aliases and certificate state), but says nothing about pagination limits, result volume, or auth/permission needs, so it adds only modest value 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, no filler, with the substantive content scope stated first and the complementary tool second. It is well front-loaded, though it is arguably too terse to cover a tool with 8 parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description carries the return-value burden, and it does name the key returned entities (domains, aliases, certificate state). Combined with the fully documented 8-parameter schema, an agent has enough to invoke it correctly, though the description could have said more about pagination-following behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% across all 8 parameters, including the nested filter object, sort syntax, cursor, page_size cap and organization slug, so the schema does the heavy lifting. The description contributes no parameter-level meaning at all, making the baseline 3 correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific resource (domains attached to a site) and adds the relevant content scope (aliases and their certificate state), so an agent knows what it gets back. It does not explicitly distinguish itself from siblings like get_site or list_certificates beyond naming one as a follow-on, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives a paired-use hint ('Pair with list_certificates to audit SSL expiry'), which implies a workflow. However, it never states when to call this tool instead of alternatives, nor any prerequisites such as needing a site id from list_sites (that only appears in the schema).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_organizationsList OrganisationsA
Read-onlyIdempotent

List the Forge organisations this API token can reach, with their slugs. Every other tool takes an organisation slug (or uses the configured default). Start here if you do not know the slug.

NameRequiredDescriptionDefault
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds genuine value beyond that by disclosing the auth-scoping behavior ('this API token can reach') and the tool's role as a slug-discovery entry point. It doesn't discuss pagination, but the schema already documents that in detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, each load-bearing: what it lists, why the slug matters, and when to call it. Front-loaded with the action and completely free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-param list tool with no output schema, the description conveys the essential return shape ('with their slugs') and its role in the workflow. It is slightly light on practical behavior like the implicit default-organization handling, but nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all five parameters (sort, cursor, filter, include, page_size) including the 30-item cap behavior. The description adds no parameter-level detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (Forge organisations), with a clear scope qualifier ('this API token can reach'). The 'with their slugs' clause signals the return content, distinguishing it cleanly from all the get_/list_ resource siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: 'Start here if you do not know the slug.' It also explains the downstream dependency ('Every other tool takes an organisation slug, or uses the configured default'), which tells the agent exactly when this tool is a prerequisite versus when it can be skipped.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_scheduled_jobsList Scheduled JobsA
Read-onlyIdempotent

Cron/scheduled jobs, either for a whole server or for one site. Shows the command, user, frequency and last run state — use it to confirm a schedule exists and is firing.

NameRequiredDescriptionDefault
siteNoRestrict to one site; omit for all jobs on the server.
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
serverYesServer id from list_servers.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, idempotentHint, openWorldHint), so the bar is lower. The description adds genuine behavioral value by enumerating what each entry shows (command, user, frequency, last run state), which compensates for the missing output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the scope/resource statement leads, followed by the return contents and the intended use. No filler and nothing important buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list tool with no output schema, the description supplies the returned fields, the server/site scoping, and a reason to call it; pagination and sort semantics live in the schema. It is nearly complete, with only the alternative output tool unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% across all 8 parameters, so the schema does the heavy lifting. The description's 'whole server or for one site' only echoes the site parameter's own description without adding format or constraint detail. Baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (cron/scheduled jobs) and its scope (whole server or one site), which is enough to distinguish it from get_scheduled_job_output and list_background_processes. It doesn't name a sibling explicitly, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives one positive use case — 'use it to confirm a schedule exists and is firing' — but no when-not guidance and no named alternative for retrieving job output or listing other process types. Usage is implied rather than routed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_server_eventsList Server EventsA
Read-onlyIdempotent

A server's recent Forge activity — provisioning steps, service restarts, configuration changes, who triggered them and whether they succeeded. The closest thing Forge has to an audit trail, and the first place to look when something changed unexpectedly.

NameRequiredDescriptionDefault
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
serverYesServer id from list_servers.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotentHint, so the safety profile is covered. The description adds real semantic context beyond that: events carry an actor and a success/failure outcome, and the feed functions as an audit trail — telling the agent what the records mean, not just that the call is safe.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, purpose front-loaded, content enumeration in the first clause, and the 'when to reach for it' hook in the second. No padding or restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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 output schema and full schema coverage, the definition supplies what the schema cannot: the meaning and shape of an event and its role as an audit trail. It could go slightly further by noting pagination-driven iteration, though the schema's page_size text already warns about it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the important page-size cap of 30 and the pagination cursor, so the schema does the heavy lifting. The description adds no parameter guidance of its own, making baseline 3 correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names the specific resource (a server's recent Forge activity) and enumerates its contents — provisioning steps, restarts, config changes, actor and outcome — so an agent knows exactly what comes back. It does not, however, distinguish itself from the adjacent get_server_event_output sibling, which likely returns per-event detail.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit situational trigger: 'the first place to look when something changed unexpectedly,' framing it as an audit trail. It stops short of naming alternatives (e.g. get_server_event_output for a single event's output), so no exclusion is stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_serversList ServersA
Read-onlyIdempotent

List the servers in an organisation — provider, region, size, PHP version, IP addresses and provisioning status. Supports filter/sort/include (try include="tags"). Use this to find a server id for the other tools.

NameRequiredDescriptionDefault
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, openWorld), so the description adds the returned field set and a concrete include relationship hint ("try include=\"tags\""). It does not discuss the 30-item page cap, but that is documented in the schema rather than left silent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: resource + scope first, returned fields second, usage routing last. No filler, and the most decision-relevant information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully enumerates the fields returned, which is what an agent needs to judge relevance. Pagination semantics live in the schema, so the remaining gap is small.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so filter/sort/include/cursor/page_size are already documented. The description restates filter/sort/include and adds a mild usage suggestion for include="tags", but no syntax or format detail beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (list) and resource (servers) scoped to an organisation, and enumerates the fields returned (provider, region, size, PHP version, IPs, provisioning status). This cleanly separates it from the singular get_server sibling without needing to open either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Use this to find a server id for the other tools" gives an explicit routing purpose that points toward the id-consuming siblings. It stops short of naming a specific alternative or stating when-not to use it, but the intended context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_site_commandsList Site Command HistoryA
Read-onlyIdempotent

The history of commands run from a site's Commands panel, with who ran them and when. An audit read — this cannot run a command.

NameRequiredDescriptionDefault
siteYesSite id from list_sites.
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
serverYesServer id the site is on.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds real value by confirming execution is impossible and by describing the returned content (who ran each command and when), which goes beyond the structured fields. It omits pagination behavior, but the schema covers that in detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short, front-loaded sentences with zero filler. The purpose comes first and the key safety constraint follows immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 8 parameters, nested filter object, pagination, and no output schema, the description gives enough to understand content and safety, and the schema fully covers parameter mechanics. It could be slightly richer about pagination or filterable fields, but nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every parameter, including the page_size cap and cursor semantics, is documented in the schema. The description adds only that results are ordered by run time/who, without explaining sort, filter, or include usage. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('history of commands run from a site's Commands panel') and immediately disambiguates it from command-executing or output-fetching siblings with 'this cannot run a command'. An agent can distinguish this audit-list from get_command_output or background-process tools 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.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'An audit read — this cannot run a command' tells the agent when-not to expect execution, which is useful negative guidance. However, it never names when to choose this over get_command_output or other command-related siblings, leaving the primary usage decision implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_sitesList SitesA
Read-onlyIdempotent

List every site in an organisation across all servers, with its domain, project type, PHP version, repository, deployment and maintenance-mode state. Prefer this over listing sites server by server. Note that the hosting server is NOT included by default — pass include="server" to answer "which server hosts acme.com?" in one call. To find one site, filter by name (filter: {"name": "acme.com"}) rather than paging through them all. Sites on a revoked (archived) server are still listed as installed; with include="server" they are marked server_revoked: true, so a stale namesake is not taken for the live site.

NameRequiredDescriptionDefault
sortNoComma-separated fields to sort by; prefix with "-" to reverse (e.g. "-created_at").
cursorNoPagination cursor from a previous response's meta.next_cursor.
filterNoField filters, e.g. {"name": "acme-web"}. Supported fields vary by endpoint.
includeNoComma-separated relationships to embed (e.g. "tags,latestDeployment").
page_sizeNoItems per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the "page" line and follow the cursor.
organizationNoOrganisation slug. Optional when the server has a default configured.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld, and the description adds real value beyond them: the hosting server is NOT included by default, sites on revoked servers remain listed as installed but are flagged server_revoked: true under include="server", which prevents misidentifying a stale namesake. It does not discuss pagination timing or response shape, but the schema covers page_size and cursor semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose and return fields, then sequences alternatives→include→filter→revoked-server caveat. Every sentence carries information, though the first sentence is dense and the revoked-server note is a long compound clause that could be tighter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-param, zero-required list tool with no output schema and full schema coverage, the description covers defaults, filtering, relationship embedding, and a non-obvious edge case (revoked server markers) that an agent would otherwise get wrong. Nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, and the description layers on concrete usage the schema lacks: filter: {"name": "acme.com"} for single-site lookup and include="server" for relationship embedding. It clarifies default behavior (server omitted unless requested), which the schema's generic include description never states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (list every site in an organisation across all servers) and enumerates the returned attributes (domain, project type, PHP version, repository, deployment, maintenance-mode state). It distinguishes itself from the server-by-server alternative, so an agent can select it against siblings like list_servers or get_site without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use guidance: prefer this over listing sites server by server; use filter by name to find a single site instead of paging; pass include="server" to answer hosting questions in one call. It names the concrete alternative behaviors and the condition selecting each, leaving nothing to inference.

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. 19 tool updatesv0.3.0
    • Changedforge_get1 field changed
      • addedInput schema / properties / tail_lines
        Added value: +{
        +  "description": "Return only the last N lines, where failures appear (default 200). Output is additionally capped by character count, so a very long single line cannot flood the response.",
        +  "exclusiveMinimum": 0,
        +  "maximum": 5000,
        +  "type": "integer"
        +}
    • Addedget_background_process_log
    • Addedget_command_output
    • Addedget_deployment_log
    • Addedget_scheduled_job_output
    • Addedget_server_event_output
    • Changedget_site_logs1 field changed
      • addedInput schema / properties / tail_lines
        Added value: +{
        +  "description": "Return only the last N lines, where failures appear (default 200). Output is additionally capped by character count, so a very long single line cannot flood the response.",
        +  "exclusiveMinimum": 0,
        +  "maximum": 5000,
        +  "type": "integer"
        +}
    • Changedlist_background_processes2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_backup_configs2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_certificates2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_databases2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_deployments2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_domains2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_organizations2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_scheduled_jobs2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_server_events2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_servers2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_site_commands2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
    • Changedlist_sites2 fields changed
      • changedInput schema / properties / page_size / description
        Previous value: -"Items per page (Forge default 30)."New value: +"Items per page, at most 30. Forge caps pages at 30 and silently returns 30 for anything larger, so read the \"page\" line and follow the cursor."
      • changedInput schema / properties / page_size / maximum
        Previous value: -100New value: +30
  2. 20 tool updatesv0.1.0
    • First observedforge_get
    • First observedget_deployment
    • First observedget_deployment_script
    • First observedget_server
    • First observedget_server_php
    • First observedget_site
    • First observedget_site_integration
    • First observedget_site_logs
    • First observedlist_background_processes
    • First observedlist_backup_configs
    • First observedlist_certificates
    • First observedlist_databases
    • First observedlist_deployments
    • First observedlist_domains
    • First observedlist_organizations
    • First observedlist_scheduled_jobs
    • First observedlist_server_events
    • First observedlist_servers
    • First observedlist_site_commands
    • First observedlist_sites

TDQS

A3.9/5.0

Scored across 25 tools

Disambiguation4/5

Each named tool targets a distinct Forge resource or action, and the descriptions do a good job clarifying scope and required identifiers. However, the cluster of output/log readers (get_deployment_log, get_command_output, get_scheduled_job_output, get_server_event_output, get_background_process_log) and the forge_get catch-all can be mistaken for one another without reading the full descriptions.

Naming Consistency4/5

Nearly all tools follow a predictable snake_case verb_noun pattern (list_servers, get_site, list_deployments). The main deviations are forge_get's prefix order and a slight suffix inconsistency between *_output and *_log, but overall naming is readable and consistent.

Tool Count3/5

25 tools is borderline heavy for a read-only surface. The breadth of Laravel Forge justifies many tools, but several resource-specific readers (sites, deployments, logs, outputs) could be consolidated, especially since forge_get already covers uncovered endpoints.

Completeness4/5

The surface provides strong read-only coverage for servers, sites, deployments, databases, backups, scheduled jobs, logs, certificates and integrations. Minor gaps for first-class tools covering monitors, firewall rules, Nginx templates, teams and similar areas are workable via forge_get, and a few log tools may return 403 with a strictly read-only token.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers