mcp-stargazing
You can use this MCP server to calculate celestial facts, fetch weather, analyze stargazing locations, plan equipment-aware observing sessions, and manage background area-analysis tasks.
Calculate altitude/azimuth, rise/set times, Moon phase/illumination, visible planets, and constellation-center positions for a time and place.
Get a nightly target forecast with Moon, visible planets, deep-sky objects, and a civil-dark night window.
Fetch aggregated current, hourly, and daily weather by place name or coordinates.
Query light-pollution grids and analyze regions for dark, accessible stargazing spots with pagination and caching.
Submit, poll, cancel, and page results for bounded background area-analysis tasks.
Rank telescope/astrophotography targets and generate single-night imaging schedules.
Use
plan_stargazing_sessionas the preferred end-to-end planner for 1–7 nights, including location, equipment preset/overrides, observation style, evidence, uncertainties, and next actions; compatibility bbox planners are also available.Inspect tool metadata/catalog and retrieve server-local datetime/timezone information.
Receive standardized JSON envelopes, structured errors, caching, async execution, and proxy support for astronomical data downloads.
Utilizes NumPy for numerical calculations involved in celestial positioning and astronomical computations.
Implements testing framework for validating celestial calculations and time/location utilities.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-stargazingwhat's visible in the night sky from New York tonight?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-stargazing
Calculate the altitude, rise, and set times of celestial objects (Sun, Moon, planets, stars, and deep-space objects) for any location on Earth, with optional light pollution analysis.
Features
Altitude/Azimuth Calculation: Get elevation and compass direction for any celestial object.
Rise/Set Times: Determine when objects appear/disappear above the horizon.
Light Pollution Analysis: Load and analyze light pollution maps (GeoTIFF format).
Composite Planning: Build a ranked observing plan that combines place quality, weather, moonlight, and top targets.
Tool Discovery: Inspect registered MCP tools programmatically through
get_tool_catalog.Code Execution Ready:
Serializable Returns: All tools return JSON-serializable data (ISO strings for dates), making them directly usable by LLMs.
Pagination:
analysis_areasupports paging (page,page_size) to handle large datasets efficiently.Stable Result Handles:
analysis_area.resource_ididentifies the cached non-pagination query so agents can fetch multiple pages safely.Standardized Responses: Successful calls return
{ "data": ..., "_meta": ... }; business validation failures return{ "error": ..., "_meta": ... }.
Performance:
Async Execution: Non-blocking celestial calculations.
Caching: Intelligent caching for Simbad queries and regional analysis.
Proxy Support: Native support for HTTP/HTTPS proxies (useful for downloading astronomical data).
Time Zone Aware: Works with local or UTC times.
Data Driven: Integrated database of 10,000+ deep-sky objects (Messier & NGC) for smart recommendations.
Related MCP server: Satellite MCP Server
Installation
This project uses uv for dependency management.
Local Installation
Install
uv:pip install uvSync dependencies:
uv syncThis will create a virtual environment in
.venvand install all dependencies defined inpyproject.toml.Activate the environment:
source .venv/bin/activateInitialize Data (Required for Nightly Planner): This downloads the latest Messier and NGC catalog data to
src/data/objects.json.python scripts/download_data.pyNote: If you are behind a firewall, ensure
HTTP_PROXYenv var is set before running this script.
Docker Installation
You can also run the server using Docker, which handles all dependencies and data initialization automatically.
Docker catalog downloads use the official simbad.harvard.edu mirror. Override with
--build-arg SIMBAD_SERVER=simbad.cds.unistra.fr to use the Strasbourg service.
Standalone downloads retain the astroquery default unless SIMBAD_SERVER is set.
The selected server is tried first; failed connection/query batches retry once and
switch to the other official mirror. Subsequent batches prefer the working mirror.
Downloads use bounded, indexed TAP queries with explicit asynchronous execution,
avoiding astroquery 0.4.11's uploaded-name query path (which drops async_job).
An empty batch or failure of both mirrors aborts rather than publishing a partial catalog.
Connection probes have a 5-second connect and 15-second read timeout; asynchronous
jobs have a 180-second execution limit. macOS Python can inherit the system proxy
even without proxy environment variables; use process-local NO_PROXY=* only when
deliberately testing direct connectivity. A successful small query does not verify
the full catalog download or CI build.
Build the image:
docker build -t mcp-stargazing .Note: If you are behind a proxy, pass the proxy URL during build:
docker build --build-arg HTTP_PROXY=http://127.0.0.1:7890 -t mcp-stargazing .Run the container:
# Basic run (MCP on :3001 + SPF web UI on :5001) docker run -p 3001:3001 -p 5001:5001 mcp-stargazing # With Environment Variables docker run -p 3001:3001 -p 5001:5001 \ -e QWEATHER_API_KEY=your_key \ -e STARGAZING_DB_CONFIG=your_db_config \ mcp-stargazingAccess:
MCP server →
http://localhost:3001/shttp(for AI agent / MCP client)SPF web UI →
http://localhost:5001/(stargazing place finder frontend)
Docker Architecture
The container runs two services managed by supervisord, both sharing the same Python
virtual environment via uv run:
Container
├── supervisord
│ ├── program:mcp → uv run mcp-stargazing --mode shttp --port 3001
│ └── program:spf-web → uv run uvicorn server.main:app --port 5001
│
Dependency resolution (single venv, no duplication):
stargazing-core>=0.2.1 ← resolved once from PyPI
stargazing-place-finder>=0.9.1
fastapi, uvicorn, ... ← SPF's transitive depsMCP Server Usage
Start the MCP server to expose tools to AI agents or other clients.
Agent-first direction
plan_stargazing_session is the preferred composite decision entry point for third-party agents.
It accepts a place name, center/radius, or exact bounds; resolves Seestar S50,
HOPE D60 + ASI2600MC Air, or custom optics configurations; keeps provider and database choices on
the server; and returns a first-class decision, alternatives, exact score components, evidence,
uncertainties, material missing inputs, ranking-reversal conditions, and next actions.
get_best_stargazing_plan and get_multiday_stargazing_plan remain registered as compatibility
entries for existing bbox-first callers. The deterministic 10-scenario gate and representative
Codex/Claude black-box smoke passed before the primary entry point was registered. New independent
astronomy lookup tools remain deferred while long-running task semantics and the 1.0 contract are
completed.
Background area analysis has bounded execution, duplicate submission, cancellation, deadlines,
retention, and paged result retrieval. The task tools activate optional task_id / progress
metadata; running progress is unknown, and runtime loss requires resubmission. See
Task Lifecycle for the workflow, limits, and recovery semantics.
See Third-party Agent Contract,
Workspace Technical Map, and
Agent Evolution Checklist. The current 21-tool routing and
parameter review is recorded in Tool Surface Audit. Evaluation assets
and the two-client evidence are under evaluations/.
The pre-1.0 public schema baseline records the existing tool
schemas and detailed planning/area models. SDK and real tools/list tests detect contract drift
before new tools are added.
The independent 1.0 contract and migration guide freezes all 21 tools,
task models, detailed payloads, annotations, and envelope semantics without replacing that
historical snapshot. The two bbox-first planners remain supported and have no active deprecation
notice. Future removal requires at least 90 days, two subsequent minor releases, and a later major.
The package version and response _meta.version are separate; this contract freeze is not a release.
For a complete primary-planner client, save one of the guide's JSON requests and run:
uv run python examples/agent_planning_demo.py --request request.json --url http://localhost:3001/shttp1. Environment Setup
Create a .env file or export variables:
# Weather tools
# 推荐:使用你账号专属的 API Host(公共域名将从 2026 年起逐步停止服务)
export QWEATHER_API_HOST="abc1234xyz.def.qweatherapi.com"
# 鉴权(二选一)
# 1) API KEY(兼容旧用法)
export QWEATHER_API_KEY="your_api_key"
# 2) JWT(推荐,更安全)
# export QWEATHER_JWT_TOKEN="your_jwt_token"
# 如需临时兼容旧公共域名(不推荐),显式开启:
# export QWEATHER_ALLOW_PUBLIC_HOST=1
# Geocoding(默认零付费、零 key)
# CJK 查询默认使用内置离线行政区划数据;未命中时回退 Photon / Nominatim。
# 可选 provider 顺序覆盖(全部支持:gazetteer, photon, nominatim, amap)
# export GEOCODER_PROVIDERS="gazetteer,photon,nominatim"
# 仅当你希望显式启用付费的 Amap 地理编码时才需要:
# export GEOCODER_PROVIDERS="amap,gazetteer,photon,nominatim"
# export AMAP_KEY="your_amap_key"
# Optional: Proxy for downloading astronomical data (Simbad/IERS)
# Highly recommended if you are in a restricted network environment
export HTTP_PROXY="http://127.0.0.1:7890"
export HTTPS_PROXY="http://127.0.0.1:7890"2. Start Server
Streamable HTTP (SHTTP) mode (Recommended for most agents):
# Basic start
python -m src.main --mode shttp --port 3001 --path /shttp
# With proxy explicitly passed (overrides env vars)
python -m src.main --mode shttp --port 3001 --path /shttp --proxy http://127.0.0.1:7890SSE mode:
python -m src.main --mode sse --port 3001 --path /ssedev mode is no longer supported because current FastMCP versions no longer provide run_dev(). Use local, shttp, or sse.
3. Response Format
Successful business responses return data in a standardized JSON format:
{
"data": {
// Tool-specific return data
"altitude": 45.5,
"azimuth": 180.0
},
"_meta": {
"version": "1.0.0",
"status": "success"
}
}Business validation failures use the same envelope style:
{
"error": {
"code": "INVALID_TIME_FORMAT",
"message": "Invalid time format: invalid-time-format",
"details": {
"time_string": "invalid-time-format"
}
},
"_meta": {
"version": "1.0.0",
"status": "error"
}
}At the MCP protocol layer, tools/list and get_tool_catalog are kept aligned, and JSON-RPC request ids are preserved in both SHTTP and SSE transport tests.
Every tool's standard MCP description includes Use when, Do not use when, Requires,
Returns, and Follow-up guidance. These explain the primary planner versus compatibility
entries, facts versus observing decisions, synchronous versus background area searches, and
common scope traps such as server-local time and constellation-center lookup. The wrapped catalog
keeps its summary description and full docstring; explicit decorator descriptions are complete
and take precedence. See the tool routing audit.
4. Available Tools
External AI callers should follow the planning result interpretation guide.
The critical field, uncertainty, score and location boundaries are also in standard MCP
descriptions, visible through tools/list without opening this README.
Composite planners score the requested night's hourly forecast, including low/mid/high cloud layers. Current conditions or daily averages never substitute for missing forecast hours. Open-Meteo requests 16 forecast days; actual usable coverage depends on each provider/model and field. Out-of-horizon spatial weather is omitted rather than snapped to the last model time. Missing/partial night coverage is explicit in notes/uncertainties; a degraded ranking is provisional. Weather evidence records the provider, interval, available hours and cloud aggregation. Weather base scores stay within 0–100; known forecasts with no usable cloud/rain/wind interval receive zero weather credit. Multi-night runs reuse raw place/weather retrievals, then evaluate each night separately; this reduces repeated I/O but does not guarantee a 60-second call.
location.center plus radius_km requests regional site selection, not a plan locked to that
coordinate. Quietness/popularity adjustments require the corresponding preference flags; these
scores are heuristics, not measured noise or crowd counts. night_window retains its documented
civil-dark meaning (Sun below −6°), not astronomical darkness (−18°). Civil-dark duration is
not a promise of usable deep-sky exposure time; verify twilight and access before departure.
get_celestial_pos: Calculate altitude/azimuth.get_celestial_rise_set: Calculate rise/set times (Returns ISO strings). Useevent_scope="calendar_day"for the historical full-local-day behavior, orevent_scope="next_events"to find the first rise and first set after the suppliedtime, rolling across midnight when needed.get_moon_info: Detailed moon phase, illumination, and age.list_visible_planets: List of all planets currently above the horizon with positions.get_constellation: Find the position (Alt/Az) of a constellation center.get_nightly_forecast: Smart planner returning curated list of best objects to view tonight (Planets + Deep Sky) plus the local civil-darknight_windowwith dusk, dawn, duration, date, and timezone.get_weather_by_name/get_weather_by_position: Fetch current weather with automatic retry on network failures.get_local_datetime_info: Get current local time information.get_tool_catalog: Discover available MCP tool metadata and parameters.plan_stargazing_session: Preferred end-to-end entry point for deciding when, where, and what to observe across one to seven nights.Inputs: a
requestobject containinglocation(exactly one ofplace_name,center, orbounds),start_date, optionaltime_zone,nights,observation_style,equipment, candidate/target limits, and popularity preferences.Equipment: stable presets are
seestar_s50andhope_d60_asi2600mc_air; advanced callers may usecustomor override individual optical fields.Returns: normalized request and resolved geography, a first-choice
decision, rankedalternatives, traceableevidence,uncertainties, materialmissing_inputs,would_change_ifconditions, and concretenext_actions.Routing: use this for a complete observing decision. Use weather, celestial, telescope, or place tools directly for focused fact lookups.
get_best_stargazing_plan: Build a ranked regional observing plan with candidate places, weather summaries, best observation windows, and top targets.Inputs:
south,west,north,east,time,time_zone,candidate_limit,target_limit,weather_provider,max_locations,min_height_diff,road_radius_km,network_type,observation_style,avoid_popular_spots,prefer_quiet_at_night,popularity_radius_km,db_config_path.Candidate recall:
candidate_limitis the number of ranked candidates returned. The service evaluates a bounded recall pool before final truncation, so a location with better weather can overtake a statically higher-ranked location.Cost-aware evaluation: the recall pool receives a low-cost weather screen first; night-window and target-forecast evaluation then runs only for the strongest internal candidates before the final ranking.
Regional weather signal: when available, the server samples the stargazing-core spatial cloud-cover grid once for the whole bbox and blends it into regional comparison; a spatial-model failure degrades without failing the plan.
Returns:
query,summary, andcandidates, wherequery.analysis_resource_idlinks the plan back to the underlying neutralanalysis_areasearch when available. When popularity preferences are enabled, MCP applies a single adjustment from the returned heuristic fields, surfaces those reasons incandidates[*].recommendation_reasons, and summarizes the top recommendation insummary.popularity_preferences_enabled,summary.primary_recommendation_drivers, andsummary.recommended_location_reason_summary. Each candidate'sscore_breakdown.factor_contributionsexposes the signed place, weather, popularity, and accessibility contributions used for ranking; explanatory reasons use the same active factors. The driver values form a stable enum:dark_sky,high_place_score,clear_weather,good_visibility,observation_style_fit,low_popularity_risk,quiet_at_night, andstrong_targets.Popularity ownership: all composite planners (single-night, multi-night, and
plan_stargazing_session) request SPF place scores withavoid_popular_spots=falseandprefer_quiet_at_night=false, preservingpopularity_radius_kmand the heuristic evidence. MCP alone applies the requested preferences; screening and final evaluation each start from the neutral score. Request echoes retain the user's preferences. To reproducequery.analysis_resource_id(or the primary planner's placeevidence.resource_id), repeat the same area search with both preference flags disabled. Standaloneanalysis_areastill forwards preferences to SPF and uses a separate cache entry when enabled.Observation style:
balancedpreserves the default behavior.deep_skyemphasizes dark skies and low moonlight,visualraises the weather weight,planetaryreduces moon penalties and prioritizes planets, andbeginneralso favors nearby road access.Night window: each candidate includes
night_windowwhen civil darkness can be determined, with local date, civil dusk, following civil dawn, duration, and timezone.best_observation_windownow represents a continuous dark-sky run when hourly data permits;start_time, weather fields, and the additiveend_time,duration_hours, andquality_scoreare returned together.
get_multiday_stargazing_plan: Compare one to seven consecutive nights and return the best night and location across the region.Inputs:
south,west,north,east,start_date,time_zone,nights, plus the same candidate, weather, street-network, and observation-style options asget_best_stargazing_plan.Returns:
query, a cross-nightsummarywithbest_night_date,best_location_name, andbest_score, andnights[]where each night contains itsnight_window, nightlyplan, errors, and warnings.Degradation: Weather or forecast sub-queries may degrade into
summary.warningsand per-candidatenotes, while the overall planning response remains successful.
get_telescope_targets: Match deep-sky objects against telescope optics — find what's best visible with your equipment.Inputs:
focal_length_mm,lon,lat,time,time_zone, plus optional optics fields such asaperture_mm, sensor dimensions, pixel size, reducer/Barlow factor, mount type, filter, andlimit.Returns: Ranked targets with visibility scores, altitude/azimuth, rise/set/transit data, FOV fit, surface brightness, mosaic guidance, and the normalized telescope configuration.
get_shooting_plan: Generate an optimized imaging schedule for a target, maximizing time above altitude threshold.Inputs: the same telescope/observer fields as
get_telescope_targets, plus optionallimitandmin_altitude.Returns:
targets,moon, a single-nightplanwith timed imaging slots,config, andtotal.
light_pollution_map: Query light pollution data for a bounding box area.Inputs:
south,west,north,east,zoom(default 10).Returns: A grid of data points with Bortle class, brightness, and SQM values.
analysis_area: Find best stargazing spots in a region.Inputs:
south,west,north,east,max_locations,min_height_diff,road_radius_km,network_type,avoid_popular_spots,prefer_quiet_at_night,popularity_radius_km,db_config_path,page,page_size.Returns: List of spots with pagination metadata (
total,page,page_size,total_pages) and aresource_idthat identifies the cached non-pagination query parameters. Each item may also include popularity heuristic fields such asstatic_popularity_risk_score,night_quiet_likelihood_score, andpopularity_notes.Validation:
page >= 1,page_size >= 1, andpopularity_radius_km > 0; invalid arguments returnCONFIGURATION_ERROR.
Background area tools:
submit_area_analysis: accepts arequestwithboundsand place-search preferences; returns a task snapshot and normalized request.max_locationsis 1–100. Deployment paths and execution budgets remain server policy.get_area_analysis_task: acceptstask_id; returns state, timestamps, failure details,execution_pending, and the successfulresult_revisionwhen present. Polling a failed task succeeds as a status lookup; inspectdata.stateanddata.failure.cancel_area_analysis_task: acceptstask_id; records idempotent cancellation. A running provider call retains its execution slot until it finishes, and its late results are discarded.get_area_analysis_result: acceptstask_id,page, andpage_size; returns the existingAnalysisAreaResultpagination shape. It never silently recomputes missing data. Expired or replaced publications require resubmission.
Workflow: submit → poll until succeeded → fetch pages. Use plan_stargazing_session for a complete observing decision; these task tools are for raw place analysis. Existing synchronous analysis_area remains available.
The AI recovery acceptance report records ten read-only state/result questions completed by each of two clients, with auditable calls and explicit limits. It does not qualify AI submission/cancellation workflows or real provider uptime. The separate active-workflow report qualifies submission, status-confirmed pagination, cancellation, and active-query reuse in three isolated workflows per client. It uses real workers with a controlled provider; real provider uptime remains outside this acceptance gate.
5. Error Handling
All tools return JSON-serializable data and use structured error handling:
Standard Error Codes:
INVALID_COORDINATES,INVALID_TIMEZONE,INVALID_TIME_FORMAT,MISSING_API_KEY,API_AUTH_FAILURE,API_TIMEOUT,API_RATE_LIMIT,EXTERNAL_API_ERROR,NETWORK_ERROR,CONFIGURATION_ERRORTask Error Codes:
TASK_NOT_FOUND,TASK_RUNTIME_CHANGED,TASK_CAPACITY_EXCEEDED,TASK_NOT_READY,TASK_UNAVAILABLE,TASK_RESULT_EXPIRED; see task recovery guidance.Weather Tools: Include automatic retry logic for network failures (up to 3 attempts with exponential backoff)
Business Error Responses: Structured MCPError-derived payloads with actionable messages for calling agents
Protocol Tests:
tools/list,get_tool_catalog, and SSE request-id behavior are covered by protocol-level testsValidation: Input parameters are validated before processing with clear error messages
Examples
Background Area Analysis:
python examples/background_area_demo.pySubmits, polls, and fetches a result page; accepts
--task-idto resume polling or--cancel --task-id ...to cancel explicitly.
Nightly Planner:
python examples/nightly_forecast_demo.pyShows a curated list of planets and deep-sky objects visible tonight, accounting for moonlight.
Visible Planets:
python examples/visible_planets_demo.pyLists which planets are currently up.
Moon Info:
python examples/moon_phase_demo.pyPrints a 30-day moon phase calendar.
Orchestration:
python examples/code_execution_orchestration.pyDemonstrates a full workflow: Get time -> Get Celestial Pos -> Check Weather -> Find Spots.
Shows how to handle the standardized response format programmatically.
Pagination:
python examples/pagination_demo.pyDemonstrates fetching large result sets page by page using the
resource_id.
Telescope Targets:
python examples/telescope_targets_demo.pyRanks deep-sky targets for a RedCat51-style optical configuration.
Shooting Plan:
python examples/shooting_plan_demo.pyProduces a time-ordered single-night imaging plan.
Project Structure
.
├── src/
│ ├── functions/ # Tool implementations grouped by domain
│ │ ├── celestial/ # Celestial calculations (pos, rise/set)
│ │ ├── metadata/ # Tool discovery surface (`get_tool_catalog`)
│ │ ├── planning/ # Single-night and multi-night composite planning
│ │ ├── telescope/ # Telescope target matching + shooting plan
│ │ ├── weather/ # Weather API integration
│ │ ├── places/ # Location and area analysis
│ │ └── time/ # Time utilities
│ ├── services/ # Transport-independent application services
│ │ └── planning.py # Single-night and multi-night planning orchestration
│ ├── schemas/ # Pydantic v2 data models
│ ├── analysis_cache.py # Caching logic for analysis results
│ ├── response.py # Standardized response formatting
│ ├── server_instance.py # FastMCP server instance (avoids circular imports)
│ ├── main.py # Entry point and tool registration
│ ├── celestial.py # Core astronomy logic (Astropy wrappers)
│ ├── placefinder.py # Place-finder bridge logic
│ └── qweather_interaction.py # Thin QWeather URL wrappers
├── tests/ # Unified test suite covering every registered tool
├── examples/ # Runnable usage examples, including both telescope tools
├── docs/ # Design docs and roadmap
├── Dockerfile # Multi-stage Docker build
├── supervisord.conf # Dual-service process manager config
└── pyproject.toml # Project configuration and dependenciesTesting
Run the unified test suite:
uv run pytest -v tests/Key tests include:
test_serialization.py: Ensures all tools return valid JSON with the correct schema.test_integration.py: Mocks external APIs to verify the entire toolchain.test_mcp_client.py: Verifiestools/list,tools/call, and SSE request-id protocol behavior.test_structured_errors.py: Verifies business validation failures stay in the structured response envelope.
Cross-repository compatibility is checked by the reusable
dependency-chain workflow. It tests
stargazing-core → stargazing-place-finder → mcp-stargazing using baseline and
candidate wheels, and blocks changes that add downstream failures.
Contributing
Follow the Code Execution with MCP best practices.
Ensure all new tools return standard JSON responses using
src.response.format_response.Add tests in
tests/for any new functionality.Follow the repository agent conventions in
AGENTS.mdfor all MCP tool and agent-facing changes.Refer to
docs/agent-contract.mdanddocs/ROADMAP.mdfor the public agent direction and implementation roadmap.
Evidence-gated observing recommendations
Only candidates with the requested night's dated weather and a usable observation window
compete for the selected session and its alternatives. Unknown weather is not replaced by
an assumed score and is not classified as bad weather. Known forecasts without a usable
window are also excluded, with a distinct reason. If none qualify, the primary planner
returns decision=null, no alternatives, explicit uncertainties and next actions.
Known place, sky and generic target facts remain in evidence entries whose source is
unranked_planning_reference; facts.status is weather_unknown or no_usable_window.
These entries have no session score or comparison to the decision. Equipment configuration
is retained as evidence when supplied; reference targets are generic, not equipment-matched.
Compatibility planners retain reference candidates and notes, but leave recommended-place and best-night summary fields null when no session qualifies. Their numeric weather fields remain schema-compatible: absent weather has zero base score, contribution and weight as placeholders, not a claim of bad weather. Place weights are not renormalized. Reference candidate scores and positions must not be interpreted as an observing-session ranking. Successful execution still means only that the request was processed.
Available Tools
21 toolsanalysis_areaA
Analyze a geographic area for suitable stargazing locations.
Use when: you need synchronous place candidates or cached pages for a fixed regional query. Do not use when: the search needs background polling/cancellation or a complete night plan. Requires: south/west/north/east bounds; keep search parameters fixed while changing pages. Follow-up: analysis_area with the same query for other pages; submit_area_analysis for background work; plan_stargazing_session for dates, weather, and target decisions.
This tool searches for dark, accessible locations with good viewing conditions. Results are cached based on search parameters.
Fast mode: Set road_radius_km=0 to skip road connectivity checks.
This avoids OSMnx network downloads from Overpass API and is much faster —
use it when you only need candidate locations with light pollution and
elevation data, without road distance analysis.
Args: south, west, north, east: Bounding box coordinates. max_locations: Maximum number of candidate locations to find (before pagination). min_height_diff: Minimum elevation difference for prominence. road_radius_km: Search radius for road access. Set to 0 to skip road checks. network_type: Type of road network ('drive', 'walk', etc.). avoid_popular_spots: Penalize heuristically popular locations when ranking results. prefer_quiet_at_night: Favor locations that are likelier to quiet down at night. popularity_radius_km: Preference horizon for the popularity heuristics. db_config_path: Optional path to database config. page: Page number (1-based). page_size: Number of results per page.
Returns: Dict with keys "data", "_meta". "data" contains: - items: List of location results for the current page. - total: Total number of locations found. - page: Current page number. - page_size: Current page size. - resource_id: Cache key for the non-pagination search parameters.
| Name | Required | Description | Default |
|---|---|---|---|
| east | Yes | ||
| page | No | ||
| west | Yes | ||
| north | Yes | ||
| south | Yes | ||
| page_size | No | ||
| network_type | No | drive | |
| max_locations | No | ||
| db_config_path | No | ||
| road_radius_km | No | ||
| min_height_diff | No | ||
| avoid_popular_spots | No | ||
| popularity_radius_km | No | ||
| prefer_quiet_at_night | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: it discloses result caching keyed on search parameters, the resource_id cache key contract for pagination, and a concrete cost/latency tradeoff (road_radius_km=0 skips OSMnx network downloads from Overpass API). It also explains that max_locations applies before pagination, avoiding a common misuse.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with usage guidance, then a fast-mode callout, then a conventional Args block — well structured and scannable. The 'Returns' section partly repeats what the output schema already provides, so a little length is not strictly earned.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 14-parameter, no-annotation, synchronous search tool with pagination and caching, the description covers invocation, cost tradeoffs, pagination stability, and output shape. Nothing an agent needs in order 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it documents all 14 parameters — bounding box, pagination, elevation prominence, road radius, network type, the popularity heuristics and their radius, and db_config_path. Non-obvious semantics such as 'Set to 0 to skip road checks' and 'before pagination' add meaning the bare schema cannot convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Analyze a geographic area for suitable stargazing locations') and immediately contrasts itself with the async sibling ('Do not use when: the search needs background polling/cancellation'), which is exactly the distinction from submit_area_analysis. An agent can route correctly without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' / 'Do not use when' blocks name the conditions (synchronous place candidates, fixed regional query) and the alternatives (submit_area_analysis for background work, plan_stargazing_session for complete night plans). The follow-up line even tells the agent how to fetch further pages.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancel_area_analysis_taskAIdempotent
Logically cancel queued/running area work and discard its late results.
Use when: a submitted area task is no longer needed and its late result must not publish. Do not use when: you want to delete cached data or interrupt another domain's operation. Requires: task_id returned by submit_area_analysis in the same server runtime. Returns: idempotent cancellation snapshot; an existing terminal state stays unchanged. A running provider call keeps its execution slot until it actually finishes. Follow-up: get_area_analysis_task to confirm state and execution_pending; wait for physical work to drain before considering resubmission.
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses that cancellation is logical (not physical), that a running provider call keeps its execution slot, that late results are discarded rather than published, and that terminal states are unchanged by re-invocation. That is exactly the non-obvious behavior an agent needs before invoking a mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Labeled lines (Use when / Do not use when / Requires / Returns / Follow-up) make it skimmable and front-load the core action. It is somewhat longer than strictly necessary, with mild redundancy between the opening sentence and the Returns line.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter mutation with an output schema, it covers provenance, idempotency, side effects, and the confirmation workflow. Nothing an agent needs to call it safely and correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry parameter meaning; it specifies that task_id comes from submit_area_analysis and must be from the same server runtime, which is a real constraint the schema lacks. It does not state the format or what happens with a stale/invalid id, so it falls short of full compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('logically cancel queued/running area work and discard its late results') and contrasts it with neighboring operations such as deleting cached data. An agent can distinguish it from get_area_analysis_task or submit_area_analysis without reading either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when' and 'Do not use when' clauses plus a named alternative domain ('another domain's operation'), and names the prerequisite tool (submit_area_analysis) and the confirmation follow-up (get_area_analysis_task). Routing is fully determined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_area_analysis_resultARead-onlyIdempotent
Page a successful area task's existing cached result without recomputing.
Use when: get_area_analysis_task reports succeeded and you need its original result pages. Do not use when: the task is queued/running and you only need to poll its state. Requires: the successful task_id, page >= 1, and page_size >= 1. Returns: cached items, pagination metadata, and resource_id with the task's publication version checked; this call never silently recomputes missing data. Follow-up: get_area_analysis_result with the same task_id for other pages; get_area_analysis_task for state; resubmit the normalized request on TASK_RESULT_EXPIRED.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| task_id | Yes | ||
| page_size | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and non-destructive, yet the description adds behavior they cannot express: results come from cache, no silent recomputation occurs, the resource_id is version-checked against the task's publication version, and expired results surface as TASK_RESULT_EXPIRED. That is the kind of failure-mode and staleness context an agent cannot infer from the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Labeled sections (Use when / Do not use when / Requires / Returns / Follow-up) front-load the routing decision and waste little space. The Returns line partially duplicates the already-present output schema, which is the only real redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a paginated cache-read with an output schema, an agent has everything needed: precondition (task succeeded), parameter constraints, pagination path, staleness check, and the recovery action on expiry. No behavioral question is left open before invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry the load: it states task_id must belong to a successful task and constrains page >= 1 and page_size >= 1, which the schema does not. It stops short of giving any bound or default rationale for page_size, leaving some semantics to inference.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Page a successful area task's existing cached result without recomputing" names a specific verb (page), a specific resource (a cached area-analysis result), and its defining constraint (cache-only, no recomputation). It is immediately distinguishable from siblings like get_area_analysis_task or submit_area_analysis.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use when: get_area_analysis_task reports succeeded..." and "Do not use when: the task is queued/running and you only need to poll its state" give an explicit inclusion and exclusion with the alternative named. The follow-up line further routes to get_area_analysis_task for state and to resubmission on TASK_RESULT_EXPIRED.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_area_analysis_taskARead-onlyIdempotent
Poll an area task's state, deadline, failure, and normalized request.
Use when: you have a task_id and need execution state, failure, or remaining physical work. Do not use when: you need result pages; do not submit a new job merely to poll. Requires: task_id returned by submit_area_analysis in the same server runtime. Returns: task snapshot with state, failure, request, and execution_pending. Running progress is unknown; success does not guarantee the separate result cache still exists. Follow-up: get_area_analysis_result after success; cancel_area_analysis_task if unwanted. On TASK_RUNTIME_CHANGED, resubmit the original request rather than polling the old ID.
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses that running progress is unknown, that success does not guarantee the result cache still exists, that the task_id is only valid in the same server runtime, and how to recover on TASK_RUNTIME_CHANGED. These are non-obvious operational traits an agent could not infer from readOnlyHint/idempotentHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, then organized into Use when / Do not use when / Requires / Returns / Follow-up blocks. Every sentence carries actionable information, with no filler or restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter polling tool this is complete: it covers prerequisites, what the snapshot contains, known limitations of the state signal, and the next step. Even though an output schema exists, the caveats about unknown progress and cache expiry are exactly the gaps structured output could not convey.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry the burden; it specifies the parameter's provenance (returned by submit_area_analysis) and a runtime constraint (same server runtime), which is real meaning beyond 'task_id: string'. It stops short of describing the ID's format or lifetime beyond the runtime caveat.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Poll an area task's state, deadline, failure, and normalized request') and enumerates exactly what fields the snapshot covers. This cleanly separates it from submit_area_analysis, get_area_analysis_result, and cancel_area_analysis_task without the agent needing to open any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' and 'Do not use when' clauses, including the negative guidance not to submit a new job merely to poll and not to use it for result pages. It also routes to the correct siblings ('get_area_analysis_result after success; cancel_area_analysis_task if unwanted') and gives a recovery path for TASK_RUNTIME_CHANGED.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_best_stargazing_planA
Create a composite stargazing plan for a region and time.
Use when: an existing bbox-first integration needs ranked regional places for one night. Do not use when: starting a new intent-based integration, providing a place name, comparing several nights, or only requesting weather facts. Requires: south/west/north/east bounds, observation time, and timezone. Returns: data.query, ranked data.candidates with scores, windows, weather and targets, and data.summary; all within the standard response envelope. recommendation_score is a relative ranking, not a probability or go/no-go threshold. _meta.status=success can still contain summary.warnings and candidate notes. Only candidates with dated weather and a usable window can be recommended. Missing-weather references retain their place weight without renormalization; weather base score/contribution/weight are zero compatibility placeholders, not bad-weather facts. summary.recommended_location_name is null when none qualify. Missing night-hour weather is unknown, not clear; a null best_observation_window is not an all-night opening. night_window is civil darkness (Sun below -6 degrees), not astronomical darkness (-18 degrees) or guaranteed exposure time. Inspect the returned candidate coordinates; a regional result is not a fixed-site plan. Follow-up: plan_stargazing_session is preferred for new integrations; get_multiday_stargazing_plan preserves bbox-first comparison across nights.
| Name | Required | Description | Default |
|---|---|---|---|
| east | Yes | ||
| time | Yes | ||
| west | Yes | ||
| north | Yes | ||
| south | Yes | ||
| time_zone | Yes | ||
| network_type | No | drive | |
| target_limit | No | ||
| max_locations | No | ||
| db_config_path | No | ||
| road_radius_km | No | ||
| candidate_limit | No | ||
| min_height_diff | No | ||
| weather_provider | No | all | |
| observation_style | No | balanced | |
| avoid_popular_spots | No | ||
| popularity_radius_km | No | ||
| prefer_quiet_at_night | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the entire burden and does most of it: it discloses that recommendation_score is relative not probabilistic, that _meta.status=success can still carry warnings, that missing-weather candidates are zero-weight placeholders rather than bad-weather facts, and that night_window is civil (-6°) not astronomical (-18°) darkness. The remaining gap is operational — nothing says whether this is read-only, whether it is expensive/slow (db_config_path and road_radius_km hint at heavy geospatial computation), or what permissions it needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded: purpose, use-when, do-not-use-when, requires, returns, then caveats. Nearly every line carries decision-relevant information, though the block of return-value caveats is lengthy and partly overlaps territory an output schema already covers.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Return-value semantics are covered far beyond what the output schema provides, so an agent knows how to interpret degraded results. But for an 18-parameter, annotation-free tool, the description leaves the majority of tuning parameters semantically undefined, which is the gap most likely to cause a wrong invocation (e.g., misusing observation_style or the three different limit parameters).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 18 parameters. The description only restates the six required ones ('south/west/north/east bounds, observation time, and timezone'), which the schema's required array already conveys. The twelve optional parameters — observation_style, weather_provider, candidate_limit vs max_locations vs target_limit, avoid_popular_spots, prefer_quiet_at_night, network_type, min_height_diff — get no meaning, valid values, or default rationale anywhere, so an agent must guess at all the ranking-affecting knobs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Create a composite stargazing plan for a region and time' — and immediately scopes it as bbox-first, night-scoped, and ranked. It explicitly names the siblings it is not (plan_stargazing_session, get_multiday_stargazing_plan), so an agent can distinguish it 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Contains an explicit 'Use when' clause, an explicit 'Do not use when' list with four named exclusions (new intent-based integration, place-name input, multi-night comparison, weather-only), and a 'Follow-up' line routing to the two preferred alternatives. This is the full when/when-not/alternative triad.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_celestial_posA
Calculate the altitude and azimuth angles of a celestial object.
Use when: you need one named object's position at a specified place and instant. Do not use when: you need an all-night target list or a complete observing decision. Requires: object name, observer coordinates, observation time, and its IANA timezone. Follow-up: get_celestial_rise_set for events; get_nightly_forecast for night targets; plan_stargazing_session for a complete observing decision.
Args: celestial_object: Name of object (e.g. "sun", "moon", "andromeda") lon: Observer longitude in degrees lat: Observer latitude in degrees time: Observation time string "YYYY-MM-DD HH:MM:SS" time_zone: IANA timezone string
Returns: Dict with keys "data", "_meta". "data" contains "altitude" and "azimuth" (degrees).
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| time | Yes | ||
| time_zone | Yes | ||
| celestial_object | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the disclosure burden and does a good job stating required inputs, time format, timezone requirements, and the returned data structure. It could be slightly stronger by explicitly noting that this is a pure calculation with no side effects, but the behavior is otherwise clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well structured and front-loaded: purpose first, then usage boundaries, requirements, follow-ups, arguments, and return shape. The sections are compact and each adds useful information without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, five required parameters, lack of annotations, and available output schema, the description is complete. It covers purpose, usage boundaries, all parameter meanings, and the return structure sufficiently for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for all five required parameters. It documents each one, including examples for celestial_object, units for lon/lat, the exact time string format, and that time_zone is an IANA timezone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pair: calculate altitude and azimuth angles for a celestial object. It clearly distinguishes the tool from siblings by saying it returns one named object's position rather than a list, events, forecast, or full observing plan.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use the tool, when not to use it, and which alternative sibling tools to use for rise/set events, nightly targets, and complete observing decisions. The guidance is concrete and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_celestial_rise_setA
Calculate the rise and set times of a celestial object.
Use when: you need one object's rise/set events. Choose calendar_day for the local date containing time, or next_events for the next rise and next set after time. Do not use when: you need a continuous observing window or a complete night plan. Requires: object name, observer coordinates, time, timezone, and the intended event scope. Follow-up: get_celestial_pos for position; plan_stargazing_session for observing windows.
Args:
celestial_object: Name of object (e.g. "sun", "moon", "andromeda")
lon: Observer longitude in degrees
lat: Observer latitude in degrees
time: Date string "YYYY-MM-DD HH:MM:SS"
time_zone: IANA timezone string
event_scope: "calendar_day" (default) finds the events in the local calendar
day containing time. "next_events" finds the next rise and next set
independently, rolling into following days when needed.
Returns: Dict with keys "data", "_meta". "data" contains "rise_time" and "set_time".
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| time | Yes | ||
| time_zone | Yes | ||
| event_scope | No | calendar_day | |
| celestial_object | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it explains the two event_scope behaviors (calendar-day lookup vs independent next rise/set rolling into following days), lists prerequisites, and notes return keys. Gaps remain around degenerate cases (circumpolar objects, no rise/set) and error behavior, so not 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Structured with labeled sections and front-loaded purpose plus when/when-not. Slight redundancy: the Args and Returns blocks largely restate schema/output-schema content, but each remains brief and harmless.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so the "Returns" note is optional; parameters are fully documented and alternatives are named. Still missing edge-case behavior (objects that never rise or set, validation bounds on lat/lon), which would complete a calculation tool with no annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate and does: it gives the time format ("YYYY-MM-DD HH:MM:SS"), the IANA timezone string, degrees for lon/lat, example object names ("sun", "moon", "andromeda"), and a clear default/semantics for event_scope. This is meaningfully richer than the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Calculate the rise and set times of a celestial object") and distinguishes itself from siblings by naming get_celestial_pos for position and plan_stargazing_session for observing windows. An agent can route to it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit "Use when" / "Do not use when" sections name the alternative (continuous observing window or complete night plan) and the required inputs. Nothing is left to inference about when this tool is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_constellationA
Get the position (altitude/azimuth) of the center of a constellation.
Use when: you need a named constellation's center position at a place and instant. Do not use when: you need to identify which constellation contains arbitrary coordinates, or to choose individual observing targets. Requires: constellation name, observer coordinates, time, and timezone. Follow-up: get_nightly_forecast for individual night targets; plan_stargazing_session for a complete observing decision.
Args: constellation_name: Name of constellation (e.g. "Orion", "Ursa Major") lon: Observer longitude in degrees lat: Observer latitude in degrees time: Observation time string "YYYY-MM-DD HH:MM:SS" time_zone: IANA timezone string
Returns: Dict with keys "data", "_meta". "data" contains name, altitude, azimuth.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| time | Yes | ||
| time_zone | Yes | ||
| constellation_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It states required inputs and return keys, but it does not disclose coordinate frame conventions, altitude/azimuth units, error behavior, or confirm read-only safety beyond the 'Get' verb.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and organized into purpose, use/do-not-use, requirements, follow-up, args, and returns. Every sentence serves a clear selection or invocation purpose with no padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the full input set, usage boundaries, and return structure, and an output schema exists. However, it omits some invocation-relevant conventions such as longitude/latitude sign convention and output altitude/azimuth units.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate and does: it documents all five required parameters, including examples for constellation_name, degrees for lon/lat, the time string format, and IANA timezone. This is substantially more than the schema alone provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get the position (altitude/azimuth) of the center of a constellation.' It also distinguishes the scope from adjacent needs by noting it is not for identifying which constellation contains arbitrary coordinates or choosing individual observing targets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit 'Use when' and 'Do not use when' guidance, plus follow-up tools for related observing tasks. The exclusion for identifying a constellation from arbitrary coordinates is clear, but it does not name a specific alternative tool for that case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_local_datetime_infoA
Retrieve the current datetime and timezone.
Use when: you need the server environment's current time and local timezone. Do not use when: you need time at a remote observing site or already have its timezone. Requires: no inputs; local means the server environment, not the user's observing site. Follow-up: use the observing site's explicit time_zone in celestial and plan_stargazing_session requests; do not infer it from the server timezone.
Returns: Dict with keys "data", "_meta". "data" contains "current_time" (ISO string).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does well: it says there are no inputs, clarifies that 'local' means the server environment, and describes the return shape. It does not explicitly state read-only/no side effects, but 'Retrieve' strongly implies that for this simple tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then organized into Use when / Do not use when / Requires / Follow-up / Returns. Every section adds useful routing or behavioral context without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter datetime tool, the description covers purpose, appropriate and inappropriate use, input expectations, the key semantic caveat, follow-up behavior, and return structure. An output schema exists, but the description remains complete without relying on it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the description correctly states 'no inputs.' Per the zero-parameter baseline, this is adequate and leaves little else to explain.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: retrieve the current datetime and timezone. It also disambiguates the meaning of 'local' as the server environment rather than the user's observing site, which separates it from celestial/session-planning siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when' and 'Do not use when' guidance, plus a follow-up warning not to infer observing-site timezone from this result. The boundary against remote-site timing and plan_stargazing_session usage is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_moon_infoA
Get detailed information about the Moon's phase and position.
Use when: you need lunar phase or illumination facts, with optional observer-local events. Do not use when: you need to rank observing sites or assess a target's overall suitability. Requires: time and timezone; supply both lat and lon for local position and rise/set. Follow-up: get_telescope_targets for equipment-aware targets; plan_stargazing_session for the combined effect of moonlight, weather, place, and observing goals.
When lat and lon are provided, also returns the Moon's local
altitude, azimuth, moonrise, and moonset relative to the observer.
Args: time: Date string "YYYY-MM-DD HH:MM:SS" time_zone: IANA timezone string lat: Observer latitude in degrees (optional, for local position) lon: Observer longitude in degrees (optional, for local position)
Returns: Dict with keys "data", "_meta". "data" contains illumination, phase_name, age_days, elongation, earth_distance, and optionally altitude/azimuth plus moonrise/moonset (UTC unix timestamps).
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | ||
| lon | No | ||
| time | Yes | ||
| time_zone | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose the key conditional behavior: lat/lon are optional, and supplying both unlocks local altitude, azimuth, moonrise, and moonset. It does not cover failure modes such as invalid timezone strings or out-of-range coordinates, 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The 'Use when / Do not use when / Requires / Follow-up' block is front-loaded and dense with actionable content. However, the Args and Returns sections largely restate the input schema and output schema, so some of the closing text does not earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter read tool with an output schema, the description covers inputs, conditional local-position behavior, exclusions, and next steps. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description fully compensates: it gives the exact time format "YYYY-MM-DD HH:MM:SS", specifies an IANA timezone string, marks lat/lon as optional degrees and states the condition under which they matter. Every parameter is documented with more precision than a bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (Moon phase and position) and immediately scopes what it covers: illumination, phase, and observer-local position. It explicitly distinguishes itself from siblings that rank sites or assess target suitability, so an agent can choose it without opening other schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit 'Use when' and 'Do not use when' pair, names the prerequisites (time, timezone, both lat and lon for local results), and routes follow-ups to get_telescope_targets and plan_stargazing_session. Alternatives and exclusions are both spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_multiday_stargazing_planA
Compare one to seven consecutive nights and recommend the best night and place.
Use when: an existing bbox-first integration compares one to seven consecutive nights. Do not use when: starting a new intent-based integration, querying nonconsecutive dates, more than seven nights, or checking background task status. Requires: south/west/north/east bounds, local start_date, timezone, and optional night count. Returns: normalized data.query, per-night plans, the best night, and summary; each night uses its own civil-dark window. recommendation_score is a relative ranking, not a probability or go/no-go threshold. _meta.status=success can still contain per-night errors, warnings and candidate notes. Compare the dated forecast hours for each night; do not reuse summary.current or summary.daily as night weather. Missing night-hour coverage is unknown, not clear. Civil darkness (Sun below -6 degrees) is not astronomical darkness (-18 degrees) or guaranteed exposure time; a null best_observation_window is not an all-night opening. Follow-up: plan_stargazing_session is preferred for new integrations; get_best_stargazing_plan for the compatible single-night regional detail.
| Name | Required | Description | Default |
|---|---|---|---|
| east | Yes | ||
| west | Yes | ||
| north | Yes | ||
| south | Yes | ||
| nights | No | ||
| time_zone | Yes | ||
| start_date | Yes | ||
| network_type | No | drive | |
| target_limit | No | ||
| max_locations | No | ||
| db_config_path | No | ||
| road_radius_km | No | ||
| candidate_limit | No | ||
| min_height_diff | No | ||
| weather_provider | No | all | |
| observation_style | No | balanced | |
| avoid_popular_spots | No | ||
| popularity_radius_km | No | ||
| prefer_quiet_at_night | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly: it flags that recommendation_score is a relative ranking rather than a threshold, that _meta.status=success can still carry per-night errors/warnings, that missing night-hour coverage means unknown rather than clear, and that civil darkness (-6°) is not astronomical darkness (-18°). These are non-obvious interpretation traps an agent would otherwise get wrong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The label-based structure (Use when / Do not use when / Requires / Returns / Follow-up) is well front-loaded and each sentence carries distinct information. The Returns block is dense but every clause is a caveat that prevents misreading; only minor tightening is possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still usefully summarizes the shape (data.query, per-night plans, best night, summary) and the caveats around it. Requirements, scope limits and follow-up routing are all covered; the only real gap is the unexplained optional tuning parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% across 19 parameters, yet the description only explains the four bbox bounds, start_date, time_zone and an optional night count. Twelve tuning parameters — network_type, target_limit, max_locations, road_radius_km, candidate_limit, min_height_diff, weather_provider, observation_style, avoid_popular_spots, popularity_radius_km, prefer_quiet_at_night, db_config_path — receive no semantic explanation anywhere, so the agent must guess their effect and valid ranges.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair and resource: 'Compare one to seven consecutive nights and recommend the best night and place.' It also names the sibling tools it would be confused with (plan_stargazing_session, get_best_stargazing_plan) and what each is for, so an agent can disambiguate without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' / 'Do not use when' blocks list the positive trigger (an existing bbox-first integration, 1-7 consecutive nights) and the exclusions (new intent-based integration, nonconsecutive dates, >7 nights, background task status). Alternatives are named in the Follow-up line.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_nightly_forecastA
Get a curated list of best objects to view for the night.
Use when: place and night are known and you need general night targets and a night window. Do not use when: you need telescope-specific target matching or regional site selection. Requires: observer coordinates, time within the intended night, timezone, and optional limit. Interpretation: this is an astronomy forecast, not a weather forecast. Deep-sky altitude and score are evaluated at the supplied time; deep_sky.score sorts lower first and must not be compared with telescope suitability_score (higher first). The legacy transit_alt is an altitude estimate at that scoring time, not a separately solved meridian transit. night_window is civil darkness (Sun below -6 degrees), not astronomical darkness (-18 degrees) or guaranteed exposure time. Follow-up: get_telescope_targets for known optics; get_shooting_plan for an imaging schedule; plan_stargazing_session when place or night still needs comparison.
Args: lon: Observer longitude in degrees lat: Observer latitude in degrees time: Observation time "YYYY-MM-DD HH:MM:SS" inside the intended night. A bare date means local midnight and can belong to the previous evening's night. time_zone: IANA timezone string limit: Max number of deep-sky objects to return (default 20)
Returns: Standard envelope; data contains: - moon_phase: Moon details - planets: List of visible planets - deep_sky: Sorted list of deep sky objects (Messier/NGC) - night_window: Civil-dark window for the requested night
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| time | Yes | ||
| limit | No | ||
| time_zone | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does it well: it discloses that deep_sky.score sorts ascending and must not be compared to telescope suitability_score (descending), that transit_alt is an estimate at scoring time rather than a solved meridian transit, and that night_window is civil darkness (-6°) not astronomical (-18°). It is silent on failure modes, however — invalid time/timezone handling, high-latitude cases where no civil darkness occurs, and whether the call has any cost — which is a real gap for a zero-annotation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then labeled Use/Do-not-use/Requires/Interpretation/Follow-up sections that scan quickly. The closing 'Returns' block largely restates what the output schema already declares, so that section is the one part that does not fully earn its space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter tool with no annotations and a rich output schema, the description covers everything an agent needs to call it correctly: when to use, when not to, required inputs, argument formats, scoring-direction pitfalls, and next-step routing. Return-value structure is correctly left to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate and it does: it documents all five parameters including the 'YYYY-MM-DD HH:MM:SS' format for time, the non-obvious caveat that a bare date means local midnight and may fall into the previous evening's night, IANA format for time_zone, and the default of 20 for limit. This is substantially richer than the bare schema types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get a curated list of best objects to view for the night') and immediately bounds the scope with an explicit exclusion ('not telescope-specific target matching or regional site selection'). An agent can distinguish it from get_telescope_targets, plan_stargazing_session, and get_shooting_plan 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Uses explicit 'Use when' / 'Do not use when' clauses and names the prerequisite state ('place and night are known'). The 'Follow-up' line routes to three named siblings with the condition that selects each (known optics, imaging schedule, place/night still undecided).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_shooting_planA
Generate a single-night astrophotography shooting plan.
Use when: optics, place, and night are fixed and you need matched targets in timed slots. Do not use when: you still need to choose a site or compare nights, or only need target ranks. Requires: focal length, observer coordinates, time, and the observing timezone (defaults to UTC); optional sensor, optical, and minimum-altitude settings. Follow-up: get_telescope_targets for target details; plan_stargazing_session to reconsider place, date, equipment preset, or observing constraints.
Runs match_telescope_targets then generate_shooting_schedule, returning targets + moon + timed shooting slots in one response. Interpretation: target altitude is at civil dusk, not the requested clock time; use altitude_curve or get_celestial_pos for another time. The schedule uses a civil-dark window (Sun below -6 degrees), not astronomical darkness (-18 degrees), and does not validate weather, access, obstructions or achieved integration time. Empty/null slots or exposure values are not an all-night imaging commitment.
Returns: data.targets[] — same structure as get_telescope_targets data.moon — {illumination, phase, moonrise, moonset, always_down, always_up, dark_fraction, altitude_curve} data.plan — {date, slots[{start_time, end_time, target_name}], total_exposure_min, moon_phase, moon_illumination, moon_delay_min} data.config — the TelescopeConfig used data.total — number of matched targets
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| time | Yes | ||
| limit | No | ||
| time_zone | No | UTC | |
| mount_type | No | equatorial | |
| aperture_mm | No | ||
| filter_type | No | ||
| min_altitude | No | ||
| barlow_factor | No | ||
| reducer_factor | No | ||
| focal_length_mm | Yes | ||
| sensor_width_mm | No | ||
| sensor_height_mm | No | ||
| sensor_pixel_size_um | No | ||
| central_obstruction_pct | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the full burden and does it well: it discloses the pipeline composition, that target altitude is reported at civil dusk rather than the requested clock time, that scheduling uses a -6 degree civil-dark window rather than -18 degree astronomical darkness, and that weather/access/obstructions are NOT validated. It also pre-empts misreading empty slots as an all-night imaging commitment.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the use/do-not-use routing, then caveats, then returns. Every section earns its place except the multi-line Returns block, which largely restates the existing output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be explained, yet the description still supplies the interpretive context an agent actually needs: which pipeline it wraps, the civil-dusk vs clock-time discrepancy, the -6 degree dark window, and the unvalidated factors.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% across 16 parameters, and the description only names the four required inputs plus a vague grouping of 'optional sensor, optical, and minimum-altitude settings'. Non-obvious knobs such as limit, mount_type, filter_type, barlow_factor/reducer_factor and central_obstruction_pct get no semantic explanation, so it only partly compensates for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource ('Generate a single-night astrophotography shooting plan') with the composition stated explicitly: it runs match_telescope_targets then generate_shooting_schedule and returns targets + moon + timed slots in one response. That immediately distinguishes it from get_telescope_targets and the multi-night/stargazing planners.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' (optics, place and night fixed) and 'Do not use when' (still choosing a site, comparing nights, only needing target ranks), with the alternative sibling named. The Follow-up line routes to get_telescope_targets and plan_stargazing_session for the excluded cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_telescope_targetsA
Recommend astrophotography targets for a telescope setup.
Use when: place, time, and optics are known and you need ranked deep-sky imaging targets. Do not use when: you only need naked-eye targets, a timed schedule, or a choice of sites. Requires: focal length, observer coordinates, time, and timezone; supply known sensor and optical details for matching. For equipment presets use plan_stargazing_session. Follow-up: get_shooting_plan for timed imaging slots; plan_stargazing_session if the observing place or night still needs comparison; get_celestial_pos for altitude at a specific clock time (the target altitude field is at civil dusk).
Given a telescope/camera configuration and observing location+time, returns a ranked list of deep-sky objects best suited for imaging. Interpretation: altitude is at civil dusk, not at the requested clock time; azimuth is at civil midnight. Use altitude_curve or get_celestial_pos for another time. transit_alt is the sampled peak within the civil-night window, in degrees; transit_time and curve time values are UTC Unix seconds. Null rise/set values mean no crossing was found inside that window, not that an object can never rise/set. suitability_score is a heuristic (higher is better), not a probability or weather clearance. Missing photometry is unknown; do not infer a seasonal visibility error from missing magnitude or from the civil-dusk altitude alone.
Args: focal_length_mm: Telescope focal length in mm (e.g. 250 for RedCat51) lon: Observer longitude in degrees lat: Observer latitude in degrees time: Observation time string "YYYY-MM-DD HH:MM:SS" time_zone: IANA timezone string (e.g. "Asia/Shanghai", "UTC") aperture_mm: Telescope aperture in mm (optional, for limiting magnitude) sensor_width_mm: Camera sensor width in mm (optional) sensor_height_mm: Camera sensor height in mm (optional) sensor_pixel_size_um: Camera pixel size in microns (optional) central_obstruction_pct: Central obstruction percentage (0-50) reducer_factor: Focal reducer factor (default 1.0) barlow_factor: Barlow/extender factor (default 1.0) mount_type: "equatorial" or "altaz" (default "equatorial") filter_type: Filter type — "Hα", "OIII", "SII", or None for LRGB limit: Maximum number of targets to return (default 20)
Returns: data.targets[] — ranked list, best first. Each target has: name, type, magnitude, catalog altitude (civil dusk, degrees), azimuth (civil midnight, degrees), dawn_altitude angular_size_arcmin, angular_size_min_arcmin, angular_size_pa_deg surface_brightness (mag/arcmin²), fov_fit_score, fov_fill_ratio suitability_score (0-100), mosaic_recommended, optimal_rotation_deg rise_time, set_time, transit_time (UTC unix timestamps), transit_alt (degrees) altitude_curve[{time, alt}] civil_dusk, civil_dawn, observation_time data.moon — {illumination, phase, altitude_curve, always_down, always_up, dark_fraction, moonrise, moonset} data.config — the TelescopeConfig used data.total — number of targets returned
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| time | Yes | ||
| limit | No | ||
| time_zone | Yes | ||
| mount_type | No | equatorial | |
| aperture_mm | No | ||
| filter_type | No | ||
| barlow_factor | No | ||
| reducer_factor | No | ||
| focal_length_mm | Yes | ||
| sensor_width_mm | No | ||
| sensor_height_mm | No | ||
| sensor_pixel_size_um | No | ||
| central_obstruction_pct | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well: it states required inputs, interpretation caveats for altitude/azimuth timing, null rise/set semantics, and that suitability_score is a heuristic rather than weather clearance. It also explains that missing photometry means unknown rather than a visibility error.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well structured and front-loaded with Use when / Do not use / Requires / Follow-up guidance. However, the Returns block substantially restates the output schema and makes the definition longer than strictly necessary, even though the interpretive notes within it are useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 15-parameter tool with no annotations and no schema descriptions, the definition is complete: it covers purpose, usage boundaries, required and optional inputs with units, alternatives, follow-ups, and return-field interpretation. The existing output schema means the description does not need to carry the entire return structure, but its added timing and null-value semantics are valuable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description documents all 15 parameters in the Args section, including optional fields, examples, units, enum-like values for filter_type and mount_type, defaults, and the 0-50 range for central_obstruction_pct. This fully compensates for the schema's lack of parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: recommend astrophotography targets for a telescope setup and return a ranked list of deep-sky imaging targets. It also distinguishes the tool from naked-eye targeting, timed scheduling, and site comparison, so an agent can identify its role among siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly names when to use it, when not to use it, and alternatives such as plan_stargazing_session and get_shooting_plan. Follow-up guidance is also provided for timed slots, site comparison, and altitude at a specific clock time.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tool_catalogA
Get metadata for all registered MCP tools.
Use when: you need the wrapped catalog with full documentation and parameter summaries. Do not use when: your client only needs standard MCP tools/list discovery or a business result. Requires: no inputs; this call discovers tools and does not perform observing analysis. Follow-up: choose a tool from its use/do-not-use guidance; plan_stargazing_session is the primary entry for complete observing decisions.
Returns: Dict with keys "data", "_meta". "data.tools" contains tool metadata objects.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses that the tool takes no inputs, discovers tools rather than performing observing analysis, and returns a dict with 'data' and '_meta' keys. It does not mention permissions or rate limits, but for a no-input discovery tool the key behavioral traits are covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured and front-loaded, with clear sections for usage and returns. It is slightly verbose but every sentence supports correct tool selection or invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given this is a zero-parameter discovery tool with an output schema, the description is complete: it explains inputs, usage boundaries, follow-up, and return structure. An agent should be able to call it correctly without additional context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so parameter semantics are inherently simple. The description appropriately states 'no inputs' rather than inventing parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get metadata for all registered MCP tools.' It also distinguishes this tool from standard MCP tools/list discovery, making the purpose clear relative to sibling discovery behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly provides when to use, when not to use, required inputs, and a follow-up path. The guidance distinguishes this catalog tool from business/analysis tools and from standard client-side discovery.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_weather_by_nameA
通过地点名称获取综合天气(当前 + 小时预报 + 日预报)。
Use when: you have a place name and need weather facts for that resolved location. Do not use when: you already have exact coordinates or need a complete observing decision. Requires: an unambiguous place name; use full administrative names for Chinese locations. Provider selection can remain at the server's default aggregation policy. Follow-up: get_weather_by_position for precise coordinates; plan_stargazing_session to combine weather with darkness, targets, and alternative observing sites.
Geocoding uses offline China gazetteer (CJK) → Photon → Nominatim cascade. Weather data is aggregated from multiple providers with graceful fallback. Open-Meteo needs no API key; network/provider failures can still occur. Interpretation: summary.current is current weather, summary.daily is calendar-day aggregation, and summary.hourly contains timestamped forecasts. For a future observing night select the actual hourly timestamps across local midnight and inspect providers and source for failures/provenance. Missing/null or out-of-horizon hours are unknown, not clear weather. Forecasts are predictions, not observations of future conditions; do not assume all providers or fields cover the same dates.
中文地名提示:建议使用完整行政区划名称,如 "浙江安吉"、"杭州西湖区"。
内置离线行政区划数据会正确解析到对应的行政区(如安吉县),而非 POI 商铺。
需要精确定位时优先使用 get_weather_by_position(lat, lon)。
Args: place_name: 地点名称。中文请使用完整行政区划(如 "浙江省安吉县"),避免仅用2-3字短名。 provider: provider 模式,可选 all/qweather/open-meteo/wttr。
Returns: Dict,包含 keys: "data", "_meta"(成功时)或 "error", "_meta"(失败时)。
| Name | Required | Description | Default |
|---|---|---|---|
| provider | No | all | |
| place_name | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does: it discloses the geocoding cascade (offline China gazetteer → Photon → Nominatim), multi-provider aggregation with graceful fallback, that Open-Meteo needs no API key but network/provider failures are possible, and how to read providers/source for provenance. It also warns that missing or out-of-horizon hours are unknown rather than clear, and that forecasts are predictions — exactly the failure semantics an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded: purpose, then when/when-not, then requirements, then follow-ups, then interpretation notes. There is some duplication — the 中文地名提示 block and the trailing Args section repeat the same full-administrative-name guidance already given in 'Requires', so a few lines could be dropped without information loss.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter tool with no annotations and no output schema, the description covers everything an agent needs: input naming rules, provider modes, fallback and failure behavior, and the return shape ('data'/'_meta' on success, 'error'/'_meta' on failure). The interpretation guidance on summary.current/daily/hourly closes the last gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate and does: place_name is documented as requiring unambiguous full administrative names with concrete CJK examples ('浙江省安吉县' rather than 2-3 character short names), and provider is documented with its enumerated modes (all/qweather/open-meteo/wttr) even though the schema declares no enum. This adds substantial meaning beyond the bare schema types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first line states a specific verb (获取/get) plus a compound resource (current + hourly + daily weather) and the resolution method (by place name). The follow-up line explicitly names get_weather_by_position as the coordinate-based sibling, so an agent can route between the two without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' / 'Do not use when' pair covers both the positive trigger (place name in hand) and the two exclusions (exact coordinates, need for a complete observing decision). Follow-up names the concrete alternatives (get_weather_by_position, plan_stargazing_session) with the condition that selects each.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_weather_by_positionA
通过经纬度获取综合天气(当前 + 小时预报 + 日预报)。
Use when: you have precise coordinates and need current and forecast weather facts. Do not use when: you only have a place name or need ranked observing sites or night targets. Requires: latitude and longitude; provider selection can remain at the default policy. Follow-up: get_weather_by_name for place-name input; plan_stargazing_session to compare observing places and nights using weather and other evidence.
Weather data is aggregated from multiple providers with graceful fallback. Open-Meteo needs no API key; network/provider failures can still occur. Interpretation: summary.current is current weather, summary.daily is calendar-day aggregation, and summary.hourly contains timestamped forecasts. For a future observing night select the actual hourly timestamps across local midnight and inspect providers and source for failures/provenance. Missing/null or out-of-horizon hours are unknown, not clear weather. Forecasts are predictions, not observations of future conditions; do not assume all providers or fields cover the same dates.
Args: lat: 纬度 lon: 经度 provider: provider 模式,可选 all/qweather/open-meteo/wttr。
Returns: Dict,包含 keys: "data", "_meta"(成功时)或 "error", "_meta"(失败时)。
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| provider | No | all |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: multi-provider aggregation with graceful fallback, Open-Meteo needs no API key, network/provider failures possible, and field semantics for summary.current/daily/hourly. It further warns that missing or out-of-horizon hours are unknown rather than clear, and that forecasts are predictions with uneven provider coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded structure is excellent: purpose, Use when, Do not use when, Requires, Follow-up, then interpretation notes. Slightly long, and the Args block partly restates what the schema already shows, but no sentence is wasted given the absence of annotations and output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-param weather tool with no annotations and no output schema, the description covers return shape (data/_meta vs error/_meta), provenance/failure inspection, and forecast interpretation caveats. Nothing an agent needs to call or interpret it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It enumerates the provider modes (all/qweather/open-meteo/wttr), which the schema does not (no enum, just a string default), adding real meaning. lat/lon are only labelled 纬度/经度, which is trivially inferable, so this is strong but not fully compensatory.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope: fetch consolidated weather (current + hourly + daily) by coordinates. The sibling get_weather_by_name is implicitly contrasted via the 'Use when' clause, so an agent can distinguish them without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' (precise coordinates, current + forecast facts) and 'Do not use when' (place name only, ranked sites, night targets), plus named follow-ups get_weather_by_name and plan_stargazing_session. Routing is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
light_pollution_mapA
Get light pollution data for a specific area.
Use when: you need a bounding-box grid of light pollution measurements for a map or analysis. Do not use when: you need ranked places or a complete observing decision. Requires: south/west/north/east bounds and optional grid zoom. Returns: data.grid points with brightness, Bortle class, and SQM, plus bounds and zoom. Follow-up: analysis_area for synchronous place candidates; submit_area_analysis for background place analysis; plan_stargazing_session for an observing decision.
Returns a grid of light pollution data points including brightness, Bortle class, and SQM.
Args: south, west, north, east: Bounding box coordinates. zoom: Grid resolution zoom level (default: 10). Higher = more detailed.
| Name | Required | Description | Default |
|---|---|---|---|
| east | Yes | ||
| west | Yes | ||
| zoom | No | ||
| north | Yes | ||
| south | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does most of it: it discloses required inputs, the shape of the response (data.grid points with brightness, Bortle class, SQM, bounds, zoom), and that zoom controls granularity. It does not mention rate limits, cost, or caching behavior for what is presumably a remote data fetch, which keeps it short of 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, followed by tightly labeled Use/Do not use/Requires/Returns/Follow-up sections that are easy to scan. The only waste is the redundant restatement of the return value later in the description ('Returns a grid of light pollution data points...'), which repeats the earlier 'Returns' line.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter read tool with an output schema, the definition covers purpose, preconditions, response shape, granularity control, and follow-up routing. An agent has everything needed to decide to call it and to invoke it correctly without further inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it largely does: it identifies south/west/north/east as bounding-box coordinates and explains zoom as grid resolution where higher means more detail (the default is already visible in the schema). It does not specify accepted coordinate ranges or zoom bounds, so a small gap remains.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Get light pollution data') and immediately narrows scope to a 'bounding-box grid of light pollution measurements'. It also explicitly names siblings it is not (ranked places, complete observing decision), so an agent can separate it from analysis_area and plan_stargazing_session without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when' and 'Do not use when' conditions, plus a 'Follow-up' line routing to analysis_area, submit_area_analysis, and plan_stargazing_session for the cases this tool does not cover. This is exactly the when/when-not/alternatives structure that earns top marks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_visible_planetsA
Get a list of solar system planets currently visible (above horizon).
Use when: you need planets above the observer's horizon at a specified instant. Do not use when: you need all-night visibility, darkness guarantees, or equipment ranking. Requires: observer coordinates, time, and timezone; above-horizon visibility alone does not establish dark-sky or telescope observing conditions. Follow-up: get_celestial_pos or get_celestial_rise_set for a selected planet; plan_stargazing_session for a planetary observing decision.
Args: lon: Observer longitude in degrees lat: Observer latitude in degrees time: Observation time string "YYYY-MM-DD HH:MM:SS" time_zone: IANA timezone string
Returns: Dict with keys "data", "_meta". "data" is a list of planet dicts (name, altitude, azimuth).
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| time | Yes | ||
| time_zone | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, and it does disclose the key semantic caveat: above-horizon visibility does not imply dark-sky or telescope conditions, plus the required inputs. It stops short of stating whether results are cached or what _meta contains, which is minor for a pure computation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded purpose followed by clearly labeled Use when / Do not use when / Requires / Follow-up / Args / Returns sections makes it skimmable, and nearly every line earns its place. The Returns block partially repeats what the output schema already declares, a small redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given four required parameters, zero annotation coverage, and an output schema that exists, the description supplies everything an agent needs: preconditions (coordinates, time, timezone), the visibility semantics, sibling routing, and a brief return shape.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: all four parameters are documented with units (degrees for lon/lat), an explicit time string format "YYYY-MM-DD HH:MM:SS", and 'IANA timezone string' for time_zone. Only lat/lon valid ranges are left implicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get a list of solar system planets') with a clear scope qualifier ('currently visible, above horizon'), and the usage/exclusion lines separate it from siblings like get_celestial_rise_set and get_best_stargazing_plan.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' and 'Do not use when' clauses name the exact conditions that select or exclude this tool, and the Follow-up line routes the agent to the correct siblings (get_celestial_pos, get_celestial_rise_set, plan_stargazing_session) with the condition for each.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_stargazing_sessionPlan Stargazing SessionARead-onlyIdempotent
Preferred end-to-end planning entry point for choosing when, where, and what to observe across one to seven nights.
Use when: you need a complete observing decision or comparisons of places and nights. Do not use when: you only need raw weather, celestial facts, or task status. Requires: request.location (place name, center/radius, or exact bounds) and start_date; timezone, one-to-seven nights, observing goal, equipment preset/overrides, and supported preference fields have explicit defaults or are optional. A center/radius is a regional search, not a plan locked to the center point. The radius becomes an approximate search box, not a strict circular distance filter. Quietness/popularity adjustments require the corresponding preference flags. Pass request as a JSON object, not a JSON string; inspect resolved_location before describing a candidate as the exact user-specified site. Returns: normalized request, decision, alternatives, evidence, uncertainties, missing inputs, ranking-change conditions, and next actions in the standard envelope. Weather evidence uses dated night-hour forecasts. Missing weather or no usable window excludes a candidate from decision and alternatives; unranked_planning_reference evidence retains known location/sky facts with weather_unknown or no_usable_window status. If none qualify, decision=null. Partial coverage remains provisional. Civil-dark windows are not astronomical darkness. Interpretation: recommendation_score is a relative ranking, not a probability or an absolute go/no-go threshold. _meta.status=success means execution succeeded; decision=null means no selected session. A null observation_window means no usable window was established, not an all-night opening. Inspect evidence, uncertainties, missing_inputs and next_actions even on success. nightly_weather_unavailable and no_usable_observation_window are high-uncertainty warnings; long_range_forecast requires a forecast recheck near departure. Never replace missing night hours with summary.current or summary.daily, or infer a provider from weather wording. Civil darkness means Sun below -6 degrees, not astronomical darkness at -18 degrees; its duration is not guaranteed exposure time. Popularity/quiet scores are heuristics, not measured noise or calibrated crowd probabilities. When equipment is supplied, decision.targets already contains equipment-matched targets; use that list to answer the selected session's target question without a second lookup. Keep the returned target order; do not compare scores across generic and equipment rankings. This is a synchronous call and can exceed a client default deadline; a timeout does not establish that a background planning task exists. Follow-up: get_shooting_plan for an imaging schedule at the selected place/night; get_weather_by_position for updated weather facts. Inspect missing inputs and next actions before treating a degraded decision as final.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations (readOnly/idempotent/openWorld) by disclosing that this is a synchronous call that can exceed a client deadline and that a timeout does not imply a background task exists. It also explains degradation behavior (missing weather excludes a candidate, decision=null when none qualify, unranked_planning_reference retention) and warns the agent to inspect evidence, uncertainties and missing_inputs even on success.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, use-when/when-not, requirements and return shape in that order, which is the right structure for a complex planning entry point. It is long and carries some redundancy — civil vs astronomical darkness is asserted twice ('Civil-dark windows are not astronomical darkness' and later 'Civil darkness means Sun below -6 degrees, not astronomical darkness at -18 degrees') — so it is dense rather than tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even with an output schema present, the description adds the interpretation layer an agent actually needs: recommendation_score is relative not probabilistic, _meta.status=success is separate from decision=null, null observation_window is not an all-night opening, and the named high-uncertainty warnings plus long_range_forecast recheck. It also closes the equipment loop by pointing to decision.targets to avoid a second lookup.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The headline schema-coverage metric is 0% (only a $ref at the top level), so the description carries real weight — and it does: it states which fields are required, that timezone/nights/goal/equipment have defaults, that a radius becomes an approximate search box rather than a circular filter, and that quietness/popularity adjustment requires the corresponding flags. It also adds an operational rule the schema cannot express: pass request as a JSON object, not a JSON string, and inspect resolved_location before calling a candidate the exact site.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource with scope: 'Preferred end-to-end planning entry point for choosing when, where, and what to observe across one to seven nights.' The word 'preferred' implicitly claims primacy over near-neighbors like get_best_stargazing_plan and get_multiday_stargazing_plan, but those overlapping planners are never named, so the agent still has to guess when the others win.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when:' (need a complete observing decision or comparisons of places and nights) and 'Do not use when:' (raw weather, celestial facts, task status) sections, plus a dedicated Follow-up block routing to get_shooting_plan and get_weather_by_position. When and when-not are both spelled out rather than inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_area_analysisA
Submit bounded background place analysis and return its task identifier.
Use when: a geographic place search may outlive one tool call and needs background control. Do not use when: you need a complete observing decision or only want to poll an existing task. Requires: request.bounds and optional place-search preferences; max_locations must be from 1 to 100. Returns: task snapshot with task_id, resource_id, state, and normalized request. Active duplicate queries share a task. Completed retries may use cached data. Follow-up: get_area_analysis_task to poll; get_area_analysis_result after success; cancel_area_analysis_task if no longer needed; plan_stargazing_session for decisions.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=false, destructive=false, openWorld=true, idempotent=false; the description adds genuinely non-obvious behavior — active duplicate queries share a task and completed retries may hit cached data — which explains the non-idempotent hint. It stops short of stating any authorization, quota, or cost implications of the submission.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Labeled sections (Use when / Do not use when / Requires / Returns / Follow-up) put the decision criteria first and keep every line functional. The final 'plan_stargazing_session for decisions' phrase is compressed to the point of being slightly cryptic, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the async lifecycle, dedupe/caching semantics, and required inputs, and an output schema exists so return-shape detail is not needed. The only omission is an explicit statement of how this differs from 'analysis_area', which an agent choosing between the two would want.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Top-level schema coverage is effectively nil (one 'request' property with no description), but the nested AreaAnalysisRequest and GeoBounds fields are individually documented. The description only restates that bounds is required and repeats the 1-100 max_locations bound already enforced by the schema, adding little beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ('Submit bounded background place analysis') and states the return ('task identifier'), so the async submit role is unmistakable. It does not explicitly contrast with the sibling 'analysis_area' (the presumable synchronous variant), which is the one remaining disambiguation gap.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when' and 'Do not use when' clauses with concrete conditions (long-running place search vs. polling an existing task vs. needing a final decision). The Follow-up line routes the agent to get_area_analysis_task, get_area_analysis_result, cancel_area_analysis_task, and plan_stargazing_session by lifecycle stage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.10.0- Changed
analysis_area3 fields changed- added
Input schema / properties / avoid_popular_spotsAdded value: +{ + "default": false, + "type": "boolean" +} - added
Input schema / properties / popularity_radius_kmAdded value: +{ + "default": 3, + "type": "number" +} - added
Input schema / properties / prefer_quiet_at_nightAdded value: +{ + "default": false, + "type": "boolean" +}
- Added
cancel_area_analysis_task - Added
get_area_analysis_result - Added
get_area_analysis_task - Changed
get_best_stargazing_plan4 fields changed- added
Input schema / properties / avoid_popular_spotsAdded value: +{ + "default": false, + "type": "boolean" +} - added
Input schema / properties / observation_styleAdded value: +{ + "default": "balanced", + "type": "string" +} - added
Input schema / properties / popularity_radius_kmAdded value: +{ + "default": 3, + "type": "number" +} - added
Input schema / properties / prefer_quiet_at_nightAdded value: +{ + "default": false, + "type": "boolean" +}
- Changed
get_celestial_rise_set1 field changed- added
Input schema / properties / event_scopeAdded value: +{ + "default": "calendar_day", + "type": "string" +}
- Added
get_multiday_stargazing_plan - Added
plan_stargazing_session - Added
submit_area_analysis
2 tool updates
v0.7.0- Added
get_shooting_plan - Added
get_telescope_targets
1 tool update
v1.0.1- Changed
get_moon_info2 fields changed- added
Input schema / properties / latAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / lonAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null +}
1 tool update
v0.4.0- Added
get_best_stargazing_plan
2 tool updates
v0.3.2- Changed
get_weather_by_name1 field changed- added
Input schema / properties / providerAdded value: +{ + "default": "all", + "type": "string" +}
- Changed
get_weather_by_position1 field changed- added
Input schema / properties / providerAdded value: +{ + "default": "all", + "type": "string" +}
3 tool updates
v0.3.0- Added
get_tool_catalog - Removed
get_visible_planets - Added
list_visible_planets
11 tool updates
v1.0.0- First observed
analysis_area - First observed
get_celestial_pos - First observed
get_celestial_rise_set - First observed
get_constellation - First observed
get_local_datetime_info - First observed
get_moon_info - First observed
get_nightly_forecast - First observed
get_visible_planets - First observed
get_weather_by_name - First observed
get_weather_by_position - First observed
light_pollution_map
TDQS
Scored across 21 tools
Most tools have clearly distinct resource/action targets, and the descriptions explicitly distinguish synchronous area search from background area tasks, weather by name from weather by coordinates, and target ranking from shooting schedules. Some overlap remains among plan_stargazing_session, get_best_stargazing_plan, and get_multiday_stargazing_plan, as well as between general nightly targets and telescope-specific targets.
The set is predominantly consistent snake_case with predictable verb_noun forms such as get_*, list_*, submit_*, cancel_*, and plan_*. Minor deviations exist: light_pollution_map and analysis_area are noun phrases without verbs, but they remain readable and understandable.
At 21 tools, the surface is on the heavy side for an MCP server and spans several subdomains: weather, celestial facts, planning, area analysis, and astrophotography. The count is defensible given the scope, but it is borderline and increases selection burden.
The server covers the core stargazing workflow well: weather, celestial positions and rise/set, Moon and planets, constellations, light pollution, synchronous and asynchronous area analysis, telescope targets, shooting plans, and single/multi-night planning. Minor gaps remain for adjacent observing needs such as meteor showers, satellite passes, aurora, or explicit equipment/profile management.
Maintenance
Related MCP Connectors
Elevation-corrected sun, moon, twilight, solar and tide data for any point on Earth
Offline observational astronomy: positions, rise/set, moon phases, eclipses, and seasons.
Read-only astronomy calculations: sun, moon, planets, eclipses, twilight and star positions.
Sunrise, sunset, twilight, golden hour and moon times for any place on Earth. Free, no API key.
Related MCP Servers
- FlicenseAqualityDmaintenanceProvides altitude-azimuth coordinates for celestial objects including planets, over 117,000 stars, and 14,000 deep sky objects based on system time and configurable location.31-
- FlicenseNot gradedqualityDmaintenanceEnables satellite orbital mechanics calculations including visibility predictions, access window analysis, and TLE generation from natural language descriptions. Supports 200+ world cities and multiple orbit types (LEO, MEO, GEO, SSO, Molniya, Polar).-
- AlicenseAqualityFmaintenanceProvides authoritative astronomical data including moon phases, solar eclipses, and sun/moon rise and set times using the US Navy API or offline Skyfield calculations. It enables users to query Earth's seasons and celestial events for any location and date.81Apache 2.0
- AlicenseAqualityDmaintenanceProvides astronomical calculations using the Swiss Ephemeris library, including planetary positions, houses, chart points, and asteroids for any date and location.410MIT