nina_planner
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 plans but in json, which then can be loaded and run as 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. |
| Get latest observatory event log entries from |
| Get latest N.I.N.A. application log entries from |
| Write out an observation plan JSON file. |
Hardware
Tool | Purpose |
| Force the telescope to home. |
Sequence Management
Tool | Purpose |
| Load a plan file as a sequence (lights, darks, bias, dawn_flats, or dusk_flats). |
| Start or resume a stopped sequence. |
| Stop any running sequence. |
| Start a non-imaging sequence with safety guardrails. |
| Start a teardown sequence, parking scope. |
| Return the loaded sequence structure and the current status of its containers, instructions, conditions, and triggers (whether loaded, running, completed, failed, or waiting). |
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
{
"target": "Veil Nebula",
"intent": "Widefield supernova remnant",
"description": "Veil Nebula complex centered between Western NGC 6960 and Eastern NGC 6992",
"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
},
"lights": [
{ "filter_name": "LP", "exposure_time_seconds": 60.0, "total_count": 60 }
],
"flats": [
{ "filter_name": "LP", "exposure_time_seconds": 5.0, "total_count": 30 }
],
"darks": [
{ "exposure_time_seconds": 60.0, "total_count": 20 }
],
"bias": [
{ "total_count": 30 }
]
}Fields
Field | Required | Description |
| no | Catalog designation, e.g. "M31", "NGC 7000" |
| no | 2-3 words describing the goal |
| no | explanation of the observation plan, including rationale, exposure goals, equipment, or sky constraints |
| yes | J2000 right ascension in hours |
| yes | J2000 declination in degrees |
| no | Exposures per batch (0 = no batching, default 5) |
| no | Target setpoint (default -10°C) |
| no | Minimum altitude and horizon safety buffer |
| no | Reference filter, HFR and temperature thresholds, interval |
| no | Dither and drift-recenter settings |
| yes | Light exposure groups (filter + time + count) |
| yes | Flat exposure groups (filter + time + count) |
| yes | Dark exposure groups (time + count) — match light exposure times |
| yes | Bias frame count (single exposure, no filter needed) |
Workflow: A Complete Imaging Run
1. Write the plan
Use observation_plan_write_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 sequence_load_plan stops any running sequence, builds the appropriate container (lights, darks, flats, or bias), and posts it to N.I.N.A.
Example order:
Load lights (main imaging overnight):
sequence_load_plan(file_path="<plan>.json", frame_type="lights")sequence_start()(runs all night; autofocus and guiding triggers are built in)Load darks (done during the day or while flats are not possible):
sequence_load_plan(file_path="<plan>.json", frame_type="darks")sequence_start()(wait for completion)Load bias (also done during the day):
sequence_load_plan(file_path="<plan>.json", frame_type="bias")sequence_start()(wait for completion)Load dawn flats (morning twilight):
sequence_load_plan(file_path="<plan>.json", frame_type="dawn_flats")sequence_start()(wait for completion)Load dusk flats (as evening twilight begins):
sequence_load_plan(file_path="<plan>.json", frame_type="dusk_flats")sequence_start()(wait for completion)
3. Teardown
At session end:
The running sequence should teardown automatically at dawn.
sequence_execute_teardown— only needed if want to immediately close for the night or the running sequence fails to park.
Notes
Filter validation:
observation_plan_write_fileandsequence_load_plancheck 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.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 Autonomous Plugin
nina-plugin.ts is an opencode 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 (sequence_get_state,get_site_equipment_status) and decide what to do next, even when no N.I.N.A. events are firing.
The plugin uses two different active opencode "agents", if they are configured, otherwise it uses the main session model. One agent is called event for responding to incoming N.I.N.A. events over websocket and and the other is check for responding to the interval check.
The plugin auto-reconnects on websocket disconnection with a 5-second retry. On server dispose, it cleans up all timers and the socket.
opencode.json — Sample Configuration
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"./nina-plugin.ts"
],
"mcp": {
"nina_planner": {
"type": "local",
"command": [
"bash",
"-c",
"python -m nina_planner 2>> /tmp/opencode_nina_planner.log"
]
}
}
}Registers the opencode plugin and the nina_planner MCP server so both run together. The MCP server provides the tools (sequence_load_plan, get_site_equipment_status, etc.) that the plugin-prompted agent calls.
Environment Variables
nina-plugin.ts (opencode plugin)
Variable | Default | Description |
|
| N.I.N.A. host and port for the websocket event stream |
|
| Interval between autonomous status checks (float) |
nina_planner (MCP server)
Variable | Default | Description |
|
| N.I.N.A. host and port for the REST API ( |
|
| Altitude in degrees for flat panel calibration frames |
|
| Azimuth in degrees pointing west for dawn flats |
|
| Azimuth in degrees pointing east for dusk flats |
This server cannot be deployed
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.
MCP server that lets AI assistants use all OneSchema features exposed via the public API.
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.4310 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.-