nina_planner
nina_planner is an MCP tool server for N.I.N.A. that lets you inspect equipment, write and track observation plans, and manage acquisition sequences.
Inspect live equipment status, capabilities, and safety/weather data.
Retrieve the active observatory profile, recent events, logs, and imaging metadata.
Write observation plan JSON files with target coordinates, exposure settings, and equipment config.
Check per-frame-type acquisition progress for a plan, with optional quality thresholds.
Load acquisition sequences (light, dark, bias, dawn_flat, dusk_flat) from a plan.
Start, stop, and inspect the state of loaded sequences.
Execute teardown to stow the telescope or enter safety standby.
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., "@nina_plannerwrite a plan for M31, load lights, and start the sequence"
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.
nina_planner — An Observatory Operator Agent

nina_planner is an MCP tool server for N.I.N.A. (Nighttime Imaging 'N' Astronomy). It lets you inspect equipment, write observation plans, load sequences, and control the telescope — all through tool calls in your AI client. The focus is on tools to generate and manage sequences on N.I.N.A. rather than issuing real-time raw Advanced API commands. This MCP server can generate "plans" — in the style of ACP (DC-3 Dreams) observatory plans, but as JSON — which can then be loaded and run as N.I.N.A. Advanced sequences.
Available Tools
Equipment & Telemetry
Tool | Purpose |
| Return the current connection state, operating state, measurements, and capabilities of active observatory equipment (mount, camera, focuser, guider, safety monitor, weather, dome, filter wheel, rotator). Auto-connects any device that is present but disconnected; if any device is mid-connect the call will error and the agent should retry after a few seconds. |
| Get observatory location (lat/lon/elevation), optics details, filter list, plate solver type, and image save path — as the raw Windows |
| List every NINA observatory profile — each with its id, name, description, and last-used time — marking the currently active one. Use it to discover which profiles exist and to find the id of the one you want. Only the active profile exposes full site/optics/filter detail. |
| Switch the active NINA profile to the one with the given id (from |
| Get latest observatory event log entries from |
| Get latest N.I.N.A. application log entries from |
| Capture the N.I.N.A. dashboard as a PNG and return two content blocks: the absolute file path as text, then the image itself (e.g. |
| Return imaging metadata for an observation-plan JSON file and one of its pointings, for the image type (light, dark, bias, flat — case-insensitive) as a wide table with one row per exposure. Light frames are attributed via the |
| Write out an observation plan JSON file. |
| Expand a base plan into a multi-pointing mosaic plan from a Telescopius-formatted mosaic CSV (one pointing per pane). Replaces the base plan's pointings, clears its |
| Report per-frame-type progress for every pointing: total, acquired (attributed to |
Sequence Management
Tool | Purpose |
| Load a plan file as a sequence without starting it — call |
| Start the currently loaded sequence. |
| Stop any running sequence and wait until NINA reports it has actually stopped. |
| A list of request objects (the only form) composes one N.I.N.A. sequence for the whole night: a single Start area, one Target area holding each step's containers in list order, and a single End area that always stows (park, then warm), so the night ends parked and warm no matter what ran. An empty list is therefore the stow: an empty Target area plus that closing End area — one bounded 3-minute "On Safe" wait, then park (or home) the mount and warm the camera. Every action is plan-backed; there is no |
| Return the loaded sequence structure and the current status of its containers, instructions, conditions, and triggers (whether loaded, running, completed, failed, or waiting). |
| Terminate the NINA.exe application immediately via taskkill. Liveness comes from the REST API: it no-ops when NINA is already down, and errors when NINA is up but remote (no local Windows interop) since it cannot be terminated from here. |
| Launch NINA into the active interactive desktop session (GUI visible). With |
| REST-API-authoritative liveness probe: |
| Report NINA's clock versus host clock, delta in seconds, and whether NINA is on simulated time. |
Related MCP server: NASA-MCP
The Observation Plan
A plan is a JSON document that describes one complete imaging session. It encodes the target, exposure settings for all four frame types (light, flat, dark, bias), and equipment configuration (cooler, autofocus, guiding, constraints).
Plan structure
An example json plan:
veil-nebula_widefield-supernova-remnant_20260913T080623.json
{
"target": "Veil Nebula",
"intent": "Widefield supernova remnant",
"description": "Veil Nebula complex centered between Western NGC 6960 and Eastern NGC 6992",
"pointings": [
{
"ra_hours": 20.85,
"dec_deg": 31.22
}
],
"batch_size": 5,
"cooler": {
"on": true,
"setpoint_celsius": -10.0
},
"constraints": {
"min_altitude": 30.0,
"horizon_offset_degrees": 2.0
},
"autofocus": {
"reference_filter_name": "LP",
"hfr_increase_sample_size": 3,
"hfr_increase_threshold_percent": 15.0,
"every_n_exposures": 10,
"threshold_celsius": 1.0
},
"guiding": {
"dither_every_n_exposures": 2,
"check_drift_every_n_exposures": 6,
"max_drift_arcmin": 1.5
},
"light_frames": [
{
"filter_name": "LP",
"exposure_time_seconds": 60.0,
"total_count": 60
}
],
"flat_frames": [
{
"filter_name": "LP",
"exposure_time_seconds": 5.0,
"total_count": 30
}
],
"dark_frames": [
{
"exposure_time_seconds": 60.0,
"total_count": 20
}
],
"bias_frames": [
{
"total_count": 30
}
]
}Fields
Field | Required | Description |
| no | Catalog designation, e.g. "M31", "NGC 7000" |
| no | 2-3 words describing the goal |
| no | Stable identifier stamped on write. Used for frame attribution; when absent, a deterministic hash of plan content is used. |
| no | explanation of the observation plan, including rationale, exposure goals, equipment, or sky constraints |
| yes | One or more target pointings. Each is a |
Pane, RA, DEC, Position Angle (East), Pane width (arcmins), Pane height (arcmins), Overlap, Row, Column
Pane 1, 0hr 56' 01", 45º 51' 18", 0.00, 309.00, 205.80, 10%, 1, 1
Pane 2, 0hr 29' 28", 45º 51' 18", 0.00, 309.00, 205.80, 10%, 1, 2
Pane 3, 0hr 55' 22", 42º 46' 13", 0.00, 309.00, 205.80, 10%, 2, 1
Pane 4, 0hr 30' 07", 42º 46' 13", 0.00, 309.00, 205.80, 10%, 2, 2
Pane 5, 0hr 54' 47", 39º 41' 07", 0.00, 309.00, 205.80, 10%, 3, 1
Pane 6, 0hr 30' 42", 39º 41' 07", 0.00, 309.00, 205.80, 10%, 3, 2
Pane 7, 0hr 54' 15", 36º 36' 00", 0.00, 309.00, 205.80, 10%, 4, 1
Pane 8, 0hr 31' 14", 36º 36' 00", 0.00, 309.00, 205.80, 10%, 4, 2Each row becomes a Pointing: RA/DEC are parsed server-side (sexagesimal like 0hr 56' 01" / 45º 51' 18" or decimal), Pane becomes the label, and Row/Column are stored as row/column metadata (N.I.N.A. does not use them — they are kept for ordering, labeling, and later mosaic assembly). The base plan's plan_id is cleared so the mosaic gets its own content-derived id; each pane is attributed independently via ({plan_id}-{pointing_index}).
No rotator: every pane's
position_angle_degmust be0. Any nonzero PA fails loudly, since PA can't be enforced without a rotator.Acquiring panes: query
get_plan_progress(file_path)to see which panes still need frames, then load the first incomplete pane withload_sequence(request=[{"plan": file_path, "action": "light", "pointing_index": N, "mode": "remaining"}])andstart_sequence(). Repeat pane by pane across the night; when the top-levelcompleteis true, the mosaic is done.
Workflow: A Complete Imaging Run
1. Write the plan
Use write_plan_file with the plan object. This validates the filter names against your active N.I.N.A. profile and writes a JSON file named like veil-nebula_widefield-supernova-remnant_20260913T080623.json.
2. Load and run each calibration type, including lights
Each call to load_sequence composes the appropriate steps (lights, darks, flats, or bias) into one N.I.N.A. sequence and posts it — it only loads the sequence; it never starts it. Every step below is therefore two calls: load_sequence(...), then start_sequence() when you are ready to begin (or press start in the NINA GUI yourself). N.I.N.A. rejects a load while a sequence is running, so stop any running sequence first with stop_sequence() (which blocks until it has actually stopped); load_sequence returns a clear error telling you to do so otherwise.
Or hand N.I.N.A. the whole night in one call: pass the whole night as one list of request objects:
load_sequence(request=[{"plan": "<plan>.json", "action": "light", "pointing_index": 1}, {"plan": "<plan>.json", "action": "light", "pointing_index": 2}, {"plan": "<plan>.json", "action": "dark"}]) then a single start_sequence()
The steps run in list order inside one sequence (one Start area, one Target area, one End area), one POST carries the lot, and entries already complete in remaining mode are skipped and reported. The End area always stows (park + warm) — so the night ends parked and warm no matter what ran, and an empty list with no steps at all is exactly the stow. Each step keeps its own conditions: a step whose window has passed (dawn flats after sunrise) is skipped instead of blocking the steps behind it.
Example order:
Run lights (main imaging overnight):
load_sequence(request=[{"plan": "<plan>.json", "action": "light"}])thenstart_sequence()(runs all night; autofocus and guiding triggers are built in)Run darks (done during the day or while flats are not possible):
load_sequence(request=[{"plan": "<plan>.json", "action": "dark"}])thenstart_sequence()(wait for completion; add"variant": "cover"to cut the light with a motorized cover instead of the wheel'sDarkslot)Run bias (also done during the day):
load_sequence(request=[{"plan": "<plan>.json", "action": "bias"}])thenstart_sequence()(wait for completion)Run dawn flats (morning twilight):
load_sequence(request=[{"plan": "<plan>.json", "action": "flat", "variant": "dawn"}])thenstart_sequence()(wait for completion)Run dusk flats (as evening twilight begins):
load_sequence(request=[{"plan": "<plan>.json", "action": "flat", "variant": "dusk"}])thenstart_sequence()(wait for completion)
3. Teardown
At session end:
The running sequence should teardown automatically at dawn.
load_sequence()thenstart_sequence()— the empty list is the stow; only needed if want to immediately close for the night or the running sequence fails to park. Every action is plan-backed, so an empty list is the only teardown form.
Notes
Required N.I.N.A. plugins: the MCP server requires the following three plugins to be installed in N.I.N.A.: Advanced API, Sequencer+, and Session Metadata.
Image file pattern: in the N.I.N.A. profile's
ImageFileSettings,FilePatternmust put$$IMAGETYPE$$in a path segment (e.g.$$DATEMINUS12$$\$$IMAGETYPE$$\...) so frames can be read per type, and — for light attribution — must include$$TARGETNAME$$(see below). The$$DATEMINUS12$$date folder is no longer required: calibration age is measured from each frame's ownExposureStarttimestamp, not the folder name.Filter validation:
write_plan_fileandload_sequencecheck that every filter name in the plan (lights, flats, autofocus reference) matches a filter in your active N.I.N.A. profile. Unknown filters will be rejected with an error listing what is available.Frame attribution: each light sequence names its target
<target>(or<target> - <label>when the pointing has a label), followed by({base_plan_id}-{pointing_index}), and N.I.N.A. expands$$TARGETNAME$$inFilePatternto that string. For the embedded id to be usable for attribution,$$TARGETNAME$$must appear somewhere in the file pattern — either as a filename token (e.g...._$$TARGETNAME$$_...) or as a folder segment (e.g.$$DATEMINUS12$$\$$IMAGETYPE$$\$$TARGETNAME$$\...). Attribution reads the embedded id from the recorded file path (file_pathinImageMetaData.csv) and accepts it in any path segment — the filename, the target directory under$$IMAGETYPE$$, or an ancestor directory when$$TARGETNAME$$leads the pattern (e.g.$$TARGETNAME$$\$$DATEMINUS12$$\$$IMAGETYPE$$\...). The token is unique to a plan pointing, so ancestor matching cannot cross-attribute between plans; if the target name is not embedded in the path at all, attribution cannot determine which plan/pointing a light frame belongs to. Parentheses are used because N.I.N.A. mangles square brackets in target names; only the parenthesised token is recognised, so frames acquired under the earlier[{base_plan_id}-{pointing_index}]form are not attributed. The sequence also records the target inTargetNameinAcquisitionDetails.csvand asOBJECTin FITS headers, but those are informational — file-path attribution is what drivesget_plan_progressandmode="remaining".Resuming a pointing: call
get_plan_progress(file_path, ...)and read the entry for pointingNin the returnedpointingslist to see what it has already acquired, thenload_sequence(request=[{"plan": <plan_path>, "action": "light", "pointing_index": N, "mode": "remaining"}])to acquire only the deficit. Lights are attributed by the{base_plan_id}-{pointing_index}id embedded in the file path (so$$TARGETNAME$$must be in the file pattern — see above). Different pointings of the same plan file are attributed independently because their embedded ids differ. Flats, darks, and bias are matched by image type/filter/exposure and are anchored to the plan's light session: they count only when shot withincalibration_window_days(default 7) of the earliest attributed light, on either side of it. Calibration acquired inside that window stays counted, so it is not re-shot on every later run. While the current time is still inside the window the deficit is reported (andwindow_openistrue); once the current time falls outside it,remaining_countreads 0 withwindow_open: falseandload_sequence(request=[{"plan": <plan_path>, "action": "dark", "mode": "remaining"}])loads nothing — raisecalibration_window_daysor write a new plan to reopen the window. Passmode="full"to deliberately re-acquire. For a mosaic,get_plan_progress(file_path)summarizes every pane at once — see Mosaics.Quality thresholds:
max_hfrandmin_detected_stars(optional) exclude light frames that fail the thresholds from the acquired count. Frames missing the quality fields are excluded whenever a threshold is set (fail-closed). Thresholds are applied only to light frames — calibration frames have no star quality.Manually failing a frame: delete (or move) the image file on disk — e.g. a bad
.fits/.tif. The metadata row stays in the CSV (the plugin only appends), but it is omitted when the metadata is read, so progress no longer counts that frame as acquired and the nextmode="remaining"load re-acquires it.The plan file is persistent — written to the current working directory. You can inspect, edit, and reuse it across sessions.
Experimental: This code is highly experimental. At the moment I am testing it at my observatory. However I don't have a camera cooler. So those operations are untested. The agent generates an advanced sequence that it loads into N.I.N.A. This sequence is still in alpha.
nina-plugin.ts — OpenCode v2 Autonomous Plugin
nina-plugin.ts is an opencode v2 plugin (not compatible with Claude Code or other MCP clients). Once registered in opencode.json, it runs as a background server inside opencode and does two things:
Websocket event monitoring — Connects to the N.I.N.A. event socket (
ws://<host:port>/v2/socket), subscribes to all events, and forwards them to the active agent as intervention prompts. Events are batched with a 1-second debounce to avoid flooding the conversation.Interval check — Every
NINA_INTERVAL_MINUTES(default 10) it prompts the agent to query observatory status (get_sequence_state,get_site_equipment_status) and decide what to do next, even when no N.I.N.A. events are firing.
The plugin triggers a dedicated opencode "agent" called worker (see worker.md), if it is configured, otherwise it uses the main session model. Both websocket-event triggers and interval checks prompt the same worker agent in an isolated session, which checks observatory status and takes action.
The plugin auto-reconnects on websocket disconnection with a 5-second retry. On server dispose, it cleans up all timers and the socket.
AGENTS.md — OpenCode Worker Agent
AGENTS.md (in .opencode/agents/) defines the observer agent that the active console user becomes and the nina-plugin.ts triggers for automated safety interrupts, sequence halts, and recovery routines.
PLAN.md — the living wishlist
A markdown file at the project root, edited by the user at any time (before or during the night). It is intentionally lightweight — entries can be as simple as a target name:
Metadata — night date, overall intent (optional).
Candidate targets — each with:
name / catalog designation (minimum required — everything else optional)
optional: coordinates, filter + exposure + count (if you want specifics)
optional: reference to an existing plan JSON file, or let the worker generate one
priority (1 = highest, optional)
optional time window / note
Selection rules — how the worker picks among candidates:
altitude floor (default e.g. 30°)
horizon buffer
tie-break order (priority, then highest current altitude, then earliest available)
Example shapes (illustrative — both are valid):
# Tonight - 2026-10-08
- M31 "before the moon comes up"
- Veil Nebula plan=veil-nebula_..._20260913.json prio 1
- M33 "if high targets done"
Rules:
- min_altitude: 30
- horizon_offset_degrees: 2
- tie_break: priority, then altitudeHow the night runs
The worker evaluates each un-imaged candidate, computes its current altitude (or loads its plan sequence and lets N.I.N.A. report it), and picks the best target: highest priority, then highest current altitude, then earliest available. It never interrupts a running observation — re-selection only happens after a sequence finishes.
For the chosen target, the worker loads the referenced plan JSON if given, otherwise generates one via
write_plan_file(using coords/filter/count fromPLAN.md, or sensible defaults), thenload_sequence(request=[{"plan": <plan_path>, "action": "light"}])followed bystart_sequence().When no candidate is viable (all below the altitude floor, or the night is over), the worker writes
report.md(overwriting any previous one) with the night's results, stows the scope, and stops. EditingPLAN.mdlater triggers re-evaluation.You can add/remove/reorder lines at any moment. The worker records completion in
PROGRESS.mdinstead and leavesPLAN.mduntouched, so your editing isn't fought over.
PROGRESS.md — Shared Progress File
PROGRESS.md is a shared observatory progress file in the project directory. Both the active session and the automated worker sessions read it on start to restore context before acting, and append a short ISO-8601-timestamped entry after each significant action (status checks, plan writes, sequence loads/starts/stops, errors, and interventions), recording what was done, the observed equipment and safety state, and any decisions. This keeps history shared across sessions.
opencode.json — Opencode v2 Sample Configuration
{
"$schema": "https://opencode.ai/config.json",
"plugins": [
{
"package": "./local/plugins/nina_notify",
"options": {
"pluginLogs": "C:/Windows/Temp/nina-notify-debug.log"
}
}
],
"mcp": {
"nina-planner": {
"type": "local",
"environment": {
"NINA_PLANNER_LOG": "C:/Windows/Temp/nina-planner-debug.log"
},
"command": [
"uv", "--directory", ".opencode/local/mcps/nina_planner", "run", "-m", "nina_planner"
]
}
}
}Registers the opencode plugin and the nina_planner MCP server so both run together. The MCP server provides the tools (load_sequence, get_site_equipment_status, etc.) that the plugin-prompted agent calls.
Plugin Options
nina-plugin.ts (opencode v2 plugin)
Configured under opencode.json > plugin as the second array element (see opencode.json).
Option | Type | Default | Description |
| string |
| N.I.N.A. host and port (no scheme) for the websocket event stream, e.g. |
| number |
| Minutes between autonomous status-check triggers of the |
| string | (none) | File path appended on each plugin event (websocket open/message/close/error, batched flush, interval trigger failures). Set to a writable path (e.g. |
| string | (none) | File path that receives an append-only JSON-lines record of every |
Environment Variables
nina_planner (MCP server)
Variable | Default | Description |
|
| N.I.N.A. host and port for the REST API ( |
| — | Local mount root for the drive letter in the profile's |
|
| Altitude in degrees for flat panel calibration frames |
|
| Azimuth in degrees pointing west for dawn flats |
|
| Azimuth in degrees pointing east for dusk flats |
|
| Windows path to |
Setting up WSL
Make sure you have setup mirroring to allow you to connect to NINA via localhost. Do this by editing wslconfig and setting networking mode to mirrored. Otherwise you will have to know the external ip of your machine in order to connect to your NINA API endpoint.
$ vi $HOME/.wslconfig
[wsl2]
networkingMode=mirroredThen shutdown wsl and restart
[$ wsl --shutdown](./$ wsl --shutdown)
$ wsl --shutdown
<Error: File '$ wsl --shutdown' not found on disk>In addition, to get the system tools to work to stop and restart NINA should it stop, make sudo password less with:
$ echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/90-userElevation & the "Change the system time" privilege
start_nina(time=...) shifts the Windows host clock with Set-Date and restores it after NINA captures the simulated time. Both calls need the "Change the system time" privilege (SeSystemtimePrivilege) in the Windows token that the MCP server uses.
WSL runs Windows tools under your Windows login token, so whether the call succeeds without prompting depends on that token — not on adding admin anywhere.
Check your token from WSL (use the full path — the bare whoami.exe is shadowed by the GNU whoami in some WSL setups and silently ignores /priv):
[/mnt/c/Windows/System32/whoami.exe /priv | grep -i systemtime](/mnt/c/Windows/System32/whoami.exe /priv | grep -i systemtime)
/mnt/c/Windows/System32/whoami.exe /priv | grep -i systemtime
<Error: File '/mnt/c/Windows/System32/whoami.exe /priv | grep -i systemtime' not found on disk>If you see SeSystemtimePrivilege … Enabled and High Mandatory Level, the clock change runs promptless — no admin changes needed. The tool calls Set-Date directly.
If the privilege is absent or integrity is Medium, the tool will fail with a "shift to '<time>' failed (host may lack 'Change the system time' privilege)" error. To fix:
Grant the user right:
secpol.msc → Local Policies → User Rights Assignment → Change the system time → Add <your account>. (Add the account itself, not justAdministrators— the right is stripped from a filtered Medium token.)Re-login so the new privilege appears in your token:
wsl --shutdown, then reconnect your SSH session.Re-verify:
/mnt/c/Windows/System32/whoami.exe /priv | grep -i systemtimeshould now listSeSystemtimePrivilege … Enabled.
start_nina(time=...) also performs deterministic restore: it captures the real host clock before the shift (real0) and restores to real0 + elapsed after NINA captures the simulated time. No w32tm /resync or NTP source is required.
Available Tools
14 toolsget_eventsA
Returns recent timestamped NINA observatory events and their event-specific details from the last since seconds. Use it to reconstruct sequence, equipment, safety, imaging, and error activity. This tool is read-only; use get_site_equipment_status and sequence_get_state for current status.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No |
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. It explicitly states 'This tool is read-only', which is a critical behavioral trait. It also implies a time-window behavior via 'since' seconds. However, it does not disclose details like ordering, pagination, or limits on returned events, which would be useful for a tool that fetches historical data. Given the read-only nature, this is a minor gap, so a 4 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with zero redundancy. It front-loads the primary purpose and then gives usage guidance. Every sentence earns its place, and it is easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only getter with one parameter and no output schema, the description covers the essential information: what it returns, when to use it, and that it is safe. It could mention whether events are sorted or if there are any maximum limits, but these are not critical for a tool of this simplicity. The mention of alternatives is a strong plus.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one parameter `since` with 0% description coverage. The description fully explains its meaning: 'from the last `since` seconds'. This adds clear semantic meaning beyond the type and default, making it easy for an agent to know what value to supply.
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: 'Returns recent timestamped NINA observatory events and their event-specific details'. It also clarifies the scope (time window) and differentiates from siblings by naming them ('use get_site_equipment_status and sequence_get_state for current status'). This leaves no ambiguity about what the tool does and how it differs.
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 tells when to use the tool ('reconstruct sequence, equipment, safety, imaging, and error activity') and when not to, with named alternatives for current status. The guidance is actionable and covers both inclusion and exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_imaging_metadataA
Returns imaging metadata parsed from the ImageMetaData.csv files in the frame folders (LIGHT, DARK, BIAS, FLAT, etc.) of the mounted N.I.N.A imaging directory. Each row is tagged with Date, FrameType, and Source. When an AcquisitionDetails.csv is present in the same session directory, its fields (e.g. TargetName, FocalLength) are injected into each image row unless the image row already has a value for that field. Defaults to lights frames for star-quality checks; pass another image type (light, dark, bias, flat — case-insensitive). Optionally filter to a single YYYY-MM-DD date.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | ||
| image_type | No | light |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the merging behavior (injecting AcquisitionDetails.csv fields unless already present), the default image type, and case-insensitivity. It does not explicitly state read-only safety, but the verb 'Returns' implies it, and it adds valuable behavioral context about the data transformation.
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 a multi-sentence paragraph but every sentence carries useful information: source, tagging, injection rule, defaults, and filter. It is front-loaded with the main purpose and does not waste words, though it could be slightly more compact without losing substance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read tool with a documented output schema, the description covers the essential behaviors: source location, row tagging, field injection, default frame type, and date filter. It does not mention error cases or what happens if the directory is missing, but those are minor given the output schema and the tool's read-only nature.
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. It explains both parameters: image_type with allowed examples and case-insensitivity, and date with a specific YYYY-MM-DD format. This adds meaning well beyond the bare schema and provides concrete guidance for values and format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Returns' and the resource 'imaging metadata parsed from the ImageMetaData.csv files', and specifies the source directory and file type. It also distinguishes itself from siblings (which are about site status, sequences, logs) by being the only tool focused on imaging metadata extraction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: it defaults to lights frames for star-quality checks and allows passing other image types, and optionally filtering by date. However, it does not explicitly name alternative tools or state when not to use it, so it lacks explicit exclusions but provides enough situational context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_logsA
Returns recent NINA application log entries, including informational messages, warnings, and errors with source and timestamp details from the last since seconds. Use it to diagnose sequence failures, equipment communication problems, and unexpected behavior. This tool is read-only and takes no action.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No |
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. It explicitly states the tool is read-only and takes no action, which is important behavioral disclosure. It also describes the content of the returned entries, covering the key behavioral traits 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?
The description is three crisp sentences: what it returns, when to use it, and its safety profile. It is front-loaded with the core behavior and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one optional parameter and no output schema, the description adequately covers return content, use cases, and non-mutating behavior. It could specify output limits or ordering, but nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description compensates by explaining that logs come from 'the last `since` seconds', giving clear meaning to the only parameter. It does not state the default value, but that is already present in the 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?
The description clearly states the tool returns recent NINA application log entries with source and timestamp details, which is a specific verb and resource. It does not explicitly differentiate from get_events, but the resource is specific enough to avoid most ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description names concrete diagnostic use cases: sequence failures, equipment communication problems, and unexpected behavior. It gives clear context for when to use the tool, though it does not mention alternatives or exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
_get_site_equipment_statusD
| Name | Required | Description | Default |
|---|---|---|---|
| profile | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| dome | No | |
| mount | No | |
| camera | No | |
| guider | No | |
| focuser | No | |
| rotator | No | |
| weather | No | |
| filter_wheel | No | |
| safety_monitor | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Tool has no description.
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?
Tool has no description.
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?
Tool has no description.
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?
Tool has no description.
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?
Tool has no description.
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?
Tool has no description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_site_equipment_statusA
Returns the current connection, operating state, measurements, and capabilities of active observatory equipment, including weather and safety-monitor status (whether the enclosure is open and it is safe to unpark), and mount capabilities (can_park, can_find_home) that determine how the scope can be stowed. Use it for live operational and safety checks. This tool is read-only and takes no action.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| dome | No | |
| mount | No | |
| camera | No | |
| guider | No | |
| focuser | No | |
| rotator | No | |
| weather | No | |
| filter_wheel | No | |
| safety_monitor | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that it is read-only and takes no action, which is a key behavioral trait. Since no annotations are provided, the description carries the full burden, and it adequately covers the safety and side-effect profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no redundancy. It front-loads the primary function, then adds usage and behavioral notes, each earning 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?
The tool has an output schema, so return values are defined there. The description explains the purpose, usage, and behavioral constraints, and mentions specific capabilities like can_park and can_find_home, making it complete for an agent to decide when to call it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema already covers everything. The description adds no parameter-specific information, but with 0 parameters, the baseline of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns current connection, operating state, measurements, and capabilities of observatory equipment, with specific examples like weather, safety-monitor status, and mount capabilities. This distinguishes it from siblings like get_site_profile and get_events by focusing on live status.
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 'Use it for live operational and safety checks,' providing clear context for when to invoke it. However, it does not mention alternatives or when not to use it, so it lacks explicit exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_site_profileA
Returns the active NINA observatory profile and static configuration, including site location, optics, camera geometry, filters, plate solvers, and image-save path. Use get_site_equipment for live equipment state. This tool is read-only and takes no action.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| site | Yes | |
| optics | Yes | |
| filters | Yes | |
| equipment | Yes | |
| profile_id | Yes | |
| description | No | |
| file_pattern | No | |
| plate_solver | No | |
| profile_name | Yes | |
| image_save_path | Yes | |
| blind_plate_solver | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly states the tool is read-only and takes no action, which is valuable behavioral disclosure. Since no annotations are provided, the description carries the full burden, and it does so by clarifying the non-mutating nature and that it returns static configuration rather than live state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no wasted words. The first sentence front-loads the tool's purpose and content, and the second sentence provides the sibling distinction and safety profile. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a zero-parameter read-only tool. It names the sibling for live state, lists the content returned, and states the read-only nature. The output schema exists, so return values need not be described in prose. Minor gap: it doesn't mention whether the profile is cached or freshly fetched, but this is not essential for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema is trivially complete. The description adds context about what the returned profile contains, which is more useful than parameter documentation in this case. Baseline 4 for zero-parameter tools is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns the active NINA observatory profile and static configuration, listing specific content areas (site location, optics, camera geometry, filters, plate solvers, image-save path). It also distinguishes itself from the sibling get_site_equipment_status by noting that tool is for live equipment state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly names the alternative get_site_equipment for live equipment state, providing a clear when-to-use distinction. It doesn't exhaustively enumerate all alternatives or exclusions, but the key sibling differentiation is present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
observation_plan_get_progressA
Returns per-frame-type acquisition progress for an observation-plan JSON file: for each exposure group, the total_count from the plan, the acquired_count attributed to this plan from the imaging metadata (ImageMetaData.csv + AcquisitionDetails.csv), and the remaining_count. Lights are attributed via the plan_id embedded in the sequence target name (falling back to the target name for legacy frames); flats/darks/bias are matched by image type, filter, and exposure. Pass max_hfr and/or min_detected_stars to exclude light frames that fail quality thresholds (frames missing the quality fields are excluded when a threshold is set). Use this before sequence_load_plan to decide what still needs acquiring.
| Name | Required | Description | Default |
|---|---|---|---|
| max_hfr | No | ||
| file_path | Yes | ||
| min_detected_stars | No | ||
| max_guiding_rms_arcsec | 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. It discloses the attribution logic (plan_id embedded in target name, fallback to target name, matching by image type/filter/exposure) and the exclusion behavior for quality thresholds. It implies a read-only operation but does not explicitly state so, nor does it mention potential edge cases like missing files. Still, it is substantially transparent about its behavior.
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 reasonably concise given the complexity, with each sentence adding essential detail. It is front-loaded with the core purpose, then explains attribution, parameters, and usage in a logical order. It avoids redundancy but is slightly long due to necessary technical detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, so return values need not be described. The description covers the input parameters, the logic, and the usage context. It lacks explicit error handling or assumptions about file existence, but for an agent it provides enough to decide when to call and what to expect. It is complete for typical use.
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 explains file_path as the observation-plan JSON file and explains max_hfr and min_detected_stars as quality thresholds. However, it does not mention max_guiding_rms_arcsec at all, leaving that parameter semantically unexplained. This partial coverage warrants a score of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Returns') and resource ('per-frame-type acquisition progress for an observation-plan JSON file') with detailed metrics (total_count, acquired_count, remaining_count). It clearly distinguishes itself from siblings by focusing on progress computation and explicitly routes to sequence_load_plan as the next step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use this before sequence_load_plan to decide what still needs acquiring,' giving a clear when-to-use directive. It also explains when to pass quality thresholds (max_hfr/min_detected_stars) and how they affect results, covering the main use case without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
observation_plan_write_fileA
Validates and writes an observation plan to a JSON file for later use by sequence_load_plan. The plan defines target coordinates, acquisition intent, light and calibration frames, batching, cooling, autofocus, guiding, and observing constraints. This tool only creates the plan file; it does not load or start a sequence.
| Name | Required | Description | Default |
|---|---|---|---|
| plan | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds useful context beyond the schema by stating the tool validates the plan, writes it to a file, and does not load/start a sequence. It also mentions the plan_id is 'stamped on write' indirectly through schema, but the description itself doesn't describe side effects of overwriting an existing file, permission requirements, or return behavior. With no annotations provided, it could still disclose more.
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?
Compact and front-loaded: first sentence covers the action, resource, and key limitation; second sentence reinforces scope. No filler, every clause carries meaning.
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 nested plan object with no schema-level parameter descriptions, the description gives a high-level overview of what the plan should include, plus a critical caveat about not loading the plan. Given there is an output schema, return values are covered. Minor gaps: no mention of file path, overwrite behavior, or validation failure outcomes, but the core agent task is well supported.
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. The description summarizes the plan's contents (target coordinates, acquisition intent, light/calibration frames, batching, cooling, autofocus, guiding, constraints), but it doesn't explain how the single parameter (plan) relates to those fields or that it must be a complete ObservationPlan object. The schema's own field descriptions are sparse, so the description helps but doesn't fully compensate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool's action ('Validates and writes'), the resource ('observation plan to a JSON file'), and its downstream purpose ('for later use by sequence_load_plan'). It explicitly distinguishes this tool from sequence_load_plan and sequence_start, making its scope obvious even 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?
The description implies usage — this is the tool to use when you want to create a plan file but not execute it — and explicitly states it does not load or start a sequence. However, it doesn't explicitly say 'use this when you need to persist a plan before loading it' nor does it contrast when to use observation_plan_get_progress or other siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sequence_enter_safety_standbyA
Loads a non-acquisition standby sequence that keeps NINA sequence-level safety and stow guardrails active while the observatory is idle. After loading, call sequence_start. Stop it before loading an acquisition or teardown sequence. Use whenever equipment is deployed and no other sequence is running.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral disclosure burden. It does well by explaining that this tool only loads a sequence, does not start it, keeps safety guardrails active, and must be stopped before loading other sequences. It does not mention side effects of neglecting the stop step, but the core behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences carry all essential information: what the tool does, what to do next, and when to stop/avoid it. Every sentence earns its place, and the most important context is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters)Skip? Given zero parameters, an output schema, and clear sibling context, the description covers the complete call workflow: load, start, stop before replacing, and the operational condition for using it. Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and schema coverage is 100%, so the schema already exhaustively documents the inputs. Per the rubric, 0 parameters earns a baseline of 4; the description adds no unnecessary parameter detail and needs none.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Loads'), a specific resource ('non-acquisition standby sequence'), and the purpose ('keeps NINA sequence-level safety and stow guardrails active while the observatory is idle'). This clearly distinguishes it from sibling tools that load or execute acquisition or teardown sequences.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit operational guidance: call sequence_start after loading, stop it before loading an acquisition or teardown sequence, and use it whenever equipment is deployed with no other sequence running. This fully orients an agent on when and how to invoke the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sequence_execute_teardownA
Loads and starts the non-acquisition teardown sequence, safely stowing the telescope (park or home, per mount capability) while NINA's sequence-level safety guardrails remain active. Use for end-of-observation close-down — when you are done observing and want to shut down the scope — or before leaving the observatory unattended. Allow it to complete without interruption. This is separate from sequence_stop, which halts the current sequence but does not stow the scope.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the stowing behavior, the park/home variation, the retained safety guardrails, and that interruption should be avoided. It does not mention failure modes or prerequisites such as mount connectivity, but the core operational behavior is well covered, which is strong for a zero-parameter 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?
Each sentence adds distinct value: action, usage, caution, and sibling distinction. There is no redundant content; the description is tightly structured and easy to parse, with the main verb and resource front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with an output schema, this description covers purpose, usage, and operational cautions. It does not need to describe return values since an output schema exists, and nothing necessary for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema already documents this with 100% coverage, so baseline 4 applies. The description adds no parameter-specific meaning, but none is needed since there is nothing 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?
The description states a specific action ('Loads and starts the non-acquisition teardown sequence') and the resource (telescope stow), and explicitly distinguishes from sequence_stop. This clearly separates it from all sibling tools without needing to inspect schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells when to use: 'when you are done observing and want to shut down the scope' or 'before leaving the observatory unattended,' and clarifies that sequence_stop does not stow. It also gives the operational instruction to 'Allow it to complete without interruption,' leaving no ambiguity about when to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sequence_get_stateA
Returns the loaded sequence structure and the current status of its containers, instructions, conditions, and triggers. Use it to determine whether a sequence is loaded, running, completed, failed, or waiting. This tool is read-only and takes no action.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description itself discloses that the tool is read-only and takes no action. This is important behavioral context for an agent deciding whether to invoke it. It also conveys what kind of information will be returned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short sentences with no filler. It front-loads the core purpose, then adds usage context, then the critical read-only behavior. Every sentence contributes value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read-only inspection tool, the description covers what it returns, what it can be used to determine, and that it has no side effects. It does not mention error cases or prerequisites, but the tool is simple enough that this is not a major 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?
The tool has zero parameters and the schema is empty, so there is nothing for the description to add about parameter meaning. The baseline of 4 applies because no parameter documentation burden exists.
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 ('Returns') and names the exact resource: the loaded sequence structure and the status of its containers, instructions, conditions, and triggers. This clearly distinguishes the tool from mutation siblings like sequence_start, sequence_stop, and sequence_load_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?
The description explicitly tells the agent when to use this tool: to determine whether a sequence is loaded, running, completed, failed, or waiting. It does not name exclusions or alternative tools, but the intended context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sequence_load_planA
Loads an acquisition sequence with safety guardrails from an observation-plan JSON file. Select the frame type: light, dark, bias, dawn_flat, or dusk_flat. In the default remaining mode the sequence only acquires frames still needed (total minus frames already attributed to this plan in the imaging metadata); if nothing remains it reports the plan as complete and loads nothing. max_hfr and/or min_detected_stars exclude light frames failing quality thresholds from the acquired count. Pass mode="full" to acquire the entire plan again. This tool only loads the sequence; call sequence_start afterward.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | remaining | |
| max_hfr | No | ||
| file_path | Yes | ||
| frame_type | No | light | |
| min_detected_stars | No | ||
| max_guiding_rms_arcsec | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden, and it does so well: it states side-effect limitations ('loads nothing' when complete), mode-dependent behavior, and the effect of quality thresholds. It doesn't fully describe every edge case or the behavior of max_guiding_rms_arcsec, but it is substantially transparent for an unannotated 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?
The description is six sentences of dense, non-redundant information. It front-loads the core purpose and guardrails, then explains modes and quality filters, and ends with the essential follow-up instruction. Every sentence adds value.
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 purpose, modes, frame types, quality filters, and the load-versus-start distinction, and an output schema exists to cover return values. It misses explicit meaning for `max_guiding_rms_arcsec` and does not mention prerequisites or error conditions, but overall it is largely complete for a 6-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains `mode` (remaining/full), enumerates all `frame_type` choices, and clarifies `max_hfr` and `min_detected_stars` effects. However, it omits any meaning for `max_guiding_rms_arcsec`, which is a small but notable gap given the 0% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action and resource: 'Loads an acquisition sequence with safety guardrails from an observation-plan JSON file.' It also differentiates itself from the sibling sequence_start by explicitly stating 'This tool only loads the sequence; call sequence_start afterward,' so an agent can separate loading from starting.
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 usage context: the default `remaining` mode acquires only needed frames, `mode="full"` reacquires the entire plan, and quality thresholds affect light-frame counting. It also provides a clear boundary and follow-up instruction: 'This tool only loads the sequence; call sequence_start afterward,' which routes the agent to the correct next step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sequence_startA
Starts or resumes the currently loaded sequence, activating its acquisition or safety workflow. Call sequence_get_state afterward to verify that it is running.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral disclosure burden. It discloses that the tool activates an acquisition or safety workflow and that the sequence may not be immediately confirmed as running, since the agent is told to call sequence_get_state afterward. It stops short of describing error behavior or idempotency, but for a zero-parameter command tool this is meaningful disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The primary action and its effect are front-loaded, and the follow-up verification instruction is a single useful addition. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter lifecycle tool with an output schema available, the description is complete: it states the action, the resource, the effect, and the immediate next step. The 'currently loaded sequence' phrasing implies the load prerequisite, and no additional context is needed 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?
The tool has zero parameters and the schema coverage is 100%, so there are no parameter semantics to clarify. The baseline for a no-parameter tool is 4, and the description appropriately focuses on behavior rather than arguments.
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 ('Starts or resumes') and a clear resource ('currently loaded sequence'), and says what it activates ('acquisition or safety workflow'). It also names the sibling sequence_get_state, which helps differentiate this tool from state-checking and lifecycle tools like sequence_stop and sequence_load_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?
The description gives clear procedural context: use this to start/resume a loaded sequence, then verify with sequence_get_state. It does not explicitly list exclusions or when to prefer a sibling, but the loaded-sequence qualifier implies a prerequisite and the named follow-up tool gives enough orientation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sequence_stopA
Stops the currently running NINA sequence immediately, leaving the telescope where it currently is — it does not stow the scope. Use for an urgent halt, to interrupt a stuck/looping sequence, or when the running sequence isn't what you wanted. If you then want to park/home the telescope, run sequence_execute_teardown separately. Note that sequence_load_plan and the teardown/standby entry tools already stop any running sequence before loading, so an explicit stop is only needed when you want to halt without loading anything new. Avoid stopping an in-progress teardown during the stow maneuver unless safety requires it, since interrupting mid-slew can leave the scope in an unsafe position. Call sequence_get_state afterward to confirm the sequence has stopped.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 of behavioral disclosure. It clearly conveys side effects: immediate stop, telescope left in place, no stowing, and the potential unsafe position from interrupting a mid-slew teardown. It also advises confirmation via sequence_get_state. This fully covers the relevant behavior.
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 longer than a simple one-liner, but every sentence earns its place: primary behavior first, then use cases, exclusions, a safety warning, and a verification step. The structure is logical and front-loaded with the most critical information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, safety-relevant control tool, the description covers all key operational context: what happens, when to call it, when not to call it, what to do instead, and how to verify the outcome. An output schema exists, so the description need not detail return values. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters and the schema is empty, so there is no parameter semantics to document. The 0-parameter baseline of 4 applies; the description appropriately does not invent unnecessary 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: 'Stops the currently running NINA sequence immediately.' It clarifies the scope by explicitly noting the scope is not stowed and by distinguishing itself from sequence_execute_teardown, making sibling differentiation clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use scenarios (urgent halt, stuck/looping sequence, unwanted sequence) and when not to use it (before the teardown/standby entry tools, during an in-progress teardown unless safety requires). It also names the alternative sequence_execute_teardown for parking/homing and the follow-up sequence_get_state. This is exemplary routing guidance.
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.
14 tool updates
v0.1.0- First observed
_get_site_equipment_status - First observed
get_events - First observed
get_imaging_metadata - First observed
get_logs - First observed
get_site_equipment_status - First observed
get_site_profile - First observed
observation_plan_get_progress - First observed
observation_plan_write_file - First observed
sequence_enter_safety_standby - First observed
sequence_execute_teardown - First observed
sequence_get_state - First observed
sequence_load_plan - First observed
sequence_start - First observed
sequence_stop
TDQS
Scored across 14 tools
Most tools are clearly separated by domain: status, profile, events, logs, imaging metadata, plan progress, and sequence control are all distinct. The duplicate `_get_site_equipment_status` tool with no description creates real ambiguity, but it is the only significant overlap.
Tool names follow predictable snake_case patterns such as `get_*`, `sequence_*`, and `observation_plan_*`. The leading-underscore duplicate `_get_site_equipment_status` breaks the convention and should be removed, but the rest of the naming is consistent.
Fourteen tools is within a reasonable range for an observatory planning and operations server, and each major area has dedicated coverage. The duplicate tool slightly inflates the count, but the real scope is well-sized.
The set covers the full observation workflow: diagnostics, plan creation, progress tracking, sequence loading/starting/stopping, teardown, and safety standby. Minor gaps like plan-file inspection/editing or pause/resume commands are workaroundable, but no severe dead ends exist.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
- FensoryOAuthcom.fensory
Trading MCP server for AI agents, with live market data, account reads and controlled execution.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceA protocol server enabling AI agents to control astrophotography equipment through the N.I.N.A. (Nighttime Imaging 'N' Astronomy) software, allowing for natural language command processing of cameras, mounts, focusers, and other astronomy equipment.12MIT
- AlicenseBqualityCmaintenanceAn MCP server that enables LLMs to query data from various NASA APIs, allowing access to astronomical data, space weather information, Earth imagery, and exoplanet information directly from compatible AI clients.216MIT
- AlicenseBqualityDmaintenanceAn MCP server for controlling astronomy equipment, supporting Dark Dragons Astronomy devices and any ASCOM Alpaca-compatible equipment.439 npmISC
- FlicenseNot gradedqualityDmaintenanceMCP server that wraps three NASA public APIs (Astronomy Picture of the Day, Mars rover photos, and near-Earth objects) as tools for AI assistants.-