# Kshana PNT-resilience simulator [Health: Active]

**Category:** 🚀 Aerospace & Astrodynamics  
**Repository:** https://github.com/AshfordeOU/kshana  
**GitHub Stars:** 8  
**npm Downloads (last month):** 1262  
**Views:** 1  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/kshana-pnt-resilience-simulator

## Description
Run the validated Kshana PNT-resilience simulator (orbits, frames, GNSS, fusion) from an AI agent.

## Tools
Capabilities this server exposes over MCP:

- **animate_scenario** — Run a Kshana scenario and return its time series as an animation. `format` is `svg` (default: one animated SVG, no script), `html` (one self-contained player page) or `frames` (numbered static SVG frames plus `manifest.json`, at most 120 frames in a reply). Optional `fps` (1 to 60, default 12), `duration_s` (0.5 to 600, default 8) and `width` (480 to 3840 pixels, default 960). The first content item is a JSON summary of what was drawn: the time range and unit, the chart titles, the number of phases and events, whether a spectrum waterfall is present, the result paths the traces were read from, any series left out, and the file names. The files follow, one content item each, in the order the summary's `files` lists them. A kind whose result has no sampled time axis is refused with a message that says so. The animation is MODELLED presentation of the run's own numbers; the same scenario and options give byte-identical files.
- **assess_receiver_log** — Assess a real GNSS receiver log for trust: read a u-blox UBX, RINEX 3 (optionally with broadcast navigation, which adds the engine's own fix, RAIM and a clock-aided monitor), Android GnssLogger or NMEA log, run the trust monitors (carrier-to-noise density drop, AGC, jamming indicator, loss of lock, position jump, RAIM, clock) against a calibration baseline, and return when and why the receiver stopped being trustworthy. Optional `[[events]]` with onsets and predicted C/N0 drops are scored against tolerances stated in the scenario: detected, late or missed, and agree or disagree. Returns the summary and the full result JSON (chart and CSV on request; a vessel run's CSV begins with a `#` comment line carrying the advisory statement, which CSV readers skip with their comment option). The log's bytes go inline in the TOML as `text` or `base64` (inline only, at most 4 MiB). A `[platform] kind = "vessel"` table selects the maritime monitors (kinematic consistency, heading against course, speed log, antenna height, C/N0 spread, time consistency) and adds a 0-100 trust score per epoch with the monitors that deducted. Every epoch also carries its satellite `geometry` (good; degraded for few satellites or high PDOP or HDOP; or unknown where the log has no satellite elevations or DOP); every epoch has a `label` (good, fair, poor); for a vessel a `geometry` monitor joins the score, deducting only when the geometry is poor (at most 15 points: degraded, never untrusted), and every deduction carries a class: geometry (the sky), environment or inconsistency (attack-like). For a stream excerpt with the gate use `assess_vessel_stream`. Advisory only; evidence tier MODELLED.
- **assess_vessel_log** — Assess a vessel's NMEA 0183 log as a batch run (`kshana receiver-trust` with `[platform] kind = "vessel"`): the score model, the monitors that ran and every epoch's 0-100 score with its deductions, its satellite geometry (good, degraded, unknown) with a `label` (good, fair, poor) on every epoch, geometry deducting only when poor, and a class on every deduction (geometry, environment, inconsistency), with `geometry_model` (thresholds, the cap and floor in force, and provenance) and `geometry_summary`. `session_toml` states the vessel's limits and any monitor or score settings (no `[log]` table needed) and `nmea` is the log text, which avoids pasting it inside a TOML string. Input is capped at 4 MiB; the reply carries the document with `epochs` cut to counts by state and at most 200 degraded or untrusted epochs. For a log in another format, or with `[[events]]` to score, use `assess_receiver_log`. Advisory only: not type-approved navigation equipment; the operator remains responsible. Evidence tier: MODELLED.
- **assess_vessel_stream** — Score a bounded excerpt of a vessel's NMEA 0183 stream the way `kshana receiver-trust live` scores it, and return per-epoch trust state (calibrating, nominal, degraded, untrusted) and 0-100 score with the monitors that deducted (live JSON-lines schema 1.3: each epoch carries `position`, an `advisory` statement that the output is advisory, and its satellite `geometry` (good, degraded with reasons such as few-satellites or high-pdop, or unknown when the excerpt has no GSV or GSA) with a `label` (good, fair, poor; geometry deducts only when poor); every deduction carries a `class`: geometry (the sky, not a finding that no attack occurred), environment or inconsistency (attack-like)), the summary (counts by state, geometry and class, lowest and final score, when the first untrusted epoch came) and the last `$PKSHT` sentence. `session_toml` declares the vessel (`[platform] kind = "vessel"`, its speed, acceleration and turn-rate limits, antenna height, whether a heading sensor is on the bus). The excerpt must hold the calibration window; input is capped at 2 MiB and 20,000 epochs, and the reply carries at most 200 degraded or untrusted epoch lines. This is the bounded form of the live command: no socket is opened and nothing is written to a port, and the gate and the telemetry exporters (the long-running process and its `--listen` server) are command-line only. The checks cannot see a spoofer whose fix is consistent with everything on the bus. Advisory only: not type-approved navigation equipment; the operator remains responsible. Evidence tier: MODELLED.
- **attach_evidence_timestamp** — Bind an RFC 3161 timestamp token to an evidence pack (`kshana evidence attach-timestamp`), in memory: `files` is a pack as `create_evidence_pack` returns it, `token_base64` the bytes of the `.tsr` file from a timestamp authority. The token is stored as `timestamp.tsr` beside the signed manifest, not inside it, and the pack with the token must still verify or nothing is attached; an existing token is kept unless `replace` is true. Returns the updated `files` (feed them to `verify_evidence_pack` with `require_timestamp` true to insist the token is present) and the verification notes. This does NOT check the timestamp authority's signature on the token or the authority's certificate (it checks the token's structure and that its message imprint is the hash of this pack's manifest.json): say so, and point the user to `openssl ts -verify`. Input and reply are capped at 4 MiB. A timestamp shows a hash existed at a time the authority states; it is not a legal opinion. Evidence tier: MODELLED.
- **build_interference_map** — Build a GNSS interference map from openly licensed aircraft (ADS-B NIC/NACp) or ship (AIS) position reports given as CSV text (`kshana interference-map adsb|ais`). Returns one GeoJSON document per UTC day (schema kshana-interference-map/v1) (file names `<source>-<dataset>-<date>.geojson`; method version 2) in which each published grid cell is `degraded`, `not_degraded`, `insufficient_sample`, `withheld_day_confounded` or `withheld_no_background` (ADS-B) or `anomalous`/`not_anomalous` (AIS), with the method, its pre-registered thresholds, the dataset licence and attribution embedded. Every per-cell count below the publication minimum (5) is `null` (withheld, never zero), and a day whose background cannot be estimated withholds its calls. Aggregate only: identifiers are hashed in memory and never returned, and a cell with fewer than 5 distinct aircraft or vessels is not published. `dataset` is an approved preset or `custom` (with licence, licence_url, attribution). Input is capped at 4 MiB and the reply at 4 MiB (use a coarser `cell_deg` or the command line for more). Nothing is fetched: land polygons, if wanted for AIS, are passed in. A degraded cell does not identify interference as the cause; an unpublished cell is not evidence of a clear cell; this is not a forecast. Evidence tier: MODELLED.
- **compliance_mapping** — The static public-framework mapping (`kshana compliance-report --mapping` / `--sources`) as Markdown: one table per framework with each row's paraphrased ask, the Kshana outputs that support evidence for it and the gap the outputs do not close; or, with `sources` true, the source documents the tables cite with versions and URLs. Led by the statement every report carries, which stays with any excerpt: a row marked evidenced means a run supports evidence for the capabilities the row names; it is not a finding that a framework is met, and it does not mean any product has been rated or approved by anyone. Needs no runs.
- **compliance_report** — Fill the public-framework mapping from Kshana result documents (`kshana compliance-report`): which rows of six resilience frameworks and standards (the US DHS Resilient PNT framework v2.0, IMO guidance for ships, EASA guidance for aviation, NIS2 Article 21, EN 16803, NIST IR 8323r1) the runs given support evidence for, which they do not, and the gap each row keeps. Pass each run as `label`, `result` (the result JSON text) and, when you have it, `scenario` (the scenario TOML, which names the kind a result does not; a receiver-trust result needs none). At most 64 runs and 4 MiB in all; nothing is read from disk. Each row's `status` is `evidenced`, `partly-evidenced`, `not-evidenced` or `out-of-scope`, and every row keeps its `gap` even when evidenced; inputs that could not be used are listed in `unrecognised` and count for nothing. Show the report's `statement` with any result, verbatim: a status means a run supports evidence for the capabilities the row names; it is not a finding that a framework is met, and it does not mean any product has been rated or approved by anyone. Do not describe the output in any stronger terms. Evidence tier: MODELLED.
- **create_evidence_pack** — Create a signed evidence pack for a window of a vessel's NMEA 0183 log (`kshana receiver-trust evidence`): the raw log bytes for the window, the configuration with every threshold, the per-epoch results and reasons, a self-contained summary page, and a manifest listing every file's SHA-256 with the full log's hash and a hash chain, signed with Ed25519. `from_s`/`to_s` are seconds since the log's first epoch. Returns the files as JSON (feed them to `verify_evidence_pack`), the signer's public key and fingerprint. The signing seed is never returned or logged; if `signing_key_seed_hex` is omitted a one-time key is used and discarded, so the pack proves integrity against the key it names itself, not who signed it: for a key that matters, create the pack on the command line (a seed passed here travels through the conversation). Input is capped at 4 MiB and the reply at 4 MiB (narrow the window). A pack is a technical record of what the engine computed from a log under stated settings; it is not a legal opinion, a finding of fact about any event, or a certification. Evidence tier: MODELLED.
- **create_round_trip_pack** — Create the signed laboratory round-trip pack (`kshana evidence round-trip`, docs/spec/TEST-CONDITIONS.md): links by hash the scenario that produced the motion, the laboratory's `kshana.test-conditions/1` document, the receiver log and its score against the stated events, in a signed evidence pack whose `config.json` carries a `round_trip` block. Refuses a pack whose conditions and scoring events disagree, or whose stated log SHA-256 is not the log's. NO SIGNAL: nothing is written, replayed or scheduled; how a scenario's motion reached the receiver is the operator's responsibility and is recorded only as stated. The signing seed is never returned or logged; omitted, a one-time key is used and discarded (integrity, not identity). Input is capped at 4 MiB and the reply at 4 MiB. A technical record, not a legal opinion or a certification. Evidence tier: MODELLED.
- **export_interop** — Export a Kshana scenario in one interoperability format: `czml` (Cesium Language, for CesiumJS), `kml` (Keyhole Markup Language, for Google Earth and geographic information system tools), `geojson` (RFC 7946), `stk` (Systems Tool Kit ephemeris `.e`, one file per satellite) or `sigmf` (Signal Metadata Format recording of a `spectrum` scenario's synthesised samples). The first content item is a JSON index: `format`, `spec_url` and `files`, each with its `suffix` (what the command line appends to the output name, for example `.czml` or `.G01.e`), `bytes`, `sha256` and `encoding`. The files follow, one content item each, in index order: `utf-8` files as their text, the binary SigMF sample file as `base64`. A campaign exports each member scenario the format applies to. A format that does not apply is refused with the reason; list_export_formats reports all five at once. Times are Coordinated Universal Time (UTC); the same scenario gives byte-identical files.
- **export_oem** — Export an `orbit` scenario's propagated constellation as CCSDS OEM 2.0 ephemeris text — the inertial (TEME) state time series carrying position AND velocity, which flight-dynamics tools (GMAT / Orekit / STK) read. This is the velocity-carrying complement of the position-only `export_sp3`. Errors if the scenario is not an orbit kind.
- **export_omm** — Export an `orbit` scenario's mean elements as a CCSDS 502.0-B-2 OMM (Orbit Mean-Elements Message) catalogue — one OMM per satellite. Errors if the scenario is not an orbit kind.
- **export_sp3** — Export an `orbit` scenario's propagated constellation as SP3-c precise-ephemeris text (the standard GNSS post-processing format). Errors if the scenario is not an orbit kind.
- **export_table_csv** — Run a Kshana scenario and return its reproducibility table as CSV text — the byte-stable table the CLI writes as `<scenario>.table.csv` and the papers cite. Only these kinds emit one: `realtime-frame-eop`, `lunar-time-budget`, `lunar-jamming`, `telecom-timing`, `leo-navmsg` when its `encode-decode` analysis runs on a `kepler16` or `kepler-rac` message model (the broadcast ephemeris table), and `moonlight-service-volume` when both `export_site_lat_deg` and `export_site_lon_deg` are set. Errors for any other kind (or an invalid scenario); use run_scenario for the figures of merit.
- **export_test_bench** — Export a scenario's vehicle motion and events for a laboratory GNSS simulator (`kshana bench-export`, docs/TEST-BENCH.md): a motion CSV and its JSON description (Earth-fixed and geodetic position, velocity, attitude, UTC), NMEA 0183 GGA/RMC sentences, a waypoint text when the sample grid is millisecond-regular, and the scenario's events as CSV and as `[[events]]` TOML for a `receiver-trust` scenario. Applies to `gnss-ins` (its navigation-state outages are the events), `jamming` and `gnss-sim`; another kind is refused with the reason. `epoch` is the UTC instant of motion time zero, `YYYY-MM-DDTHH:MM:SS` (default 2024-01-01T00:00:00Z). Nothing is written to disk: the first content item is a JSON index (`files` with `suffix`, `bytes`, `sha256`; `notes` on any file left out; `notice`), followed by each file's text in index order. The same scenario and epoch give byte-identical files. NO SIGNAL: nothing exported is, models or drives a radio-frequency or baseband signal, and an event is a labelled interval, not a recipe for producing interference; the simulator and its operator supply the signals and are responsible for running them only where authorised. Keep the notice with the files. Kshana publishes no results from such runs. Evidence tier: MODELLED.
- **fit_imu_log** — Fit the sensor parameters of the `hybrid` and `fusion` scenarios from a stationary IMU log (`kshana imu-fit`, docs/MACHINE-INPUTS.md). Those scenarios take noise parameters, not a time series: this reads them off a log recorded with the sensor held still, by the overlapping Allan deviation of the integrated signal. Returns JSON: `fit` (accelerometer bias, velocity-random-walk PSD `q_va`, gyro bias, angle-random-walk PSD `q_arw`, bias-instability floor when the log is long enough to show one, the log's rate and span, the early Allan slopes, and `notes` on what could not be fitted or trusted), `toml` (an `[accel_classical]` table whose provenance names the log's SHA-256, ready to paste into a scenario) and `sha256`. A log that was not stationary, or is too short or unevenly sampled, gives wrong parameters or is refused; the slopes (about -0.5 where white noise dominates) show which. Nothing is written to disk. Evidence tier: MODELLED (the estimator applied to the log, no external oracle).
- **generate_training_nmea** — Generate synthetic bridge NMEA 0183 for crew training from a `nmea-scenario` TOML (`kshana nmea-scenario`): a vessel track and a timeline of scripted events (jamming, position drag-off, time spoof, replay delay, with recovery). Returns the checksum-valid sentence set (GGA, RMC, VTG, GSV, GSA, GNS, ZDA, HDT, VBW; the first 2000 lines) and the instructor log (what was injected when, with the true track and a top-level `summary` of peak speeds and accelerations; drag-off events carry their peak drag speed and acceleration; schema kshana-nmea-training/1) as JSON and text. The receiver's visible-satellite ceiling is `receiver.max_used` (default 12). Deterministic per `seed`. TEXT ONLY: nothing here synthesises RF, IQ or any waveform, nothing is transmitted, and the output is for training and testing, never for a vessel's live navigation systems (a marker sentence in the stream says so). Advisory, not type-approved navigation equipment. Streaming to a TCP or UDP address is command-line only. Four example scenarios ship in scenarios/training/.
- **get_example_scenario** — Return the TOML text of one bundled reference scenario, byte for byte the file the repository ships under `scenarios/`. Pass the text (edited or not) to run_scenario, report_scenario, animate_scenario or an export tool. Names come from list_example_scenarios. A scenario that exists in the repository but is not bundled is refused with the reason.
- **import_route** — Write a GeoJSON route into a Kshana scenario that flies a waypoint track, and return the new scenario TOML (run it with run_scenario). The route is a `LineString` (or a `Feature` / `FeatureCollection` holding one) of longitude, latitude positions; it replaces the scenario's `start_lat_deg`, `start_lon_deg`, `step_lat_deg`, `step_lon_deg` and `waypoints`. The kinds that take a route are `terrain-nav`, `terrain-slam`, `gravity-map` and `combined-altpnt`; any other kind is refused with the reason. Give the two ends of the track, or evenly spaced positions along a straight line: the track kinds fly start + i*step, so any other shape is refused.
- **iq_acquire** — FFT acquisition of one or more PRNs over an IQ recording in the work directory (`kshana iq acquire`). Reads only the samples one search needs (coherent × noncoherent code periods), which must fit the sample budget. Optional `frontend` stages (band-pass, notch, blanking, excision, AGC, quantiser) run first. Replies with one detection per PRN: `acquired`, `doppler_hz`, `code_phase_chips`, the normalised peak `statistic`, its detection `threshold` and the `peak_ratio`; `json_out` / `csv_out` also keep the full result as files, and `surface_out` (one PRN; .csv, .json or .bin) keeps the whole Doppler × code-phase correlation-power surface with the peak and its parabolic and fine-search Doppler refinements.
- **iq_campaign** — Run a lab-replay campaign held in the work directory (`kshana iq campaign`): recordings (each described by a `kshana.test-conditions/1` file stating the lab's known truth) x front-end chains x loop designs, each cell tracked and scored against the stated conditions (time to loss of lock, re-acquisition time, C/N0 degradation against the stated J/S beside an analytic reference labelled MODELLED, false-lock rate, PLL/DLL jitter, availability). Incremental: one call runs the pending cells that fit the sample budget (or `max_cells`), every finished cell is kept, and the next call resumes. Replies with the cell counts, failures, the files written, and the `digest` once every cell is done. Scores recorded data only; it synthesises no interference.
- **iq_campaign_status** — Report a lab-replay campaign's progress from its output folder in the work directory, reading files only: cells done and pending, the recordings, front ends and designs in the plan, and the `digest` once every cell is done.
- **iq_frontend** — Apply receiver front-end and interference-mitigation DSP to an IQ recording in the work directory and write the result as a new raw recording with a `<out>.json` sidecar (`kshana iq frontend`). `stages` picks any of: `bandpass_hz` [lo, hi] FIR, adaptive `notch`, pulse `blank`ing, frequency-domain `excise`, `agc`, and a `bits`-bit quantiser (preceded by an automatic AGC unless `no_agc`), always in that order. The whole input must fit the sample budget. Replies with the samples processed and the files written with their byte counts. This processes a recording; it synthesises nothing.
- **iq_info** — Describe one IQ recording in the work directory without processing it: kind (raw with sidecar, SigMF, SigMF collection), sample format, sample rate, centre frequency, total samples, duration, data files and their size, capture boundaries and annotation count, as JSON (the same row `kshana iq info` prints). Optional `raw` describes a raw file with no sidecar; optional `hash` adds each data file's SHA-256 (reads the whole file).
- **iq_labfit** — Fit the tracking-loop loss-of-lock model to lab runs (`kshana iq labfit`): an `iq-labfit` scenario TOML names one or more runs, each a receiver log plus its stated test conditions; the engine loads each log, fits the loop and empirical models, bootstraps the uncertainty and computes the hold-out error. Everything is inline: each run's `log` gives `text` or `base64` (a `path` is refused) and the tool reads and writes no file, so it does not need the IQ work directory. Alternatively the scenario's `[input]` names `campaign = "<out-dir>"`, a finished `kshana iq campaign` output folder: the tool then fits the C/N0 and lock models to its scored cells (a `kshana.labfit-iq/1` report; Q is stated, never fitted, and the identifiable J/S offset is fitted; with `mode = "validation"` a `[validation]` table is required). That folder is resolved relative to the IQ work directory and must lie inside it (anything outside is refused); it is read, nothing is written. Replies with the parsed `report`, the residuals and predictions as CSV text and a Markdown summary. Input is capped at 4 MiB. The fit describes the lab runs given; it is not a prediction for other receivers or conditions beyond what the report states. Evidence tier: MODELLED.
- **iq_monitor** — Run the interference and spoofing detection monitors over an IQ recording in the work directory (`kshana iq monitor`): the wideband `power` and `spectral` monitors, and, given `signal` + `prns`, the per-satellite C/N0 and signal-quality monitors, each against a baseline learned from the first `baseline_s` seconds (or from a settings file). Replies with the series (name and length), every event the monitors raised (start, end, monitor, what changed; at most 200 in the reply), and the settings and baselines the monitors learned; `json_out` keeps the whole report (every series, event and spectrum) and `csv_prefix` writes `<prefix>.series.csv` and `<prefix>.events.csv`. The span must fit the sample budget (`max_seconds` narrows it). A monitor event says a measured quantity left its learned baseline; it does not identify a cause or a source. This scores recorded data only; it synthesises nothing. Evidence tier: MODELLED.
- **iq_scene** — Generate a multi-satellite GNSS IQ scene into a file in the work directory (`kshana iq scene`). Stated-profile mode: `signal` + `prns` (+ optional `dopplers_hz`, `cn0_dbhz`, `data`). Broadcast mode: `nav` (a RINEX navigation file in the work directory) + `rx_pos` [lat, lon, alt] places each healthy GPS satellite at its true broadcast geometry. Optional `channel` applies ionosphere, troposphere, scintillation, multipath, land-mobile shadowing or NLOS at the signal level. `rate_hz × duration_s` must fit the sample budget (see iq_signals). Writes the recording (raw + `<out>.json` sidecar, or a SigMF pair) and a truth sidecar; replies with the files written and their byte counts, the sample count and sampling, and the truth's first epoch per satellite (code phase, Doppler, C/N0) to score iq_acquire against. The IQ layer adds no interference or spoofer synthesis; nothing is ever transmitted.
- **iq_signals** — The GNSS IQ layer's set-up, as JSON: `signals` (the signal names iq_scene, iq_acquire and iq_track accept), `enabled` (whether the IQ file tools are on), `work_dir` (the only folder they read and write; every path argument is relative to it), `max_samples` (the most complex samples one call may generate or process) and, when off, `reason`. IQ samples never travel through the protocol: tools take file paths in the work directory and reply with compact JSON summaries. The IQ layer adds no interference or spoofer synthesis; nothing is ever transmitted. Call this first.
- **iq_sweep** — Replay one IQ recording in the work directory across several tracking-loop designs and report each design's steady-state result (`kshana iq sweep`): the designs are every design of a `kshana.loop-design/1` file (`design`), or the product of the `pll_bws_hz`, `dll_bws_hz`, `spacings_chips` and `coherents` lists on the built-in design. Each PRN is acquired once and every (design, PRN) channel tracks the same samples, so each result is exactly that of running the design alone. Replies with, per design and PRN, `epochs`, `phase_jitter_deg` and `code_jitter_chips` (over the second half of the run), `phase_lock_frac`, `code_lock_frac`, `mean_cn0_dbhz` and the design's hash; `json_out` / `csv_out` keep the table as files. The span tracked must fit the sample budget (`max_seconds` narrows it) and at most 256 (design, PRN) channels run per call. This processes a recording; it synthesises nothing.
- **iq_test_conditions** — Validate a lab test-condition file (`kshana iq conditions`): a `kshana.test-conditions/1` file, TOML or JSON text, stating the lab's known truth for a recording (the satellites expected, the settle time, the stated jamming or interference schedule). Replies with the resolved conditions and their `hash`, or the reason the file is invalid. Inline only: nothing is read from disk, and a recording path the file names is not opened (a campaign resolves those inside the work directory). Input is capped at 4 MiB.
- **iq_track** — Acquire then track one or more PRNs over an IQ recording in the work directory (`kshana iq track`): acquisition initialises each channel, then the DLL/PLL (optionally FLL-assisted) loop bank replays the recording once. The samples tracked (the whole recording, or its first `max_seconds`) must fit the sample budget. The loops come from `design` (a `kshana.loop-design/1` TOML file in the work directory, `design_name` to pick one) or the built-in design, with the loop arguments overriding it; `reacquire` re-acquires a channel that loses lock or false-locks. Tracking streams, so memory does not grow with the recording. Replies with the design's name and hash, any `warnings` (`commensurate_sampling`: a sample rate that is a multiple of half the chip rate makes code-loop jitter and bias unrepresentative) and, per channel, the epoch count, seconds tracked, final Doppler and code phase, final and mean C/N0 (dB-Hz), the fractions of epochs in phase and code lock, `locked_at_end`, the final lock state, false locks detected and re-acquisitions. Per-epoch output goes to files only: `epochs_out` (E/P/L, discriminators, loop states, C/N0, lock state; .csv/.jsonl/.bin), `events_out`, `json_out` / `csv_out`. A PRN that is not acquired is refused with its statistic and threshold.
- **jammertest_import** — Read the published Jammertest test catalogue and transmission plan (NPRA/jammertest-plan, MIT) as scheduled truth (`kshana jammertest import`): the slots of one test area become receiver-trust events with the catalogue id and year in each label. `plans` holds one plan file per day, `log_start_utc` is the log's first epoch, `local_offset_h` the plan's offset from UTC (default 2, CEST). Returns `events_toml` (append it to a receiver-trust session), `events` (test id, kind, onset and end in seconds since the log start), and the counts skipped. The events are PLANNED slots, not recorded on-air times: a slot may start late or never run, and the plan's `status` field is mostly empty. No contact or personal field of the plan is read. Input is capped at 4 MiB per text. Evidence tier: MODELLED.
- **jammertest_score** — Score a receiver log against the Jammertest schedule (`kshana jammertest score`): per scheduled test the detection latency (first alarm minus planned start), whether it was detected within the tolerance, late or missed, and the time to recover (an alarm-free stretch of `recover_hold_s`), plus the false alarms outside every slot and its guard. `session_toml` needs only `[log] format = "ubx"` (or rinex, android, nmea, sbf); give the log as `log` (text formats) or `log_base64` (binary). Needs the catalogue and plan JSON (`catalog_json`, `plans`) and the test area (`location`). Returns the scorecard: `tests`, `summary`, `baseline_contaminated` and a MODELLED label. The schedule is planned slots, not recorded on-air times, so a miss may be a test that never ran. A signed evidence pack needs a signing key: use the command line (`kshana jammertest score --key`). Input is capped at 4 MiB per text. Advisory only: not type-approved navigation equipment; the operator remains responsible. Evidence tier: MODELLED.
- **list_example_scenarios** — List the bundled reference scenarios as JSON: `count`, and `scenarios`, an array of `name`, `kind` and `about` (the first sentence of the file's own header comment). Every one is a complete scenario that runs as it stands, so this is the quickest way to a valid TOML for a kind: pick a name, fetch it with get_example_scenario, edit it, run it. Pass `kind` to list only the examples of one kind (for example `spectrum`, `solar-system`, `constellation-design`, `campaign`, `leo-signal`, `leo-pass`, `leo-navmsg`, `leo-pvt`).
- **list_export_formats** — Report which interoperability export formats apply to a Kshana scenario, without running it: a JSON array with one entry per format (`czml`, `kml`, `geojson`, `stk`, `sigmf`) giving `applies`, the `reason` when it does not, and `spec_url`, the published specification the writer follows. CZML (Cesium Language), KML (Keyhole Markup Language), GeoJSON and the STK (Systems Tool Kit) ephemeris `.e` describe the scenario's geometry; SigMF (Signal Metadata Format) records the samples a `spectrum` scenario with an `[iq]` block synthesises. Call this before export_interop.
- **list_scenario_kinds** — List every built-in Kshana scenario kind with its description and required/optional TOML fields, as a JSON array. Use this to discover what scenarios can be run and how to construct a valid scenario TOML for run_scenario.
- **list_standards_packs** — List the standards packs (`kshana standards-pack list`): scored scenario sets for the DHS Resilient PNT framework test profiles, IMO MSC.1/Circ.1575 and ICAO Doc 9849 Appendix F, each with the bars it states before the run and the compliance rows it supports evidence for. Needs no input. A pack measures modelled scenarios against stated bars; it rates no product. Evidence tier: MODELLED.
- **lunanet_afs_check** — Check the LunaNet Augmented Forward Signal (AFS) against the published specification, pinned to LNIS Version 5 Applicable Document 1 Volume A (LSIS-AFS V1.0, 29 January 2025) (`kshana lunanet-afs-check`, docs/LUNANET-AFS.md). Mode `spec` checks this implementation against the document's printed code tables (the first and last 24 chips of every AFS-I Gold, AFS-Q Weil and tertiary code for PRN 1 to 210, and both Legendre sequences) and worked examples (SB1 BCH, CRC-24Q), bars B1 to B10 of a pre-registration; B4 reports one miss (the document prints the same last 24 chips for tertiary PRN 147 and 151). Mode `symbols` checks a hard-decision symbol stream (text of 0 and 1) for the synchronisation pattern, SB1 decoding, FID, TOI continuity and frame spacing. Subframes 2 to 4 (rate-1/2 LDPC, CRC-24Q) are NOT verified: the LDPC matrices are in a separate annex that is not implemented. Mode `generate` returns a test stream with placeholder subframes: symbols, not a waveform; Kshana writes no signal. VALIDATED only against the printed tables of that edition, which the document itself marks TBC; say so, and do not describe a result as showing that any LunaNet node or service is correct. Advisory only.
- **render_leaderboard** — Render kshana-bench result files (`kshana bench leaderboard`) as the static leaderboard page, HTML text in the reply: `results` is a list of `kshana-bench-result/1` JSON texts (at most 256, 4 MiB each), each validated first; a file scored under another major spec version is refused because results of different major versions are never put in one table. A row says this file scored this number on this split; it does not mean any product has been rated or approved by anyone. Nothing is written. Evidence tier: MODELLED.
- **report_scenario** — Run a Kshana scenario and return its report: an executive summary, the inputs, every result figure with its unit and its VALIDATED or MODELLED label, the events, the capability rows the run exercised, and a reproducibility record (engine version, scenario and result SHA-256 digests, seed, the command that reproduces it). `format` is `json` (default; the machine-readable `report.json`) or `html` (the printable, self-contained `report.html` with the chart embedded). A campaign's report also carries its sweep table or Monte Carlo distribution. The report is a pure function of the scenario: no clock is read.
- **route_exposure** — Summarise how much of a route runs through degraded cells of one or more interference maps (`kshana route-exposure`): for each map (one per source per UTC day, the GeoJSON `build_interference_map` returns), the route length and the shares of its length in degraded cells, in cells that were not degraded, in cells with too little sample to assess, and in cells not observed. The route is a GeoJSON LineString or `lat,lon` CSV text; `date_from`/`date_to` (YYYY-MM-DD) keep maps in a date range. Input is capped at 4 MiB per item. Cells not observed are not evidence of a clear route; a degraded cell does not identify interference as the cause; this describes past reports and is not a forecast. Evidence tier: MODELLED.
- **run_scenario** — Run a Kshana PNT-resilience scenario from a TOML definition and return its figures of merit. Returns the human-readable summary followed by the full result JSON (FoMs, curves). Kshana validates SGP4/SDP4, IAU reference frames, Allan deviations, GNSS availability/DOP, ARAIM protection levels, GNSS/INS fusion, and quantum-sensor models against published references. Every kind runs through this one tool, including `spectrum` (radio-frequency spectrum and waterfall), `solar-system`, `constellation-design` and `body-pnt` (constellations around any body), `campaign` (chained phases, parameter sweeps, Monte Carlo ensembles and composed scenarios) and the low-Earth-orbit navigation kinds `leo-signal`, `leo-pass`, `leo-navmsg`, `leo-pvt`, `leo-ppp`, `ntn-positioning` and `leo-pnt-chain`. Content is inline: a scenario field that names a file is refused, and a scenario is at most 4 MiB. Call list_scenario_kinds first to discover scenario types and their fields, and list_example_scenarios / get_example_scenario for a complete runnable scenario of a kind.
- **run_standards_pack** — Run one standards pack (`kshana standards-pack run <id>`): every scenario in it, scored against bars stated before the run. Returns the report (each test `MET`, `NOT MET`, or `NEEDS INPUT` when it needs a receiver log and is not scored; each bar with its measured and expected value) and the same as `markdown`. Pass the report JSON to `compliance_report` to see the rows the pack supports evidence for. Say plainly that a MET bar means a modelled scenario met a stated bar, and that a NOT MET is a result on record; never describe the output as showing that a product or a framework is met. Advisory only: analysis output, not type-approved navigation equipment. Evidence tier: MODELLED.
- **score_benchmark** — Score a kshana-bench submission (`kshana bench score`, bench/SPEC.md, docs/BENCH.md): a predictions file (`kshana-bench-predictions/1`) against a truth file (`kshana-bench-truth/1`), both JSON text, at most 4 MiB each, and return the result file (`kshana-bench-result/1`) with the spec version, task (a detection on receiver logs, b detection on IQ, c timing holdover prediction, d out-of-distribution optimism gap), split, the SHA-256 of both inputs and the task's metrics (AUC, detection probability at a false-alarm cap, RMSE per horizon, or the optimism gap). `threshold` is the declared alarm threshold of tasks a and b. Nothing is read from disk or written. Every score is MODELLED and describes a log or corpus, never a product; it is not a certification and no organisation is endorsed by a score. Evidence tier: MODELLED.
- **sky_geometry** — Sky geometry under an azimuth-dependent skyline (a street canyon, a harbour, a fjord, a container terminal): from a site, a time and constellation presets, two-line element sets (`tle`, with a UTC `epoch`) or satellites given as azimuth/elevation or ECEF, which satellites are visible and which are hidden by the skyline, GDOP/PDOP/HDOP/VDOP/TDOP from the gnss_lib_py-checked DOP kernel, the east-north-up cofactor and covariance with one receiver clock per system (or one in common), and the horizontal error ellipse at one sigma and at a stated confidence for a stated UERE. With no `request`, describes a REPRESENTATIVE skyline preset with its provenance and its cut every degree (an empty `skyline_preset` lists them). Scenarios of the orbit and integrity (with `user_site`), gnss-sim, jamming, leo-pvt and leo-pass kinds take the same `[skyline]` section through run_scenario. Evidence tier MODELLED: geometry under a stated error model, line of sight only; not a prediction of a receiver's real error and not an integrity bound; preset constellations are a representative sky, not the sky of a date; `tle` text with an `epoch` (UTC) gives the sky those element sets give at that epoch (SGP4), not a measurement, and `sky_source` says which. Carries the advisory: not type-approved navigation equipment. No Monte Carlo over MCP (bulk samples; use the CLI, Python or WASM). Inline only, at most 4 MiB.
- **trust_telemetry** — Render a GNSS trust stream or a `receiver-trust` result as security telemetry text (`kshana trust-telemetry`, docs/TRUST-TELEMETRY.md), with the same encoders the command line uses: `prometheus` (the exposition of the final state), `cef` or `leef` (one RFC 5424 syslog line per band change, or per epoch with `syslog_all`; no timestamp, because no clock is read) or `otlp` (the OTLP/HTTP JSON metrics payload). `input_kind` is `jsonl` (default) or `result`; a stream line that does not parse is skipped and counted in `kshana_trust_input_errors_total`. Nothing is sent, served or written: the output is text in the reply (the running exporters, which are a process, stay on the command line). The receiver-reported position is left out unless `expose_position` is true. An input that carries satellite geometry (live schema 1.3, results from 0.36) adds the geometry label (good, fair, poor; never scored but for poor) and status, HDOP, PDOP, VDOP and satellites used, and a `class` label (geometry, environment, inconsistency) on each reason; an older input renders exactly as before. Advisory only: Kshana is not type-approved navigation equipment (IEC 61108, IEC 61162) and the operator remains responsible. Evidence tier: MODELLED.
- **validate_scenario** — Pre-flight check of a Kshana scenario TOML: verify it parses as TOML and detect its scenario kind, without running it. Returns the detected kind, or a descriptive error for malformed TOML. (run_scenario performs the full validation by executing the scenario.)
- **verify_evidence_pack** — Verify a signed evidence pack (`kshana evidence verify`): every file's SHA-256 against the manifest, the hash chain, the Ed25519 signature, and with `public_key` (the signer's key, from the signer by another route) that the signer is the one expected, and with `full_log` that the log you hold is the one the pack records and that the slice came from it. Returns the report: `ok`, each failure by code and file, every check, `signer_pinned`, notes, and a `verdict`: `verified` (signer pinned), `intact-signer-not-pinned` (everything checks but no trusted `public_key` was given, so the signature proves only that the pack is intact against the key it names itself, which anyone can generate; say so, do not call it verified) or `failed`, with a `message` to show the user. `require_timestamp` fails a pack that carries no timestamp token. Inputs are capped at 4 MiB. A verified pass says the record is unchanged and who signed it (the key you supplied); it does not say what caused any event, who is responsible, or that the log shows what the receiver really received.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "kshana-pnt-resilience-simulator": {
    "command": "npx",
    "args": ["-y","kshana-mcp@0.40.0"]
  }
}
```

## Documentation

## What Kshana PNT-resilience simulator MCP server does

Kshana PNT-resilience simulator exposes the Kshana PNT simulation engine to AI agents through MCP. Its subject area is resilience of positioning, navigation, and timing systems when GNSS signals are disrupted or unavailable. The engine can represent orbital motion, coordinate and reference-frame operations, GNSS conditions, and navigation-sensor fusion.

The simulator is intended for analysing failure and degradation scenarios rather than only nominal navigation. Supported examples include jamming, spoofing, and clock holdover. A run can be used to assess how long a system keeps its time and position within defined budgets, and to compare the margin provided by different clocks or sensors.

## How it works

A scenario supplies the conditions for a run, together with a seed. Kshana uses those inputs and the engine version to produce reproducible results, so the same run can be repeated bit for bit. The broader Kshana project can run from a terminal, notebook, IDE, AI assistant, or browser; this listing focuses on its MCP surface for agent-driven access.

Kshana distinguishes capabilities by evidence status. The project’s machine-checked ledger labels them as VALIDATED when an independent external oracle agrees, MODELLED when they are internally consistent and explicitly identified as such, or PARTNER when they depend on a hardware part. This classification is useful when deciding whether a simulation result is suitable for a particular engineering or research workflow.

## Tools and capabilities

The MCP interface is designed around the simulator’s main technical areas:

- Orbit-related simulation and analysis.
- Reference-frame and coordinate calculations.
- GNSS signal and availability scenarios.
- Fusion of navigation inputs and sensors.
- Resilience analysis for jamming, spoofing, and holdover conditions.
- Agent access to Kshana run results and simulation workflows.

These capabilities fit work that requires an agent to inspect PNT behaviour under degraded signals, compare timing or navigation margins, or reason about the consequences of losing GNSS service.

## Limitations and notes

Simulation results depend on the selected scenario, seed, engine version, and the evidence status of the capability being used. “Validated,” “modelled,” and “partner” are different assurance categories, not interchangeable guarantees. The project describes itself as an open-source simulator, while also identifying a commercial licensing option; review the applicable licence before incorporating it into a product or service.

The engine is specifically oriented toward PNT resilience. It is therefore a better fit for orbital, GNSS, timing, navigation, and sensor-fusion analysis than for general-purpose geospatial or aerospace task automation. The project’s published material also identifies multiple user surfaces, including terminal, notebook, browser, and AI-assistant use, with the MCP surface providing the agent-facing route.

_Full upstream README: https://allmcps.com/mcp/kshana-pnt-resilience-simulator/readme_

