Skip to main content
Glama

nina_planner — An Observatory Operator Agent

Banner for repository

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

get_site_equipment_status()

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_site_profile()

Get observatory location (lat/lon/elevation), optics details, filter list, plate solver type, and image save path.

get_events(since)

Get latest observatory event log entries from since seconds.

get_logs(since)

Get latest N.I.N.A. application log entries from since seconds.

get_imaging_metadata(file_path, pointing_index=1, image_type="light")

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 {base_plan_id}-{pointing_index} id embedded in the recorded file path; dark/bias/flat frames are matched by image type/filter/exposure and must fall within the plan's calibration_max_age_days window of today (UTC). Each row carries the frame identity fields (file_path, date, exposure_number, exposure_start, duration, filter_name) plus its metrics as columns, namespaced by group (quality.hfr, guiding.rms, background.adu_mean, pointing.airmass, ...). Timestamps are normalized to milliseconds-precision UTC ISO-8601 with a Z suffix (e.g. 2026-09-22T02:16:25.123Z). Per-exposure weather samples from WeatherData.csv are joined onto the same row (weather.temperature, humidity, cloud_cover, ...) by exposure number and normalized UTC exposure start. Dead columns are dropped dynamically: columns constant across the returned frames are listed once under summary.constants; columns with no real values (ASCOM NaN/-1, empty, n/a, and the 0 sentinel N.I.N.A writes for unmeasured quality/guiding/CCD metrics) are listed under summary.unpopulated. The result also carries the plan's plan_id, pointing_index, and target.

write_plan_file(plan)

Write out an observation plan JSON file.

get_plan_progress(file_path, pointing_index=1, max_hfr?, min_detected_stars?, max_guiding_rms_arcsec?)

Report per-frame-type progress for one pointing: total, acquired (attributed to {base_plan_id}-{pointing_index}), and remaining for each exposure group. Quality thresholds exclude light frames that fail them.

Sequence Management

Tool

Purpose

load_sequence_from_plan(file_path, frame_type, pointing_index=1, mode="remaining", max_hfr?, min_detected_stars?, max_guiding_rms_arcsec?)

Load a plan file as a sequence (light, dark, bias, dawn_flat, or dusk_flat). pointing_index (1-based, default 1) selects which pointing of the plan to load — lights embed {base_plan_id}-{pointing_index} in the NINA target name so each pointing's frames are attributed independently. Default remaining mode acquires only frames not yet attributed to that pointing; mode="full" acquires the whole plan. Quality thresholds exclude light frames that fail them from the acquired count. Reports "pointing complete" and loads nothing when nothing remains.

start_sequence()

Start or resume a stopped sequence.

stop_sequence()

Stop any running sequence.

enter_safety_standby()

Start a non-imaging sequence with safety guardrails.

stow_telescope()

Start a teardown sequence, parking scope.

get_sequence_state()

Return the loaded sequence structure and the current status of its containers, instructions, conditions, and triggers (whether loaded, running, completed, failed, or waiting).

stop_nina()

Terminate the NINA.exe application immediately via taskkill.

start_nina(time=None)

Launch NINA into the active interactive desktop session (GUI visible). With time=None, launches on current real time. With time="YYYY-MM-DDTHH:MM:SS", shifts host clock, launches NINA, and restores real clock so NINA runs on simulated time. Errors if NINA is already running (call stop_nina() first).

get_nina_time()

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 five frame types, and equipment configuration (cooler, autofocus, guiding, constraints).

Plan structure

An example json plan:

{
  "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": [
    {
      "filter_name": "LP",
      "exposure_time_seconds": 60.0,
      "total_count": 60
    }
  ],
  "flat": [
    {
      "filter_name": "LP",
      "exposure_time_seconds": 5.0,
      "total_count": 30
    }
  ],
  "dark": [
    {
      "exposure_time_seconds": 60.0,
      "total_count": 20
    }
  ],
  "bias": [
    {
      "total_count": 30
    }
  ]
}

Fields

Field

Required

Description

target

no

Catalog designation, e.g. "M31", "NGC 7000"

intent

no

2-3 words describing the goal

plan_id

no

Stable identifier stamped on write. Used for frame attribution; when absent, a deterministic hash of plan content is used.

description

no

explanation of the observation plan, including rationale, exposure goals, equipment, or sky constraints

pointings

yes

One or more target pointings. Each is a Pointing object: label (optional string shown in the NINA target name when set), ra_hours (J2000 RA in hours, [0, 24)), dec_deg (J2000 dec in degrees, [-90, +90]), and position_angle_deg (optional rotator PA in degrees east of north, [0, 360); omitted forwards 0 to NINA). A pointing is selected at run time via pointing_index on load_sequence_from_plan/get_plan_progress/get_imaging_metadata.

batch_size

no

Exposures per batch (0 = no batching, default 5)

cooler

no

Target setpoint (default -10°C)

constraints

no

Minimum altitude and horizon safety buffer

autofocus

no

Reference filter, HFR and temperature thresholds, interval

guiding

no

Dither and drift-recenter settings

light

yes

Light exposure groups (filter + time + count)

flat

yes

Flat exposure groups (filter + time + count)

dark

yes

Dark exposure groups (time + count) — match light exposure times

bias

yes

Bias frame count (single exposure, no filter needed)


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_from_plan builds the appropriate container (lights, darks, flats, or bias), and posts it to N.I.N.A.

Example order:

  1. Load lights (main imaging overnight): load_sequence_from_plan(file_path="<plan>.json", frame_type="light") start_sequence() (runs all night; autofocus and guiding triggers are built in)

  2. Load darks (done during the day or while flats are not possible): load_sequence_from_plan(file_path="<plan>.json", frame_type="dark") start_sequence() (wait for completion)

  3. Load bias (also done during the day): load_sequence_from_plan(file_path="<plan>.json", frame_type="bias") start_sequence() (wait for completion)

  4. Load dawn flats (morning twilight): load_sequence_from_plan(file_path="<plan>.json", frame_type="dawn_flat") start_sequence() (wait for completion)

  5. Load dusk flats (as evening twilight begins): load_sequence_from_plan(file_path="<plan>.json", frame_type="dusk_flat") start_sequence() (wait for completion)

3. Teardown

At session end:

  • The running sequence should teardown automatically at dawn.

  • stow_telescope — only needed if want to immediately close for the night or the running sequence fails to park.


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 Powerups, and Session Metadata.

  • Image file pattern: in the N.I.N.A. profile's ImageFileSettings, the first two top-level path segments of FilePattern must be $$DATEMINUS12$$ followed by $$IMAGETYPE$$ (e.g. $$DATEMINUS12$$\$$IMAGETYPE$$\...). get_imaging_metadata and frame attribution rely on this layout to locate each frame type's folder.

  • Filter validation: write_plan_file and load_sequence_from_plan check 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$$ in FilePattern to 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_path in ImageMetaData.csv); if the target name is not embedded in the filename or a folder name, it cannot determine which plan/pointing a light frame belongs to. The sequence also records the target in TargetName in AcquisitionDetails.csv and as OBJECT in FITS headers, but those are informational — file-path attribution is what drives get_plan_progress and mode="remaining".

  • Resuming a pointing: call get_plan_progress(file_path, pointing_index=N, ...) to see what a particular pointing has already acquired, then load_sequence_from_plan(..., 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 must fall within the plan's calibration_max_age_days (default 7) window of today (UTC), so stale calibration frames are not counted as acquired and get re-shot. Pass mode="full" to deliberately re-acquire.

  • Quality thresholds: max_hfr and min_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 next mode="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 v1 Autonomous Plugin

nina-plugin.ts is an opencode v1 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:

  1. 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.

  2. 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 — Planning a Night's Session

plan.md is the user's living wishlist for the night — a markdown file at the project root that you edit at any time (before or during the night). It is deliberately lightweight: entries can be as simple as a target name. The worker agent reads it fresh on each trigger to decide which target to image next, so no write_plan_file call is needed up front.

Structure

  1. Metadata — night date, overall intent (optional).

  2. 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

  3. Selection rules — how the worker picks among candidates:

    • min_altitude floor (default e.g. 30°)

    • horizon_offset_degrees safety buffer (default 2°)

    • tie-break order (priority, then highest current altitude, then earliest available)

Example

# Tonight

- 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 altitude

How 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 from plan.md, or sensible defaults), then load_sequence_from_plan(frame_type="light") and start_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. Editing plan.md later triggers re-evaluation.

  • You can add/remove/reorder lines at any moment. The worker records completion in progress.md instead and leaves plan.md untouched, 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 v1 Sample Configuration

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [ 
    [ "./nina-plugin.ts", 
      { 
        // "ninaEndpoint": "192.168.0.24:1888", // defaults to 127.0.0.1:1888
        "pluginLogs": "/tmp/nina-plugin-debug.log",
        "intervalCheck": 0  // 0 disables interval check, defaults to every 10 minutes
      } 
    ]
  ],
  "mcp": {
    "nina-planner": {
      "type": "local",
      "environment": {
        // "NINA_ENDPOINT": "192.168.0.24:1888", // defaults to 127.0.0.1:1888
	// "NINA_DRIVE_MOUNT": "/System/Volumes/Data/Network", // defaults to /mnt/<drive>
        "NINA_PLANNER_LOG": "/tmp/nina-planner-debug.log"
      },
      "command": [ // don't use bash -c, hard for opencode to kill and restart
        "python",
       	"-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_from_plan, get_site_equipment_status, etc.) that the plugin-prompted agent calls.


Plugin Options

nina-plugin.ts (opencode v1 plugin)

Configured under opencode.json > plugin as the second array element (see opencode.json).

Option

Type

Default

Description

ninaEndpoint

string

127.0.0.1:1888

N.I.N.A. host and port (no scheme) for the websocket event stream, e.g. 192.168.0.24:1888. The plugin connects to ws://<ninaEndpoint>/v2/socket.

intervalCheck

number

10

Minutes between autonomous status-check triggers of the worker agent. Accepts a float; the value is multiplied by 60_000 ms before scheduling.

pluginLogs

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. /tmp/nina-plugins.log) to capture diagnostic output. Omit or leave empty to disable file logging.

agentHistory

string

(none)

File path that receives an append-only JSON-lines record of every worker session the plugin spawns. Each line is { timestamp, sessionId, agent, messages }. Omit or leave empty to skip history capture.


Environment Variables

nina_planner (MCP server)

Variable

Default

Description

NINA_ENDPOINT

127.0.0.1:1888

N.I.N.A. host and port for the REST API (host:port). For WSL, try 192.168.0.24:1888

NINA_DRIVE_MOUNT

—

Local mount root for the drive letter in the profile's image_save_path, used by get_imaging_metadata to resolve the imaging directory on Linux and WSL (e.g. /mnt on a Mac with C: mounted there, /mnt/c in WSL). Defaults to /mnt/<drive> (e.g. /mnt/c). On Windows (win32) the profile image_save_path is used directly.

NINA_FLATS_ALTITUDE

80

Altitude in degrees for flat panel calibration frames

NINA_FLATS_AZIMUTH_DAWN

270

Azimuth in degrees pointing west for dawn flats

NINA_FLATS_AZIMUTH_DUSK

90

Azimuth in degrees pointing east for dusk flats

NINA_EXE_PATH

C:\Program Files\N.I.N.A. - Nighttime Imaging 'N' Astronomy\NINA.exe

Windows path to NINA.exe used by start_nina to launch NINA.

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=mirrored

Then shutdown wsl and restart

$ wsl --shutdown
$ wsl

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-user

Elevation & 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 /groups | grep -i "Integrity"

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:

  1. Grant the user right: secpol.msc → Local Policies → User Rights Assignment → Change the system time → Add <your account>. (Add the account itself, not just Administrators — the right is stripped from a filtered Medium token.)

  2. Re-login so the new privilege appears in your token: wsl --shutdown, then reconnect your SSH session.

  3. Re-verify: /mnt/c/Windows/System32/whoami.exe /priv | grep -i systemtime should now list SeSystemtimePrivilege … 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 tools
get_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceNo

TDQS

A4.7/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It 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.

Conciseness5/5

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.

Completeness4/5

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

For a simple read-only 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.

Parameters5/5

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.

Purpose5/5

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

The description states a specific verb and resource: '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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNo
image_typeNolight

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden. 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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceNo

TDQS

A4.1/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It 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.

Conciseness5/5

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.

Completeness4/5

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

For a simple read-only 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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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
ParametersJSON Schema
NameRequiredDescriptionDefault
profileYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
domeNo
mountNo
cameraNo
guiderNo
focuserNo
rotatorNo
weatherNo
filter_wheelNo
safety_monitorNo

TDQS

D1/5.0
Behavior1/5

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.

Conciseness1/5

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.

Completeness1/5

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.

Parameters1/5

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.

Purpose1/5

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.

Usage Guidelines1/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
domeNo
mountNo
cameraNo
guiderNo
focuserNo
rotatorNo
weatherNo
filter_wheelNo
safety_monitorNo

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
siteYes
opticsYes
filtersYes
equipmentYes
profile_idYes
descriptionNo
file_patternNo
plate_solverNo
profile_nameYes
image_save_pathYes
blind_plate_solverNo

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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

The description is complete for a 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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
max_hfrNo
file_pathYes
min_detected_starsNo
max_guiding_rms_arcsecNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the 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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
planYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

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

No annotations are provided, so the description carries the 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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations provided, the description 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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNoremaining
max_hfrNo
file_pathYes
frame_typeNolight
min_detected_starsNo
max_guiding_rms_arcsecNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral disclosure burden, 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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations provided, the description carries the 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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full 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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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

The description states a specific verb and resource: '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.

Usage Guidelines5/5

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.

  1. 14 tool updatesv0.1.0
    • First observed_get_site_equipment_status
    • First observedget_events
    • First observedget_imaging_metadata
    • First observedget_logs
    • First observedget_site_equipment_status
    • First observedget_site_profile
    • First observedobservation_plan_get_progress
    • First observedobservation_plan_write_file
    • First observedsequence_enter_safety_standby
    • First observedsequence_execute_teardown
    • First observedsequence_get_state
    • First observedsequence_load_plan
    • First observedsequence_start
    • First observedsequence_stop

TDQS

B3.2/5.0

Scored across 14 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count4/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    A 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.
    12
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    An 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.
    21
    6
    MIT