mcpField
K
Kshana PNT-resilience simulator

Kshana PNT-resilience simulator

Local
kshana.devScience & Education7Updated 5d ago

About 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

  1. 01Run and validate TOML scenarios
  2. 02Generate reports and animations
  3. 03Assess GNSS receiver and vessel logs
  4. 04Export interoperability and orbit formats
  5. 05Create and verify signed evidence packs
  6. 06Analyze interference maps and IQ recordings

Use cases

  1. 01Run GNSS resilience scenarios and inspect figures of merit
  2. 02Check receiver logs for loss of trust
  3. 03Prepare reproducible evidence from vessel log windows
  4. 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.

mcp.json · Universal config
{
"mcpServers": {
"ashfordeou-kshana": {
"command": "npx",
"args": [
"-y",
"kshana-mcp"
],
"env": {
"KSHANA_MCP_IQ_DIR": "<KSHANA_MCP_IQ_DIR>",
"KSHANA_MCP_IQ_MAX_SAMPLES": "<KSHANA_MCP_IQ_MAX_SAMPLES>"
}
}
}
}
Run commandnpx -y kshana-mcp
Environment variables to set
KSHANA_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.

Packages
ocighcr.io/ashfordeou/kshana-mcp:0.39.0
npmkshana-mcp0.39.0
pypikshana-mcp0.39.0

Tools

No tool list yet

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: the mark, a compass reticle marking the precise instant, beside the wordmark kshana

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.

One open engine at the centre, with the MCP server as one of its surfaces beside the command line, the Rust library, Python, WebAssembly and Kshana Studio, the Docker image and the JetBrains plugin; every surface runs the same engine, and Kshana Pro depends on it without forking it

Tools

ToolWhat it does
run_scenarioRun 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_kindsThe 87 built-in scenario kinds with descriptions + required/optional fields — so the agent can construct a valid scenario.
validate_scenarioPre-flight check: parse the TOML and detect its kind, without running.
list_example_scenariosThe 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_scenarioThe TOML text of one bundled reference scenario, byte for byte the file under scenarios/.
report_scenarioRun 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_scenarioRun 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_formatsWhich 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_interopExport 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_routeWrite 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_sp3Export an orbit scenario's constellation as SP3-c (Standard Product 3, revision c) precise ephemeris.
export_ommExport 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_oemExport 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_csvRun 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_geometrySky 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_logAssess 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_streamScore 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_logA 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_importRead 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_scoreScore 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_packA 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_timestampBind 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_packVerify 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_nmeaSynthetic 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_mapA 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_benchA 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_packThe 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_sweepReplay 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_monitorRun 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_labfitFit 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_conditionsValidate a kshana.test-conditions/1 file given as text and return the resolved conditions with their hash. Inline only.
compliance_reportThe 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_mappingThe 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_telemetryA 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_logAccelerometer 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_packsThe 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_packOne 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_checkThe 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_benchmarkA 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_leaderboardkshana-bench result files rendered as the static leaderboard page (HTML text), each validated first.
trust_telemetryA 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_exposureThe 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_signalsThe 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_infoDescribe 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_sceneGenerate 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_acquireFFT (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_trackAcquire, 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_frontendApply 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_campaignRun 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_statusA 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 with overwrite: 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_SAMPLES complex samples (default 50 000 000). In bytes that is 400 MB as cf32_le (8 bytes a complex sample), 200 MB as ci16_le (4 bytes) and 100 MB as ci8 (2 bytes); a scene is written as cf32_le unless format says otherwise. The check runs before any work, and the refusal names the duration or max_seconds that 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_out files 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:

CapabilityKindsAn example to start from
Spectrum and waterfallspectruml-band-waterfall-jamming
The solar systemsolar-systemsolar-system-tour
Constellations around any bodyconstellation-design, body-pntlunar-relay-constellation, europa-surface-pnt
Campaigns: chained phases, sweeps, Monte Carlo (seeded random ensembles), compositioncampaigncampaign-sweep-jammer-power
Low Earth orbit (LEO) navigation: signal designleo-signalleo-band-trade
LEO navigation: pass link budgetleo-passleo-pass-iridium
LEO navigation: navigation messageleo-navmsgleo-navmsg-encode-decode
LEO navigation: fused positioning and timingleo-pvt, leo-ppp, ntn-positioning, leo-pnt-chainleo-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.

ChannelCommand or buttonRequiresPinned form
Claude Desktop extensiondouble-click the .mcpb for your system: macOS (Apple silicon) · macOS (Intel) · Windowsnonekshana-mcp-<target>.mcpb of v0.39.0
Cursor (one click)npx (Node) · DockerNode, 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 Codeclaude mcp add kshana -- npx -y [email protected] · plugin: /plugin marketplace add ashfordeOU/kshana then /plugin install kshana@ashfordeNode (or Docker)[email protected]
npxnpx -y [email protected]Node 18+[email protected]
uvx / pipxuvx kshana-mcp==0.39.0 · pipx run kshana-mcp==0.39.0Python 3.9+ with uv or pipxkshana-mcp==0.39.0
Dockerdocker run -i --rm ghcr.io/ashfordeou/kshana-mcp:0.39.0Dockerghcr.io/ashfordeou/kshana-mcp:0.39.0
Homebrewbrew install ashfordeOU/tap/kshana-mcpbrewformula for v0.39.0
Scoopscoop bucket add ashforde https://github.com/ashfordeOU/scoop-bucket then scoop install kshana-mcpScoop (Windows)manifest for v0.39.0
wingetwinget install AshfordeOU.KshanaMcpwinget (Windows)--version 0.39.0
cargocargo install kshana-mcp --version 0.39.0Rust 1.88+kshana-mcp 0.39.0
Prebuilt binarythe release page: kshana-mcp (Linux x86-64), kshana-mcp-<target>[.exe], checked by SHA256SUMS and gh attestation verifynonev0.39.0
MCP registryio.github.ashfordeOU/kshana-mcp (found by registry-aware clients)a registry-aware client0.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.mdyour own hostv0.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.json with the same mcpServers shape; check your client's docs for the file location.
  • CLI agents — many accept the same JSON via an mcp add / mcp.json mechanism.

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

Markdown supported

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.