Skip to main content
Glama
MohamedXAdel

fortyguard-mcp

by MohamedXAdel

fortyguard-mcp

An MCP server for the FortyGuard Temperature API — hyperlocal urban heat data for US locations.

CI Python 3.11+ License: MIT

Gives an AI agent 12 tools over FortyGuard's five analysis endpoints: street-level temperature heatmaps, environmental parameters, satellite and street-view segmentation, and heat intelligence reports.


Why this exists

FortyGuard's API is asynchronous, returns large payloads, charges per call, and has a handful of behaviours that are easy to get wrong and expensive to get wrong. This server handles those:

  • Long-running jobs. A heat-intelligence report takes 3–7 minutes; MCP clients time out long before. Waits are bounded and always return the activity_id, so nothing is lost.

  • Large results. One heatmap can be 527 tiles / 223 KB. Payloads pass through untouched when they fit; when they don't, you get the statistics plus every route to the rest — never a silent truncation.

  • Repeat cost. Results are deterministic, so they're stored locally and an identical request is served from disk instead of being paid for twice.

  • Reports you can actually open. Heat Intelligence returns a short-lived signed URL rather than a document. The server downloads the PDF and hands you a local path.

Related MCP server: climate-risk-mcp-server

Design position

It is a thin pass-through, not a translation layer. API responses and error messages are returned verbatim — FortyGuard's validation messages are genuinely good, and rewriting them would be both brittle and worse:

Polygon ring is not closed: the first and last positions must be identical.
Input should be 60, 80 or 100
Latitude -112.095 is out of bounds; must be between -90.0 and 90.0.

Nothing account-specific is baked in. Area caps, endpoint entitlements, credit costs and date ranges all vary by plan — Basic allows 10 mi² with no premium endpoints, Premium allows 50 mi². Those are read from your account at runtime rather than hardcoded, so the server behaves correctly whatever plan you're on. There is deliberately no estimate_cost: reporting your real balance is truthful where predicting from someone else's price list would not be.

It degrades safely. An unknown status counts as pending, never as success. An unrecognised result shape is passed through rather than guessed at. A change at FortyGuard's end costs this server efficiency, not correctness.

Install

uvx --from git+https://github.com/mohamedxadel/fortyguard-mcp fortyguard-mcp

Or from a checkout:

pip install -e .

Requires Python 3.11+. Runs on Linux, macOS and Windows.

Set it up

One command does the whole thing — stores your key, checks it against the API, finds your MCP client and writes the config:

fortyguard-mcp setup
FortyGuard MCP setup

1. API key
------------------------------------------------------------------------
Get a key from the FortyGuard dashboard, then paste it here.
FortyGuard API key (input hidden):

OK Stored 32 characters in /home/you/.config/fortyguard-mcp/.env
  Permissions: 0600 (owner read/write only)

2. Check
------------------------------------------------------------------------
Checking the key against the API... works
  plan: Hackathon | credits remaining: 1,242,100

3. Connect a client
------------------------------------------------------------------------
Found:
  1. Claude Desktop         not configured
  2. Cursor                 already configured
  3. none - just print the config

Configure which? [1-3, or Enter to skip]

Your existing client config is backed up before anything is written, and only the fortyguard entry is touched.

If something is wrong later, fortyguard-mcp --doctor checks the key, the API, disk permissions and every client config, and tells you what to fix.

Configuring a client by hand

The key lives under your user profile, so the client config needs no secret in it at all — which matters, because client configs get committed.

{
  "mcpServers": {
    "fortyguard": { "command": "fortyguard-mcp" }
  }
}
  • macOS ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows %APPDATA%\Claude\claude_desktop_config.json

  • Linux ~/.config/Claude/claude_desktop_config.json

claude mcp add fortyguard -- fortyguard-mcp
{
  "mcpServers": {
    "fortyguard": { "command": "fortyguard-mcp" }
  }
}
{
  "mcp": {
    "servers": {
      "fortyguard": { "command": "fortyguard-mcp" }
    }
  }
}
{
  "mcpServers": {
    "fortyguard": { "command": "fortyguard-mcp" }
  }
}

Not installed on PATH? Use {"command": "uvx", "args": ["fortyguard-mcp"]}. fortyguard-mcp --print-config prints the right block for your machine.

This server speaks stdio, so any client that launches a local process works. Hosted connectors that only accept an HTTPS URL cannot reach it as shipped — see Serving over a network.

Where the key is looked for

Source

1

FORTYGUARD_API_KEY in the environment

your client's env block

2

FORTYGUARD_ENV_FILE=/abs/path

explicit opt-in

3

<config dir>/.env

what setup writes

The current directory is deliberately not searched. An MCP server is spawned wherever the client happens to be — the protocol docs warn it may be / on macOS. A CWD-relative .env therefore does one of two wrong things: silently adopts an unrelated repository's keys (including FORTYGUARD_DATA_DIR, which would redirect your paid archive), or fails to find the key you did set, with nothing to indicate why. Both were reproduced before this was changed.

Run fortyguard-mcp --where to see every path checked and which one resolved.

Settings

Variable

Default

Purpose

FORTYGUARD_API_KEY

Required. Never logged or written to disk by this server.

FORTYGUARD_BASE_URL

https://api.fortyguard.com

API endpoint. Must be https unless it is loopback.

FORTYGUARD_DATA_DIR

platform data dir

Where results and reports are stored

FORTYGUARD_INLINE_TOKEN_BUDGET

25000

Above this, format="auto" summarises rather than inlines

FORTYGUARD_COORDINATE_PRECISION

5

Decimal places in compact encoding (~1 m)

FORTYGUARD_POLL_TIMEOUT_S

600

Ceiling on any single wait

FORTYGUARD_REPORT_TIMEOUT_S

120

Ceiling on a report download

FORTYGUARD_REPORT_MAX_BYTES

104857600

Ceiling on what one download may write to disk

FORTYGUARD_REPORT_ALLOW_PRIVATE_HOSTS

false

Allow report downloads from private/loopback addresses. Only for self-hosted storage.

FORTYGUARD_MAX_STORAGE_BYTES

unset

Optional archive cap for CI/containers

FORTYGUARD_LOG_LEVEL

INFO

Diagnostics to stderr as JSON lines, credentials redacted

Troubleshooting

Run fortyguard-mcp --doctor first — it checks each of these and names the fix.

Symptom

Cause

Fix

Client shows no tools

Server failed to start

fortyguard-mcp --doctor; check the client's MCP log

Every call fails with "FORTYGUARD_API_KEY is not set"

Key not found on any of the three paths

fortyguard-mcp setup, or --where to see what was checked

[401] or [403]

Key rejected by the API

Check it in the FortyGuard dashboard

[402] insufficient credits

Balance exhausted

get_credit_usage for the real balance

Result "completed" with 0 tiles

Outside coverage, below the minimum area, or no data for that date

Still charged — check the AOI with validate_aoi

"cannot start … data directory could not be prepared"

FORTYGUARD_DATA_DIR unwritable

Point it somewhere writable

Report download refused, "not a public address"

The link named a private address

Expected. Set FORTYGUARD_REPORT_ALLOW_PRIVATE_HOSTS=true only for self-hosted storage

Tools

Tool

Costs credits?

What it does

get_credit_usage

no

Your plan, balance and per-endpoint breakdown, from the API

get_storage_info

no

What is archived locally, by endpoint, and where it lives

validate_aoi

no

Geodesic area, bounds, edge lengths, ring closure, coordinate order

split_aoi

no

Cut an area into pieces under a maximum you supply

create_heatmap

yes

Run a heatmap and wait inline (measured 21–38 s)

submit_heatmap

yes

Submit and return immediately with an activity_id

get_env_params

yes

Humidity, heat index, wet bulb, air quality at a point

submit_satellite

yes

Satellite land-cover segmentation

submit_streetview

yes

Street-view scene analysis

submit_heat_intelligence

yes

Full heat report as a PDF (3–7 min, never waited on inline)

check_status

no*

Collect a submitted analysis; free once collected

get_result_slice

no

Read part or all of a stored result: top_n, bbox, every_nth, columnar, geojson

* Polling itself is free — measured across calls taking 1 to 121 polls, all charged identically. Credits attach to the submitted task once, on success.

Resources

URI

Contents

fortyguard://account/usage

This key's plan and credits

fortyguard://storage

The local archive

fortyguard://result/{activity_id}

The complete untouched payload, uncapped

Result size is your choice, not ours

A large result is never truncated and never withheld. format decides:

format

Behaviour

auto (default)

the raw payload when it fits the context budget; otherwise a summary listing every route to the rest, including taking all of it

columnar

every tile as a compact table — no ceiling, roughly 12× smaller than raw

geojson

the untouched API payload — no ceiling

The budget applies to auto only, because auto is you declining to choose. Naming a format is you choosing, and it is honoured at whatever size the result comes to.

Supplying temperature

get_env_params and submit_heat_intelligence need a temperature matching the heatmap for the same place and time. Give either temperature= or from_activity_id= naming a completed heatmap — not both. Sourcing reads a stored result, so it costs nothing and also supplies the matching date, keeping the two consistent by construction. Supplying both is an error rather than a silent precedence rule, because the two can disagree and picking a winner would hide that.

Heat Intelligence reports

The API returns this analysis as a temporary signed URL, not as a document. check_status downloads the PDF before that link expires and returns the path:

"report": {
  "downloaded": true,
  "path": "/home/you/.local/share/fortyguard-mcp/reports/<activity_id>.pdf",
  "size_bytes": 960709,
  "content_type": "application/pdf"
}

The URL itself is never returned, logged, or archived. That is not merely tidiness: this URL should be treated as being as sensitive as your API key, not as a scoped capability that stops mattering once it expires. Anywhere the link lands is somewhere a credential has landed.

If the download fails, the analysis is still archived and the response says so plainly — the link is not recoverable, and re-running the analysis is charged again.

A real API request and response

Recorded live on 2026-08-23, verbatim. This exact exchange is in the repository as tests/fixtures/v1_heatmap/t2_5_exceedance.json, and the test suite replays it — so this is re-checkable rather than illustrative.

What was asked: how many hours on 15 July 2024, between 06:00 and 18:00 local, did each 100 m tile of a downtown-Phoenix block spend above 30 °C?

RequestPOST https://api.fortyguard.com/v1/heatmap (api-key header redacted):

{
  "polygon_aoi": {
    "type": "FeatureCollection",
    "features": [{
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [[
          [-112.095, 33.470], [-112.080, 33.470],
          [-112.080, 33.479], [-112.095, 33.479],
          [-112.095, 33.470]
        ]]
      }
    }]
  },
  "granularity": 100,
  "date_time": {
    "start_date": "2024-07-15",
    "start_time": "06:00",
    "end_time": "18:00",
    "filter_type": 2
  },
  "analytic_type": "exceedance",
  "threshold": 30,
  "direction": "above"
}

Submit response — the API is asynchronous, so this returns an id, not data:

{
  "error": false,
  "status_code": 200,
  "message": "Heatmap Submitted Successfully",
  "data": { "activity_id": "5ca4bab3-7ae2-463f-b7a9-8ab77bc5e6c0" }
}

Final pollGET /v1/status/5ca4bab3-7ae2-463f-b7a9-8ab77bc5e6c0, truncated to one of 112 tiles:

{
  "error": false,
  "status_code": 200,
  "data": {
    "activity_id": "5ca4bab3-7ae2-463f-b7a9-8ab77bc5e6c0",
    "status": "Completed",
    "result": {
      "map_data": {
        "type": "FeatureCollection",
        "features": [{
          "id": "0",
          "type": "Feature",
          "properties": { "tile_id": 0, "value": 12.0 },
          "geometry": {
            "type": "Polygon",
            "coordinates": [[
              [-112.09525400214712, 33.47190687658275],
              [-112.09418659710028, 33.47191630437707],
              [-112.09419749679817, 33.47278345511555],
              [-112.09526491247276, 33.47277402701284],
              [-112.09525400214712, 33.47190687658275]
            ]]
          }
        }]
      },
      "stats_data": {
        "activity_id": "5ca4bab3-7ae2-463f-b7a9-8ab77bc5e6c0",
        "analytic_type": "exceedance",
        "units": "hour",
        "n_cells": 112,
        "min": 12.0,
        "max": 12.0,
        "mean": 12.0
      }
    }
  }
}

The answer: every one of the 112 tiles was above 30 °C for all 12 hours requested. Cost, measured: 4,220 credits.

Through this server, that whole exchange — submit, poll until complete, archive, shape to fit the context window — is one create_heatmap call.

What does not work yet

Stated plainly, because knowing the edges is more useful than a feature list.

Not built

  • No remote/hosted mode. The server speaks stdio and is launched as a local subprocess. --transport sse|streamable-http exists but has no authentication and no per-caller isolation, so it is not a supported deployment — see Serving over a network.

  • No cost estimation. Deliberate: per-call cost varies by plan, and a lookup table built from one account would confidently mislead every other one. Use get_credit_usage for your real balance.

  • No geocoding. Areas of interest are GeoJSON. There is no "Phoenix downtown" → polygon step; the agent supplies coordinates.

  • No caching of failed or in-flight work. Only completed results are archived.

  • No automatic retry. A transport failure is reported, not retried.

Known limits, measured against the live API

  • United States only. Areas outside coverage return a successful response with zero tiles and are still charged. The server says so explicitly, but it cannot prevent the charge — coverage is not published as a queryable map.

  • 60 m is the finest granularity, despite marketing describing ~20 m.

  • Empty results are billed — sub-minimum areas, dates with no data, and times past the forecast edge all return Completed with zero tiles at full price.

  • Some requests never reach a terminal state. Very large areas and out-of-range dates were still Processing after ~8 minutes. Every wait is bounded for this reason, and returns the activity_id.

  • start_time is local to the area of interest, not UTC. Undocumented by the vendor and easy to get wrong.

  • No published accuracy figures. No RMSE, MAE or bias for FortyGuard's models is publicly available, and we found no independent validation. Treat outputs as a relative heat surface, not as calibrated ground truth.

  • Compact encoding uses tile centroids, accurate to about a centimetre, not exact polygon rings. Request format="geojson" for exact geometry.

  • The archive grows without bound. Nothing is evicted, by design — results cost credits and never go stale. FORTYGUARD_MAX_STORAGE_BYTES caps it if you need that; get_storage_info shows what is there.

Verified platform support

Linux, macOS and Windows; Python 3.11–3.14. CI covers all three on 3.14 and Linux across every version. Windows was the development machine.

Stored data

Results are written to a durable data directory, not a cache directory:

Path

Windows

%LOCALAPPDATA%\fortyguard-mcp\

macOS

~/Library/Application Support/fortyguard-mcp/

Linux

~/.local/share/fortyguard-mcp/

results/<activity_id>.json        the payload
results/<activity_id>.meta.json   endpoint, request, size, hash
reports/<activity_id>.pdf         files fetched from a signed URL
index/<request_hash>              request -> activity_id, for the cache

Nothing is evicted. Results cost credits and never go stale, so deleting them to reclaim cheap disk would cost real money to undo. Cache directories get reclaimed by the OS under disk pressure, which is exactly why this isn't one. The directory is plain files and safe to delete whenever you like — you lose only the ability to avoid re-paying for those queries.

API keys and pre-signed URLs are stripped before anything is written, and stored payloads are always valid JSON: non-finite numbers are nulled on the way in and the count is recorded on the sidecar, so the archive never quietly differs from what the API sent.

Security

The server treats everything it did not originate as untrusted — including the API's own responses.

  • Credentials never leave. The API key is redacted from every log record, every tool response and everything written to disk. Pre-signed URLs are treated the same way: the report URL is as sensitive as the key itself, so it is fetched and then destroyed rather than stored.

  • Downloads are scoped to the public internet. A download_link in an API response is a URL chosen by something outside this process. Every hop, redirects included, is resolved and refused if it points at a loopback, link-local, private or reserved address — so a malformed or hostile response cannot use this server to read your cloud metadata endpoint or an internal admin port. FORTYGUARD_REPORT_ALLOW_PRIVATE_HOSTS=true opts out for self-hosted storage.

  • Agent input never builds a URL or a path. activity_id is percent-encoded before it enters the status path, and every filename is sanitised with a digest appended when sanitising changes it, so two ids cannot collide.

  • https is required for FORTYGUARD_BASE_URL unless it is loopback: the key travels as a header on every request.

  • Several API keys can share one machine. Every stored result is stamped with a digest of the key and base URL that paid for it, and a key only ever reads back its own — by request, by activity_id, or by resource URI. A staging base URL likewise never answers with production data.

  • Bounded by default. Response bodies, report downloads, redirect chains, GeoJSON nesting depth and poll waits all have ceilings, so a broken or hostile upstream cannot exhaust memory, disk or the event loop.

Found something? Please open a security advisory on the repository rather than a public issue.

Logging

Diagnostics are written to stderr as one JSON object per line:

{"ts":"2026-08-26T00:46:17.007+00:00","level":"INFO","logger":"fortyguard_mcp.server","msg":"fortyguard-mcp starting"}

Never to stdout — under the stdio transport that is the JSON-RPC channel, and a single stray byte corrupts the stream. A test drives a real subprocess and asserts every line of stdout parses as JSON-RPC.

The API key and any pre-signed URLs are stripped from every record, including exception text and third-party loggers. The protocol's own logging capability (notifications/message) is deliberately unused: it is deprecated as of protocol version 2026-07-28, and the SDK drops messages the client did not opt into. Progress notifications during long polls are a separate mechanism and are still sent.

Verifying an install

With the MCP Inspector:

npx @modelcontextprotocol/inspector --cli --config your-config.json --server fortyguard --method tools/list

Expect 12 tools, 2 resources and 1 resource template. validate_aoi is the safest smoke test — it is local and costs nothing.

Serving over a network

The default and supported transport is stdio: the client launches the server as a local subprocess. --transport sse and --transport streamable-http exist but print a warning, because everything above assumes a single local user:

There is no authentication, no per-caller isolation and no rate limiting. Anyone who can reach the port can spend your credits and read your archive.

If you need it, bind to loopback behind an authenticating reverse proxy.

Development

pip install -e ".[dev]"
pytest                          # 540 tests, fully offline — no API key, no credits
ruff check .
mypy src

The suite runs against a replay server built from 50 real recorded API exchanges, so it is deterministic, free, and green even when the API is unreachable.

Two cross-checks need extra libraries and are kept in their own extra, because they verify the two numbers this package quotes most — the geodesic area agreement with pyproj, and the chars-per-token ratios that decide whether a payload is inlined:

pip install -e ".[dev,verify]"  # adds pyproj + tiktoken; nothing should skip

CI runs the suite on Python 3.11–3.14 (Linux, plus Windows and macOS at 3.14), type-checks, lints, builds both artifacts, installs the wheel into a clean venv, and runs the cross-check job separately.

Run mypy in an environment holding only this package's dependencies. A dev box that also has numpy installed trips over numpy's stubs, which use 3.12-only syntax; nothing in src/ imports numpy.

Further reading

  • MEASUREMENTS.md — the measured API envelope: costs, durations, enums, error taxonomy, determinism. Every value measured live, with the recorded exchanges in tests/fixtures/ so each is re-checkable offline.

  • CHANGELOG.md — including the security review this release came out of

Provenance

Built for the FortyGuard "Building the World's Temperature AI" hackathon (kickoff 18 Aug 2026). All source in this repository was written after kickoff, between 22 and 28 Aug 2026. No pre-existing boilerplate was carried in; the project depends only on the third-party packages declared in pyproject.toml (mcp, httpx, pydantic, pydantic-settings, platformdirs).

The 50 recorded API exchanges in tests/fixtures/ are real responses from the live FortyGuard API, captured during the build with the api-key header redacted at record time.

Licence

MIT

Available Tools

12 tools
check_statusA

Check on a submitted analysis, or wait for it. If it has finished, the result comes back and is archived locally. Polling is free and the job runs whether or not you poll. Once collected, calling this again is served from disk at no cost.

ParametersJSON Schema
NameRequiredDescriptionDefault
formatNoauto, geojson, or columnar.auto
wait_sNoSeconds to wait for completion. 0 checks once and returns immediately.
activity_idYesFrom a submit_* call.

TDQS

A4.1/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral burden, and it does well. It discloses that results are archived locally, that polling is free, that the job runs independently of polling, and that repeat calls are served from disk. These are meaningful behavioral traits beyond 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.

Conciseness5/5

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

Three sentences, each adding distinct value: core action, result handling, and cost/behavior semantics. The most important information is front-loaded and there is no wasted text.

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 polling/status tool with three well-documented parameters, the description covers the essential behaviors: what happens on completion, persistence, and cost. An output schema is absent, but the description does not fully describe the result structure or error cases. Mostly complete, with minor gaps.

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 even without extra parameter detail. The description adds only general context about waiting and results, while the schema already documents format, wait_s, and activity_id. It does not materially enhance parameter understanding.

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 clearly states the tool checks on a submitted analysis and can wait for completion, with the result returned once finished. It identifies the resource (submitted analysis) and the action (check/wait), but does not explicitly differentiate it from sibling tools like get_result_slice. This is clear but lacks direct sibling distinction.

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 gives practical guidance: polling is free, the job runs regardless of polling, and repeated calls after collection are served from disk at no cost. This implies use after a submit_* call and encourages polling, but does not explicitly state when to prefer alternatives like get_result_slice. Clear context but no exclusions.

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

create_heatmapA

Run a temperature heatmap and wait for the result inline. Measured heatmaps take 21-38 seconds. If the wait runs out you get the activity_id back and nothing is lost - the job keeps running and check_status collects it. An identical earlier request is served from the local archive for free. filter_type: 1 = single hour (start_date + start_time); 2 = range of hours, same day (start_date + start_time + end_time); 3 = single day (start_date only); 4 = range of days (start_date + end_date). granularity is the tile edge in metres (60, 80, 100); omit it to let the API choose. analytic_type is optional (tcm, time_of_measure, exceedance, persistence); omit it for plain temperature. start_time is interpreted as local time at the area of interest, not UTC.

ParametersJSON Schema
NameRequiredDescriptionDefault
formatNoauto = the raw API payload when it fits the context budget, otherwise a summary naming every way to fetch it. geojson = the raw payload whatever its size. columnar = a compact table, about 12x smaller.auto
wait_sNoSeconds to wait inline before returning the activity_id instead.
end_dateNo
end_timeNo
directionNo
thresholdNo
start_dateNo
start_timeNoHH:MM, local to the area, not UTC.
filter_typeNo1 = single hour (start_date + start_time); 2 = range of hours, same day (start_date + start_time + end_time); 3 = single day (start_date only); 4 = range of days (start_date + end_date)
granularityNoTile edge in metres: 60, 80, 100.
polygon_aoiYesArea of interest as GeoJSON.
analytic_typeNoOptional analytic: tcm, time_of_measure, exceedance, persistence.

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations provided, the description bears full responsibility for disclosing behavior. It does this well: expected duration (21-38s), timeout behavior (returns activity_id, job keeps running), idempotent caching for identical earlier requests, and the important local-time interpretation of start_time. The absence of error-handling or quota details keeps it from a 5.

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?

The description is dense but well-structured: behavior first, timing details second, then parameter meanings. Some material duplicates the schema's filter_type text, which costs a little efficiency, but every sentence serves a practical purpose and the critical timeout/archive behavior 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?

For a 12-parameter tool with no output schema, this description covers the workflow well: inline wait, timeout fallback, later retrieval via check_status, archive reuse, filter modes, granularity, analytic_type, and local-time semantics. It does not describe the successful inline return payload or clarify direction/threshold, but the overall invocation context is mostly complete.

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 description restates filter_type combinations and granularity defaults that already appear in the schema, and adds useful 'omit it' guidance for granularity and analytic_type. However, direction and threshold are unexplained in both schema and description, and schema coverage is only 58%. This adds some value beyond the schema but leaves significant parameter semantics to inference.

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 opens with a specific verb and resource: 'Run a temperature heatmap and wait for the result inline.' This clearly differentiates from sibling tools like submit_heatmap (which likely returns immediately) and check_status (which collects results later). It is not a tautology and conveys the tool's core behavior.

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 tells the agent when the inline-wait model applies, what happens on timeout, and that check_status can later collect the activity_id. It also notes that duplicate requests are served from the local archive. It does not explicitly name submit_heatmap as the alternative for fully asynchronous submission, but the wait/timeout behavior strongly implies the tradeoff.

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

get_credit_usageA

Your account's plan, credit balance, and per-endpoint usage breakdown, straight from the API. This is the authority on what your key can do - area limits and endpoint access vary by plan and are not assumed anywhere in this server.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It usefully explains that this is a live, authoritative view of account capabilities, and that area limits and endpoint access vary by plan. However, it does not explicitly state the operation is read-only/no side effects, nor does it mention any authentication requirements or response format nuances.

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 compact sentences deliver all necessary information with no filler. The first sentence immediately states what the tool returns, and the second adds authoritative context about plan-dependent limits. Every sentence 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?

For a zero-parameter, no-output-schema tool with no annotations, the description is complete enough for an agent to know exactly what this tool provides and why it should consult it. It covers the return contents (plan, balance, per-endpoint usage), the authority of the data, and the variability of limits by plan.

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?

The tool has zero parameters, so there are no parameter semantics to document. The description instead focuses on what the tool returns, which is appropriate. This matches the baseline for zero-parameter tools.

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 resource (account plan, credit balance, per-endpoint usage breakdown) and clarifies this tool is the authoritative source for key capabilities. This distinguishes it from siblings like get_storage_info or submit_heatmap, which clearly serve different purposes.

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 clearly indicates when to use this tool: whenever you need authoritative plan limits, credit balance, or endpoint access details. It explicitly says these are 'not assumed anywhere in this server', giving the agent a strong signal to call this before making assumptions. It does not name specific alternative tools or provide explicit when-not-to-use guidance, 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_env_paramsA

Environmental parameters at a single point - humidity, heat index, wet bulb, air quality and more. Requires a temperature, which must match the heatmap for the same place and time. Supply it either as temperature=, or as from_activity_id= naming a completed heatmap covering this point, which also supplies the matching date. Give one or the other, not both. Narrow the response with analysis=, or omit it to receive every parameter.

ParametersJSON Schema
NameRequiredDescriptionDefault
wait_sNo
analysisNoWhich parameters to return. Omit for all of them (verified). Values: heat_index_celsius, apparent_temperature_celsius, wet_bulb_temperature_celsius, relative_humidity_percent, precipitation_mm, cloud_cover_octas, elevation, solar_irradiance, air_quality:idx, air_quality_pm2p5:idx, air_quality_pm10:idx, air_quality_no2:idx, air_quality_o3:idx, air_quality_so2:idx, aqi_us_co, methane_ppb, co2_ppm. NOTE these are NOT the sections submit_heat_intelligence takes - that endpoint uses a different vocabulary.
latitudeYesDecimal degrees.
longitudeYesDecimal degrees.
start_dateNo
start_timeNo
filter_typeNo1 = single hour (start_date + start_time); 2 = range of hours, same day (start_date + start_time + end_time); 3 = single day (start_date only); 4 = range of days (start_date + end_date)
temperatureNoDegrees Celsius. Mutually exclusive with from_activity_id.
from_activity_idNoA completed heatmap to read the temperature and date out of. Free - no API call. Mutually exclusive with temperature.

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the disclosure burden and does meaningful work: it reveals the heatmap-matching requirement, that from_activity_id is free and supplies the date, that the two temperature inputs are mutually exclusive, and that omitting analysis returns every parameter. It stops short of describing error behavior or the response envelope, but covers the non-obvious constraints.

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 with no filler: the first states what the tool returns, the second states the core precondition and how to satisfy it, and the third explains response narrowing. Key constraints are front-loaded.

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?

The description is strong on the temperature/activity path but leaves a notable gap: it says the temperature must match 'the same place and time' and that from_activity_id supplies the date, yet it never explains how to specify the time when using temperature= directly. With no output schema and no annotations, a mention of filter_type/start_date/start_time or the response structure would make it fully complete.

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 67%, and the description adds semantics beyond the schema: mutual exclusivity of temperature and from_activity_id, the date-providing role of from_activity_id, and the narrowing effect of analysis. It does not add meaning for wait_s or start_date/start_time, but the schema already documents the remaining core parameters.

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 opens with a concrete resource ('Environmental parameters at a single point - humidity, heat index, wet bulb, air quality and more') and a clear action (get). This distinguishes it from sibling submit/validate tools and makes the tool's purpose immediately actionable.

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 explicitly states the precondition (a temperature matching the heatmap), offers two mutually exclusive ways to satisfy it (temperature= or from_activity_id=), and explains when to omit analysis. It does not name alternative read tools such as get_result_slice, but the guidance for this tool's own options is specific and unambiguous.

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

get_result_sliceA

Read part or all of an already-collected result from local disk. Costs nothing and makes no API call, so use it freely: take the hottest tiles with top_n, a sub-area with bbox, a downsample with every_nth, the whole thing compactly with format='columnar', or the untouched payload with format='geojson'. Naming a format gets you all of it at whatever size it comes to; the context budget applies only to the default format='auto'. Statistics for both the slice and the full result are always reported, so a slice maximum is never mistaken for the real one.

ParametersJSON Schema
NameRequiredDescriptionDefault
bboxNo[west, south, east, north]. West may exceed east to cross the antimeridian.
top_nNoReturn only the N highest-valued tiles.
formatNoauto = fit it to the context budget, and if it does not fit, say what exists and how to fetch it. columnar = the compact table in full, whatever its size. geojson = the raw payload in full, whatever its size. Both named formats are delivered complete - the budget applies to auto only.auto
every_nthNoKeep every Nth tile.
activity_idYesA collected analysis.

TDQS

A4.8/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full transparency burden. It goes well beyond a basic read description by disclosing: no API call and no cost, complete delivery of named formats versus context-budgeted auto mode, and that statistics for both the slice and full result are always reported. This prevents common misuses, like mistaking a slice maximum for the true maximum.

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 earns its place: purpose, cost/safety, paramter usage, format/budget caveat, and output statistics are each covered exactly once. The key behavioral trait (free/no API call) is front-loaded so an agent can immediately classify this as a cheap read operation.

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 5 parameters, no annotations, and no output schema, the description is remarkably complete: it explains all slicing modes, format behavior and the context-budget nuance, and the statistics guarantee. The input schema covers antimeridian bbox and parameter types, so nothing essential is left unexplained for an agent to call this correctly.

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

Parameters5/5

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

Although schema coverage is 100% (baseline 3), the description adds substantial operational meaning beyond the schema: top_n is for "the hottest tiles," bbox for a "sub-area," every_nth for "a downsample," and the formats are mapped to concrete outcomes ("compact" vs "untouched payload"). This gives an agent a practical understanding of how to shape each parameter, not just its type.

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 opens with a specific verb and resource: "Read part or all of an already-collected result from local disk." It clearly distinguishes this from sibling submission/creation tools by noting it "makes no API call" and reads "already-collected" results. The description also enumerates the different slicing modes, leaving no ambiguity about what the tool does.

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 gives clear when-to-use guidance: since it "Costs nothing and makes no API call, so use it freely." It also implicitly signals when-not: this is for already-collected results, not for starting new analyses, unlike sibling submit_* and create_* tools. However, it does not explicitly name the alternative tools or state "use submit_* instead when you need a new analysis," so it stops short of a full when-not/alternatives specification.

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

get_storage_infoA

What this server has archived on local disk: how many results, broken down by endpoint, how much space they take, any report files downloaded from signed URLs, and where all of it lives. Nothing is ever deleted automatically - stored results cost money and never go stale, so the directory is yours to manage.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral disclosure burden. It meaningfully explains that nothing is ever deleted automatically, that stored results persist and cost money, and that the directory is user-managed. It does not cover auth needs or rate limits, but for a simple read-only storage summary the key behavioral traits are disclosed.

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 two sentences, front-loaded with the primary output summary and followed by a useful behavioral note about persistence and cost. Every sentence adds distinct value with 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 annotations, parameters, and an output schema, the description covers all essential aspects: what data is returned, where it lives, and how it behaves over time. It could be more explicit about the exact return format, but for a no-argument storage information tool it is sufficiently complete.

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?

The tool has zero parameters, so the description does not need to explain parameter meaning. The input schema is empty and the description fully describes what the call returns; a baseline of 4 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 specifies a clear resource (local disk archive) and states exactly what the tool reports: result counts by endpoint, space usage, downloaded report files, and storage location. It is easily distinguished from siblings like get_credit_usage or get_result_slice, which address different concerns.

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 the tool is for inspecting and managing archived storage, but it does not explicitly state when to choose this tool over alternatives or mention any exclusions. The intended usage is evident from context, but the guidance is not made explicit.

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

split_aoiA

Cut an area of interest into a grid of smaller areas, each at or under a maximum size you specify. Use it when the API rejects an area as too large. There is no default maximum: the cap depends on your plan, so take it from your contract or from the API's own rejection message. Local computation, no credits.

ParametersJSON Schema
NameRequiredDescriptionDefault
polygon_aoiYesThe area to split, as GeoJSON.
max_area_km2YesMaximum area per piece, in square kilometres. Required - this server does not assume your plan's limit.

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations on the tool, the description carries the full behavioral disclosure burden. It usefully states 'Local computation, no credits' and explains that there is no default maximum cap. It does not describe the output format or potential failure modes, which would be needed for a 5.

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 with a distinct purpose: the action, the appropriate use case, and the cap/credit caveats. There is no filler, and the most important information is front-loaded.

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

Completeness4/5

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

For a two-parameter local utility, the description covers the core purpose, when to use it, parameter nuance, and cost behavior. It does not specify the exact return contract, but 'grid of smaller areas' sets a reasonable expectation. A 5 would explicitly state the return payload or edge cases.

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?

The schema already documents both parameters with 100% coverage, so the baseline is 3. The description adds value specifically for max_area_km2 by explaining that the cap depends on plan and should be taken from contract or rejection messages. polygon_aoi receives minimal added meaning beyond 'area of interest,' but the overall parameter guidance is improved.

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 opens with a specific verb and resource: 'Cut an area of interest into a grid of smaller areas, each at or under a maximum size you specify.' This makes the function's purpose immediately clear. It does not explicitly name or contrast sibling tools such as validate_aoi, so it stops short of full differentiation.

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 gives an explicit trigger condition: 'Use it when the API rejects an area as too large.' It also provides practical guidance about deriving the max area from the contract or rejection message. It lacks an explicit 'when not to use' or named alternatives, which prevents a perfect score.

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

submit_heat_intelligenceA

Submit a heat intelligence report for a point and return an activity_id. This one is slow - measured at about 395 seconds - so it is never waited on inline. Collect it with check_status, which downloads the PDF to local disk and returns its path under 'report'; the API delivers this analysis as a short-lived signed URL, which is never returned or stored. Needs a temperature: give temperature= or from_activity_id=, not both. analysis is required - pass all five categories for a complete report.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoYYYY-MM-DD.
analysisYesReport sections to include, at least one: geographic, environmental, urban, events, anthropogenic. Pass all five for a complete report. NOTE these are NOT the measurement names get_env_params takes - that endpoint uses a different vocabulary and does not require this.
latitudeYesDecimal degrees.
longitudeYesDecimal degrees.
temperatureNoDegrees Celsius. Mutually exclusive with from_activity_id.
from_activity_idNoA completed heatmap to read temperature and date from. Free. Mutually exclusive with temperature.

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and delivers: it discloses the ~395 second latency, the async expectation, the short-lived signed URL that is never stored, and exactly how the PDF is retrieved and delivered. This is far beyond the schema's structural information.

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?

Four dense sentences, each earning its place: action/return, latency, collection workflow, and parameter constraint. The most decision-relevant facts are front-loaded before workflow details.

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 six-parameter async submit tool with no output schema and no annotations, the description covers the full lifecycle: submission, latency, retrieval, result location, and parameter invariants. An agent has enough to call it correctly and know what to do afterward.

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; the description adds real value by stating that a temperature source is mandatory (temperature or from_activity_id, not both) even though neither is marked required in the schema. It also reinforces the complete-report requirement, though the schema already documents the five analysis categories.

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 first sentence states a specific action and resource: submit a heat intelligence report for a point, with an explicit return (activity_id). It also distinguishes the tool from its companion sibling by directing collection to check_status, so an agent can tell submission from retrieval.

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 gives clear operational guidance: never wait inline, collect via check_status, and provide exactly one of temperature or from_activity_id. It does not explicitly contrast this tool with the sibling submit_heatmap/satellite/streetview tools, so it stops short of full when-not/alternative coverage.

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

submit_heatmapA

Submit a temperature heatmap over an area and return immediately with an activity_id, without waiting for it to finish. Use this when you have other work to do, or for a large area. Collect it with check_status. If this exact request was run before, the stored result comes back straight away instead of an activity_id, marked from_archive, and costs nothing. filter_type: 1 = single hour (start_date + start_time); 2 = range of hours, same day (start_date + start_time + end_time); 3 = single day (start_date only); 4 = range of days (start_date + end_date). granularity is the tile edge in metres (60, 80, 100); omit it to let the API choose. analytic_type is optional (tcm, time_of_measure, exceedance, persistence); omit it for plain temperature. start_time is interpreted as local time at the area of interest, not UTC.

ParametersJSON Schema
NameRequiredDescriptionDefault
end_dateNoYYYY-MM-DD, for filter_type 4.
end_timeNoHH:MM, for filter_type 2.
directionNo
thresholdNo
start_dateNoYYYY-MM-DD.
start_timeNoHH:MM, local to the area, not UTC.
filter_typeNo1 = single hour (start_date + start_time); 2 = range of hours, same day (start_date + start_time + end_time); 3 = single day (start_date only); 4 = range of days (start_date + end_date)
granularityNoTile edge in metres: 60, 80, 100.
polygon_aoiYesArea of interest as GeoJSON.
analytic_typeNoOptional analytic: tcm, time_of_measure, exceedance, persistence.

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It transparently states the asynchronous return behavior, the archive/cache behavior with from_archive and zero cost, and the local-timezone interpretation of start_time. It could add cost/rate or failure details, but the essential behavioral traits are disclosed.

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 information-dense and every sentence adds value: purpose, when-to-use, result collection, archive behavior, and parameter semantics. It front-loads the most important async behavior and remains readable despite covering several nuanced options.

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 complex tool with 10 parameters, no annotationns, and no output schema, the description covers the central return contract, filtering modes, optional parameters, and timezone handling. The main gaps are direction and threshold semantics and a bit more shape detail for polygon_aoi, but the tool remains usable with this definition.

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 description coverage is high at 80%, and the description adds value by clarifying filter_type mapping to date/time fields, granularity omission behavior, analytic_type omission behavior, and local-timezone semantics. It does not explain direction or threshold, but those are optional and not heavily behooped.

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 a specific verb and resource: submit a temperature heatmap over an area, returning an activity_id immediately instead of waiting for completion. This distinguishes the tool from synchronous alternatives and clarifies its core purpose without ambiguity.

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?

Explicit usage guidance is provided: 'Use this when you have other work to do, or for a large area.' It also directs the agent to collect results via check_status and explains the cached-result behavior. It does not explicitly contrast with create_heatmap or other submit tools, but the when-to-use criteria are clear.

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

submit_satelliteA

Submit satellite land-cover segmentation for a point and return an activity_id. Collect it with check_status.

ParametersJSON Schema
NameRequiredDescriptionDefault
latitudeYesDecimal degrees.
longitudeYesDecimal degrees.
start_dateNo
start_timeNoHH:MM, local to the point, not UTC.
filter_typeNo1 = single hour (start_date + start_time); 2 = range of hours, same day (start_date + start_time + end_time); 3 = single day (start_date only); 4 = range of days (start_date + end_date)
granularityNoTile edge in metres: 60, 80, 100.

TDQS

A4.1/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses the asynchronous nature by stating 'return an activity_id. Collect it with check_status,' which tells the agent this is a job-submission operation rather than a direct result fetch. It does not mention side effects, credits, or validation requirements, but the core behavioral contract is transparent.

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 two short sentences with no filler. 'Submit satellite land-cover segmentation for a point' is front-loaded and immediately states the action and resource, while the second sentence efficiently links to check_status. Every word earns its place.

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 6 parameters, no output schema, and no annotations, the description gives the essential workflow—submit and poll via check_status—but omits context such as whether the point must be inside a previously validated AOI, how long processing might take, or any credit/cost implications. The schema covers parameter formats, so basic invocation is possible, but a fully informed agent would need more context.

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 83%, which is high, so the schema already documents most parameters. The description adds only the notion of 'a point' (latitude/longitude) and provides no additional detail about optional parameters like filter_type, start_date, or granularity. This meets the baseline for high schema coverage but adds no extra semantic 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 states a specific verb and resource: 'Submit satellite land-cover segmentation for a point.' It clearly identifies what the tool does and distinguishes it from sibling submission tools like submit_streetview and submit_heatmap through the 'satellite land-cover segmentation' resource. It also names the return artifact (activity_id), making the tool's role 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?

The description gives clear context: use this tool to submit satellite land-cover segmentation for a point, and then collect the result via check_status. It does not explicitly list when not to use it or name alternatives, but the resource type and follow-up instruction provide enough guidance for an agent to select it among siblings.

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

submit_streetviewA

Submit street-view scene analysis for a point and return an activity_id. Collect it with check_status.

ParametersJSON Schema
NameRequiredDescriptionDefault
latitudeYesDecimal degrees.
back_viewYesAlso analyse the opposing direction.
longitudeYesDecimal degrees.
vertical_angleYesCamera pitch in degrees. 10 is a normal street-level view.
horizontal_angleYesField of view in degrees, 0-360. 90 is a normal street-level view.

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral disclosure burden. It explicitly reveals the asynchronous pattern: the tool returns an activity_id rather than a direct result, and the result must later be collected via check_status. This is a key operational trait that an agent needs to know. It does not mention cost, permissions, or failure modes, but the core submit-then-poll behavior is transparently conveyed.

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 zero redundant wording. The primary action and output are front-loaded, and the follow-up instruction to use check_status is short and direct. Every word adds value.

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 submit-style asynchronous tool with no output schema, the description sufficiently explains what is returned and how to retrieve the eventual result. All required parameters are fully documented in the schema. A minor gap is the lack of any mention of whether this operation consumes credits or requires a valid AOI, but the core invocation flow is complete.

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 covers all 5 parameters with descriptive text, so schema coverage is 100%. The description adds context that the parameters describe a street-view point and scene analysis, but it does not add meaning beyond the schema's own parameter descriptions. This meets the baseline for schema-heavy documentation but does not exceed it.

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 action ('Submit street-view scene analysis') applied to a resource ('a point') and the expected output ('return an activity_id'). It clearly identifies that this is the street-view variant among sibling submit tools like submit_satellite and submit_heatmap, so an agent can distinguish it without opening schemas.

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

Usage Guidelines4/5

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

The description gives clear usage context: submit analysis, get an activity_id, then collect with check_status. It does not explicitly enumerate when to choose this over submit_satellite or submit_heatmap, but the resource type is implicit in the name and description, providing adequate direction. No exclusions or alternative conditions are stated, so an agent must infer modality from the tool name.

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

validate_aoiA

Measure a GeoJSON area of interest locally: geodesic area in km2 and square miles, bounding box, edge lengths, ring closure, and whether the coordinates look transposed. Costs nothing and makes no API call. It reports only - no size limit is applied, because limits vary by plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
polygon_aoiYesGeoJSON FeatureCollection, Feature, Polygon or MultiPolygon.

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the full behavioral burden and does well: it states that the tool costs nothing, makes no API call, only reports, and applies no size limit. It also discloses the heuristic nature of the transposition check with 'look transposed.' Minor omissions like handling of invalid GeoJSON or exact output formatting prevent a higher score.

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 earning its place: the first lists outputs, the second covers cost and network behavior, the third explains the no-limit policy. Key information is front-loaded and there is 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?

The description is complete for a single-parameter reporting tool: it explains the purpose, the local execution, the lack of side effects, and the boundary around size limits. There is no output schema, but the description sufficiently conveys the kind of measurements returned, so an agent can anticipate the result without needing a full return-value spec.

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 schema already fully documents the single parameter as a GeoJSON FeatureCollection, Feature, Polygon, or MultiPolygon. The description adds that the parameter is an 'area of interest' and that it is measured locally, but does not add format details beyond the schema. This meets the baseline for full schema coverage.

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 verb ('Measure') and resource ('GeoJSON area of interest') and lists concrete outputs: geodesic area, bounding box, edge lengths, ring closure, and transposition check. It also distinguishes itself from siblings by noting it runs locally and makes no API call, which separates it from the submit_* tools.

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 conveys when to use this tool: as a local, cost-free pre-flight check of an AOI before submission. It implies a validation workflow and notes that no size limit is applied because limits vary by plan, giving useful context. It does not explicitly name sibling alternatives like split_aoi, but the local/no-API-call framing makes the appropriate use clear.

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

TDQS

A4.2/5.0
Disambiguation4/5

Most tools target distinct resources or actions: AOI helpers, retrieval, point analyses, and heatmap jobs are all clearly separated. The one genuinely confusable pair is submit_heatmap vs create_heatmap, which run the same operation with only the waiting behavior differing.

Naming Consistency4/5

The set mostly follows clean get_* and submit_* conventions, with validate_aoi and split_aoi fitting the verb_object pattern. The exception is create_heatmap, which breaks the submit_* async pattern even though it creates the same kind of job.

Tool Count5/5

With 12 tools the server is well-scoped for its domain: account/storage introspection, AOI prepping, sync and async heatmap submission, point analyses, status polling, and local result access are all represented. Nothing feels redundant or superfluous.

Completeness4/5

The core workflow is fully covered: prep the AOI, submit or create heatmaps and point analyses, poll with check_status, and read results from disk. Minor gaps include no way to enumerate all previously submitted jobs and no deletion tool for archived results, though storage is explicitly left to the user.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Exposes public weather and climate data through a standardized API, allowing AI agents to retrieve current conditions, 7-day forecasts, and historical data. It enables weather-aware automation and data enrichment for conversational agents and travel planning.
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides AI agents with access to CO2 emissions data, climate projections, and risk assessments for heat, flooding, and drought, supporting ESG analysis and CSRD compliance.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides free energy intelligence APIs for AI agents: solar production estimates, US clean-energy incentives by ZIP, home Energy Node Scores, contractor search, and consented installer routing.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MohamedXAdel/fortyguard-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server