Kshana PNT-resilience simulator
LocalAbout Kshana PNT-resilience simulator
Kshana PNT-resilience simulator is an MCP server for running validated positioning, navigation, and timing simulations. It is for AI assistant users who need computed results, provenance, and clear VALIDATED or MODELLED labels rather than model-generated calculations.
Key features
- 01Run and validate TOML scenarios
- 02Generate reports and animations
- 03Assess GNSS receiver and vessel logs
- 04Export interoperability and orbit formats
- 05Create and verify signed evidence packs
- 06Analyze interference maps and IQ recordings
Use cases
- 01Run GNSS resilience scenarios and inspect figures of merit
- 02Check receiver logs for loss of trust
- 03Prepare reproducible evidence from vessel log windows
- 04Export scenario data for external tools
MCP support
Exposes Kshana simulation, assessment, reporting, and export tools to MCP clients over stdio. Tools run the engine and return JSON results, with optional charts and files.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
npx -y kshana-mcpKSHANA_MCP_IQ_DIRFolder the GNSS IQ tools (iq_scene, iq_acquire, iq_track, iq_frontend, iq_info, iq_campaign, iq_campaign_status) may read and write; every IQ path argument is relative to it. Unset leaves the IQ file tools off; the other tools are unaffected. In a container, mount a volume and point this at it.KSHANA_MCP_IQ_MAX_SAMPLESMost complex samples one IQ call may generate or process (default 50000000).Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.
Tools
Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.
Details
From the project README
kshana-mcp: ask your AI assistant, and the engine answers
kshana-mcp is a Model Context Protocol (MCP) server for
Kshana, the open-source simulator for PNT (positioning, navigation and timing)
resilience. It lets an AI (artificial intelligence) assistant run the real engine and read
back its JSON (JavaScript Object Notation), instead of guessing the maths. It speaks over
stdio (standard input and output) to any MCP-compatible client, including Cursor and
JetBrains AI Assistant / Junie.
The maths Kshana is validated for is exactly where a language model guesses badly: SGP4 (Simplified General Perturbations 4) orbit propagation, reference frames of the IAU (International Astronomical Union), Allan deviations, GNSS (Global Navigation Satellite System) availability and DOP (dilution of precision), ARAIM (advanced receiver autonomous integrity monitoring) protection levels, GNSS and INS (inertial navigation system) fusion, and quantum-sensor models. Ask a question; the assistant runs a real scenario and gets figures of merit with their provenance and their VALIDATED or MODELLED label.
Tools
| Tool | What it does |
|---|---|
run_scenario | Run a scenario from a TOML (Tom's Obvious, Minimal Language) definition; returns the summary + full result JSON (JavaScript Object Notation: figures of merit, curves). Optional include_chart returns the chart as SVG (Scalable Vector Graphics). |
list_scenario_kinds | The 87 built-in scenario kinds with descriptions + required/optional fields — so the agent can construct a valid scenario. |
validate_scenario | Pre-flight check: parse the TOML and detect its kind, without running. |
list_example_scenarios | The bundled reference scenarios as JSON: each name, its kind and one sentence on what it shows. Optional kind filter. Every example runs as it stands, so this is the quickest way to a valid TOML for a kind. |
get_example_scenario | The TOML text of one bundled reference scenario, byte for byte the file under scenarios/. |
report_scenario | Run a scenario and return its report: executive summary, inputs, every figure with its unit and its VALIDATED or MODELLED label, events, the capabilities exercised and a reproducibility record. format is json (default) or html (the printable single-file page). |
animate_scenario | Run a scenario and return its time series as an animation: svg (default), html (a self-contained player) or frames (at most 120 in a reply). The first content item is a JSON summary of what was drawn; the files follow. A kind with no sampled time axis is refused with the reason. |
list_export_formats | Which interoperability formats apply to a scenario (czml, kml, geojson, stk, sigmf), the reason when one does not, and the specification each writer follows. Does not run the scenario. |
export_interop | Export a scenario as CZML (Cesium Language), KML (Keyhole Markup Language), GeoJSON, STK (Systems Tool Kit) ephemeris .e, or SigMF (Signal Metadata Format, for a spectrum scenario with an [iq] block). The first content item is a JSON index of the files (suffix, size, encoding, and the SHA-256 digest, the 256-bit Secure Hash Algorithm); the files follow, the binary SigMF sample file as base64. |
import_route | Write a GeoJSON LineString route into a scenario that flies a waypoint track (terrain-nav, terrain-slam, gravity-map, combined-altpnt) and return the new TOML. |
export_sp3 | Export an orbit scenario's constellation as SP3-c (Standard Product 3, revision c) precise ephemeris. |
export_omm | Export an orbit scenario's elements as a CCSDS (Consultative Committee for Space Data Systems) 502.0-B-2 OMM (Orbit Mean-elements Message) catalogue. |
export_oem | Export an orbit scenario's state series as CCSDS OEM (Orbit Ephemeris Message) 2.0 ephemeris — the TEME (true equator, mean equinox) position and velocity series flight-dynamics tools (GMAT, the General Mission Analysis Tool; Orekit; STK, the Systems Tool Kit) read; the velocity-carrying complement of the position-only export_sp3. |
export_table_csv | Run a scenario and return its reproducibility table as CSV (comma-separated values) — the byte-stable table the CLI (command-line interface) writes as <scenario>.table.csv. Only realtime-frame-eop, lunar-time-budget, lunar-jamming, telecom-timing, leo-navmsg (its encode-decode analysis on a kepler16 or kepler-rac message model) and moonlight-service-volume with export_site_lat_deg + export_site_lon_deg set emit one; any other kind returns an error naming these. |
sky_geometry | Sky geometry under an azimuth-dependent skyline: from a site, a time and constellation presets, two-line element sets (tle, propagated by SGP4 to a UTC epoch) or satellites as azimuth/elevation or ECEF, the satellites visible and those hidden by the skyline, GDOP/PDOP/HDOP/VDOP/TDOP from the gnss_lib_py-checked DOP kernel, the east-north-up cofactor and covariance (one clock per system or one in common) and the horizontal error ellipse; with skyline_preset instead of request, a REPRESENTATIVE preset with its provenance and its cut every degree. MODELLED; carries the advisory; no Monte Carlo over MCP. See docs/SKYLINE.md. |
assess_receiver_log | Assess a real GNSS (global navigation satellite system) receiver log for trust. The TOML names the log's format (ubx, rinex, android, nmea or sbf) and gives its bytes inline as text or base64; the tool runs the trust monitors (carrier-to-noise density drop, loss of lock, AGC (automatic gain control), jamming indicator, position jump and, with RINEX plus broadcast navigation, RAIM (receiver autonomous integrity monitoring) and a clock-aided monitor) and returns when and why the fix stopped being trustworthy. Optional [[events]] and [compare] sections score stated events and predicted C/N0 drops against stated tolerances. A [platform] kind = "vessel" table selects the maritime monitors and adds a 0-100 trust score per epoch with the monitors that deducted (advisory; MODELLED). The log goes inline as text or base64 (at most 4 MiB). Chart and per-epoch CSV on request. See docs/RECEIVER-TRUST.md. |
assess_vessel_stream | Score a bounded NMEA 0183 excerpt (at most 2 MiB and 20,000 epochs; it must hold the calibration window) the way kshana receiver-trust live scores it: per-epoch trust state and 0-100 score with the monitors that deducted, a summary and the last $PKSHT. The bounded form of the live command: no socket is opened and nothing is written to a port; the gate, --listen and the telemetry exporters (Prometheus, OTLP, syslog) are command-line only. Advisory only; MODELLED. See docs/MARITIME-TRUST.md. |
assess_vessel_log | A vessel's NMEA 0183 log (at most 4 MiB) as a batch run, with the session TOML stating the vessel's limits: the score model and every epoch's 0-100 score with its deductions (the reply keeps counts by state and the first 200 degraded or untrusted epochs). Advisory only; MODELLED. |
jammertest_import | Read the published Jammertest test catalogue and transmission plan (NPRA/jammertest-plan, MIT) as scheduled truth (kshana jammertest import): one test area's slots become receiver-trust events with the catalogue id and year in each label. Planned slots, not recorded on-air times; no contact field of the plan is read. MODELLED. See docs/JAMMERTEST.md. |
jammertest_score | Score a receiver log against that schedule (kshana jammertest score): per test the detection latency, missed alarms and time to recover, and the false alarms outside every slot. Text logs as log, binary (ubx, sbf) as log_base64. A signed pack needs a key: command line. Advisory only; MODELLED. |
create_evidence_pack | A signed evidence pack for a window of a vessel's log (kshana receiver-trust evidence): the raw log bytes for the window, configuration, per-epoch results and reasons, a summary page, and a manifest with every SHA-256 and a hash chain, signed with Ed25519. The signing seed is never returned or logged; without one a one-time key is used, so the pack proves integrity, not identity. A technical record, not a legal opinion. See docs/EVIDENCE-PACKS.md. |
attach_evidence_timestamp | Bind an RFC 3161 timestamp token (base64 of the .tsr bytes) to a pack, in memory (kshana evidence attach-timestamp); the pack with the token must still verify. The timestamp authority's signature is not checked: use openssl ts -verify. |
verify_evidence_pack | Verify a pack (kshana evidence verify): every hash, the chain, the signature, and with the signer's public key and the full log, who signed it and that the slice came from that log. Names every failure and file. The verdict is verified (signer pinned), intact-signer-not-pinned (everything checks but no public key was given, so the signer is not established) or failed; require_timestamp fails a pack with no timestamp token. |
generate_training_nmea | Synthetic bridge NMEA 0183 for crew training from a nmea-scenario TOML (jamming, position drag-off, time spoof, replay delay) with the instructor log (kshana-nmea-training/1); deterministic per seed. Text only: nothing is synthesised at RF or IQ and nothing is transmitted; never for a vessel's live navigation systems. The reply carries the first 2000 lines. |
build_interference_map | A GNSS interference map from ADS-B or AIS position reports as CSV text (at most 4 MiB): one kshana-interference-map/v1 GeoJSON per UTC day, aggregate only (no identifiers, cells under 5 distinct aircraft or vessels withheld), with the dataset licence embedded. A degraded cell does not identify interference as the cause; not a forecast. MODELLED. See docs/INTERFERENCE-MAP.md. |
export_test_bench | A scenario's vehicle motion and events for a laboratory GNSS simulator (kshana bench-export): motion CSV and JSON, NMEA, waypoints and events as text, nothing written to disk. Kinds gnss-ins, jamming, gnss-sim. No signal: nothing exported is, models or drives a radio-frequency or baseband signal; the simulator and its operator supply the signals. See docs/TEST-BENCH.md. |
create_round_trip_pack | The signed laboratory round-trip pack (kshana evidence round-trip): the scenario, the laboratory's kshana.test-conditions/1 document, the receiver log and its score against the stated events, linked by hash. Refuses conditions and scoring events that disagree. No signal; a technical record, not a certification. |
iq_sweep | Replay one IQ recording in the work directory across several tracking-loop designs (kshana iq sweep): per design and PRN the steady-state phase and code jitter, lock fractions and mean C/N0. At most 256 (design, PRN) channels per call; the span must fit the sample budget. |
iq_monitor | Run the interference and spoofing detection monitors over an IQ recording in the work directory (kshana iq monitor): wideband power and spectral monitors and per-satellite C/N0 and signal-quality monitors against a learned baseline. Series names and lengths and up to 200 events in the reply; the whole report on request as files. An event says a measured quantity left its baseline, not why. MODELLED. |
iq_labfit | Fit the tracking-loop loss-of-lock model to lab runs (kshana iq labfit) from an iq-labfit scenario whose logs are inline (text or base64; a path is refused). Reads and writes no file. MODELLED. |
iq_test_conditions | Validate a kshana.test-conditions/1 file given as text and return the resolved conditions with their hash. Inline only. |
compliance_report | The public-framework mapping filled from result documents given as text (kshana compliance-report): which rows of six resilience frameworks and standards (US DHS Resilient PNT framework v2.0, IMO ships, EASA aviation, NIS2 Article 21, EN 16803, NIST IR 8323r1) the runs support evidence for, which they do not, and each row's gap. Takes runs of {label, result, scenario?} (at most 64, 4 MiB in all). A status says the runs support evidence for the row's capabilities; it is not a finding that a framework is met and not a rating or approval of any product. The statement is returned with every report; show it verbatim. MODELLED. See docs/compliance/. |
compliance_mapping | The static mapping tables (or, with sources, the source documents they cite with versions and URLs) as Markdown, led by the same statement. Needs no runs. |
trust_telemetry | A trust stream (JSON lines) or receiver-trust result rendered as Prometheus text, CEF or LEEF syslog lines, an OTLP JSON payload or Home Assistant MQTT discovery and state lines, with the kshana trust-telemetry encoders. Text in the reply: nothing is sent or served and no clock is read. Advisory only. |
fit_imu_log | Accelerometer and gyro parameters of the hybrid and fusion scenarios fitted from a stationary IMU log (CSV or EuRoC) by Allan deviation, with a ready-to-paste [accel_classical] table and the log's SHA-256 (kshana imu-fit). Text in, JSON out; MODELLED. |
list_standards_packs | The standards packs (kshana standards-pack list): scored scenario sets for the DHS Resilient PNT framework test profiles (levels 1 to 4), IMO MSC.1/Circ.1575 and ICAO Doc 9849 Appendix F. |
run_standards_pack | One pack run against its bars stated before the run (kshana standards-pack run): each test MET, NOT MET or NEEDS INPUT, with measured and expected values; give the report to compliance_report to see the rows. MODELLED; rates no product. |
lunanet_afs_check | The LunaNet Augmented Forward Signal checked against LNIS V5 AD1 Volume A (LSIS-AFS V1.0, 29 January 2025): spec (the implementation against the document's printed code tables and worked examples), symbols (a symbol stream: sync pattern, SB1, FID, TOI continuity) or generate (a test stream). LDPC and CRC-24Q of subframes 2 to 4 are not verified; no signal is written. |
score_benchmark | A kshana-bench submission scored against a truth file, both JSON text (kshana bench score, bench/SPEC.md): the result file with the spec version, split, input hashes and the task's metrics. MODELLED; describes a log or corpus, never a product. |
render_leaderboard | kshana-bench result files rendered as the static leaderboard page (HTML text), each validated first. |
trust_telemetry | A trust stream (JSON lines) or receiver-trust result rendered as Prometheus text, CEF or LEEF syslog lines or an OTLP JSON payload, with the kshana trust-telemetry encoders. Text in the reply: nothing is sent or served and no clock is read. Advisory only. |
route_exposure | The share of a route's length in degraded, not-degraded, unassessed and not-observed cells of one or more interference maps, optionally within a date range. Unobserved cells are not evidence of a clear route. |
iq_signals | The GNSS IQ layer's set-up: the signal names the IQ tools accept, whether the IQ file tools are on, the work directory and the per-call sample budget. Call it first. |
iq_info | Describe one IQ (in-phase and quadrature) recording in the work directory without processing it: format, sample rate, centre frequency, samples, duration, data files and sizes (kshana iq info). |
iq_scene | Generate a multi-satellite GNSS IQ scene into the work directory (kshana iq scene): stated Doppler/C/N0 profiles, or true broadcast-ephemeris geometry from a RINEX navigation file, with an optional signal-level propagation channel. Replies with the files written and their byte counts and the truth's first epoch per satellite. |
iq_acquire | FFT (fast Fourier transform) acquisition of one or more PRNs (pseudo-random noise codes) over a recording (kshana iq acquire), optionally behind front-end stages: per PRN, acquired or not, Doppler, code phase, peak statistic and threshold; surface_out (one PRN) keeps the whole Doppler × code-phase correlation surface with fine-Doppler refinements. |
iq_track | Acquire, then track with the DLL/PLL/FLL (delay-, phase- and frequency-locked loop) bank (kshana iq track), with the loops from a kshana.loop-design/1 TOML file in the work directory (design) or the built-in design, and optional re-acquisition (reacquire): per channel, epochs, final Doppler, final and mean C/N0, phase- and code-lock fractions, locked at the end, the final lock state, false locks and re-acquisitions, plus the design's name and hash. Tracking streams in bounded memory; per-epoch output goes to files only (epochs_out: E/P/L, discriminators, loop states, C/N0, lock state as .csv/.jsonl/.bin; events_out). |
iq_frontend | Apply receiver front-end and interference-mitigation DSP (digital signal processing: band-pass, notch, blanking, excision, AGC, quantiser) to a recording and write a new one (kshana iq frontend). |
iq_campaign | Run a lab-replay campaign (kshana iq campaign): recordings, each with a test-condition file stating the lab's known truth, × front-end chains × loop designs. Each cell is scored for 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 and availability. Incremental and resumable: each call runs the pending cells that fit the sample budget (or max_cells). |
iq_campaign_status | A campaign output folder's progress: cells done and pending, and the digest once complete. Reads files only. |
Each tool is a thin, faithful wrapper over a public function of the kshana library — no
new simulation logic lives here, so an agent runs exactly the validated engine.
The GNSS IQ tools: files in, compact JSON out
IQ recordings run to gigabytes, so the iq_* tools never pass samples through the
protocol. They follow one contract:
- A work directory. The server reads and writes IQ files only inside the folder named
by
KSHANA_MCP_IQ_DIR. Every path argument is relative to it (an absolute path must resolve inside it); inputs are resolved through symlinks before the check, an output's folder must already exist inside it, and an existing output is replaced only withoverwrite: true. Unset, the IQ file tools are off and say how to enable them; every other tool is unaffected. - A sample budget. One call generates or processes at most
KSHANA_MCP_IQ_MAX_SAMPLEScomplex samples (default 50 000 000). In bytes that is 400 MB ascf32_le(8 bytes a complex sample), 200 MB asci16_le(4 bytes) and 100 MB asci8(2 bytes); a scene is written ascf32_leunlessformatsays otherwise. The check runs before any work, and the refusal names the duration ormax_secondsthat fits. - Compact replies. Each tool answers with one JSON summary: acquisition peaks, C/N0,
lock state, and every file written with its path and byte count. Per-epoch tables go to
the
json_out/csv_outfiles you name. - Unknown arguments are refused, not ignored, so a misspelt option is an error.
Each tool runs the same code path as kshana iq on the command line, in process. The layer
is software only: it writes files for software receivers and drives no radio hardware. The IQ
layer adds no interference or spoofer synthesis, and nothing is ever transmitted. (The separate
spectrum scenario kind can write analytic jammer IQ snapshots to a file.)
{
"mcpServers": {
"kshana": {
"command": "/Users/you/.cargo/bin/kshana-mcp",
"env": { "KSHANA_MCP_IQ_DIR": "/Users/you/iq" }
}
}
}
With the Docker image, mount the folder and point the variable at it:
docker run --rm -i -v "$PWD/iq:/iq" -e KSHANA_MCP_IQ_DIR=/iq ghcr.io/ashfordeou/kshana-mcp.
Every kind is reachable
run_scenario dispatches on the scenario's kind, so every kind list_scenario_kinds
names runs through it. That includes the newer families, each with bundled examples an
agent can fetch:
| Capability | Kinds | An example to start from |
|---|---|---|
| Spectrum and waterfall | spectrum | l-band-waterfall-jamming |
| The solar system | solar-system | solar-system-tour |
| Constellations around any body | constellation-design, body-pnt | lunar-relay-constellation, europa-surface-pnt |
| Campaigns: chained phases, sweeps, Monte Carlo (seeded random ensembles), composition | campaign | campaign-sweep-jammer-power |
| Low Earth orbit (LEO) navigation: signal design | leo-signal | leo-band-trade |
| LEO navigation: pass link budget | leo-pass | leo-pass-iridium |
| LEO navigation: navigation message | leo-navmsg | leo-navmsg-encode-decode |
| LEO navigation: fused positioning and timing | leo-pvt, leo-ppp, ntn-positioning, leo-pnt-chain | leo-doppler-positioning, leo-pnt-end-to-end |
list_example_scenarios with a kind names every bundled example of that kind.
Animations, reports and interoperability exports are not kinds: they are views of a run,
and animate_scenario, report_scenario and export_interop return them for any
scenario they apply to.
Not served: study suites (kshana --study <suite.toml>), because a suite names sibling
scenario files on disk and the scenario tools read no file. Run each member with
run_scenario. (The IQ tools do read and write files, inside their work directory only.)
Install the MCP server
Advisory, not type-approved navigation equipment: the operator remains responsible for navigation. The server runs on your computer; nothing is sent to Ashforde OÜ.
Pick any channel; all run the same server. Per-client snippets (Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Zed, Goose, Codex CLI, Gemini CLI, Continue) are in docs/MCP-INSTALL.md.
| Channel | Command or button | Requires | Pinned form |
|---|---|---|---|
| Claude Desktop extension | double-click the .mcpb for your system: macOS (Apple silicon) · macOS (Intel) · Windows | none | kshana-mcp-<target>.mcpb of v0.39.0 |
| Cursor (one click) | npx (Node) · Docker | Node, or Docker | [email protected] / ghcr.io/ashfordeou/kshana-mcp:0.39.0 |
| VS Code (one click) | npx (Node) · Docker · Insiders (npx) | Node, or Docker | [email protected] / ghcr.io/ashfordeou/kshana-mcp:0.39.0 |
| Claude Code | claude mcp add kshana -- npx -y [email protected] · plugin: /plugin marketplace add ashfordeOU/kshana then /plugin install kshana@ashforde | Node (or Docker) | [email protected] |
| npx | npx -y [email protected] | Node 18+ | [email protected] |
| uvx / pipx | uvx kshana-mcp==0.39.0 · pipx run kshana-mcp==0.39.0 | Python 3.9+ with uv or pipx | kshana-mcp==0.39.0 |
| Docker | docker run -i --rm ghcr.io/ashfordeou/kshana-mcp:0.39.0 | Docker | ghcr.io/ashfordeou/kshana-mcp:0.39.0 |
| Homebrew | brew install ashfordeOU/tap/kshana-mcp | brew | formula for v0.39.0 |
| Scoop | scoop bucket add ashforde https://github.com/ashfordeOU/scoop-bucket then scoop install kshana-mcp | Scoop (Windows) | manifest for v0.39.0 |
| winget | winget install AshfordeOU.KshanaMcp | winget (Windows) | --version 0.39.0 |
| cargo | cargo install kshana-mcp --version 0.39.0 | Rust 1.88+ | kshana-mcp 0.39.0 |
| Prebuilt binary | the release page: kshana-mcp (Linux x86-64), kshana-mcp-<target>[.exe], checked by SHA256SUMS and gh attestation verify | none | v0.39.0 |
| MCP registry | io.github.ashfordeOU/kshana-mcp (found by registry-aware clients) | a registry-aware client | 0.39.0 |
| Remote (streamable HTTP) | kshana-mcp --http 127.0.0.1:8080, self-hosted: see https://github.com/ashfordeOU/kshana/blob/main/docs/deploy/mcp-http.md | your own host | v0.39.0 |
From a checkout or git (development):
cd mcp/kshana-mcp && cargo install --path .
cargo install --git https://github.com/AshfordeOU/kshana kshana-mcp
HTTP mode (self-hosted)
kshana-mcp --http 127.0.0.1:8080 serves the same tools over streamable HTTP at /mcp. It binds
loopback only; a non-loopback address needs --allow-remote and a bearer token in
KSHANA_MCP_HTTP_TOKEN; the IQ file tools are off; request size, time and concurrency are capped; no
CORS header is sent. Kshana does not host an endpoint: you self-host it. See
docs/deploy/mcp-http.md.
cargo install puts kshana-mcp on your PATH (typically ~/.cargo/bin/kshana-mcp).
The server talks JSON-RPC (JSON remote procedure call) over stdio; logs go to stderr. Building from source needs a Rust
toolchain ≥ 1.88 (the patched rmcp 2.x SDK needs it; the kshana library itself needs
only 1.85); the Docker image needs none.
Register it with a client
Virtually every MCP client uses the same mcpServers config block — register the
kshana-mcp binary by absolute path:
{
"mcpServers": {
"kshana": {
"command": "/Users/you/.cargo/bin/kshana-mcp",
"args": [],
"env": {}
}
}
}
Or, with the Docker image instead of a local binary (no PATH needed):
{
"mcpServers": {
"kshana": {
"command": "docker",
"args": ["run", "--rm", "-i", "ghcr.io/ashfordeou/kshana-mcp"]
}
}
}
Where that block lives depends on the client:
- Cursor —
~/.cursor/mcp.json(global) or.cursor/mcp.json(per project). - JetBrains AI Assistant / Junie — Settings → Tools → AI Assistant → Model Context Protocol → Add → As JSON, paste the block, then fully restart the IDE (integrated development environment).
- Desktop assistants — most use a
…_config.jsonwith the samemcpServersshape; check your client's docs for the file location. - CLI agents — many accept the same JSON via an
mcp add/mcp.jsonmechanism.
Always use an absolute path to the binary. Set RUST_LOG=debug in env to troubleshoot
(diagnostics go to stderr; stdout is reserved for the JSON-RPC protocol).
Try it
Once registered, ask your assistant things like:
- "List the Kshana scenario kinds." →
list_scenario_kinds - "Show me a Kshana spectrum example and run it." →
list_example_scenarios,get_example_scenario,run_scenario - "Run the Kshana clock-holdover scenario with a 20 ns threshold and a 2-hour GNSS
outage; what's the quantum-vs-classical holdover?" →
run_scenario - "Export that GPS (Global Positioning System) constellation as SP3." →
export_sp3 - "Give me the realtime-frame-eop table as CSV." →
export_table_csv - "Put that Iridium pass on a Cesium globe." →
list_export_formats,export_interop - "Animate the jamming campaign." →
animate_scenario - "Give me the report for that run, with its reproducibility record." →
report_scenario - "Make a one-second GPS L1 scene with PRNs 3 and 17, then acquire and track it." →
iq_signals,iq_scene,iq_acquire,iq_track
Design note — why a separate crate
The server is a standalone, workspace-excluded crate with its own Cargo.lock, so the
official Rust MCP SDK (software development kit) rmcp and its async runtime never enter the published kshana
crate's dependency graph: a library or Python user does not compile a server they do not
run. (It was first split out because rmcp is edition 2024, needing rustc ≥ 1.85,
while the main crate then promised 1.75. The library now declares 1.85; this server
declares 1.88, the floor of the security-patched rmcp 2.x.) Continuous integration (CI)
gates this crate on its own — tests and cargo deny against its lockfile. rmcp's licence tree is clean
(Apache-2.0/MIT/BSD), so, unlike the xval/anise-frames cross-validation crate it
otherwise mirrors, the split is not about licensing.
License: AGPL-3.0-only, the GNU Affero General Public License version 3 only (or a commercial licence from Ashforde OÜ; see the repository's LICENSING.md).
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.