# SimConnect MCP (pypi · simconnect-mcp)

MCP server for MSFS SimConnect - full read/write access to SimVars, L-vars and events

- Trust score: 63/100 (medium)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-09-21

## Components

- pypi · `simconnect-mcp`: 63/100 (this document), [markdown](https://verifymcp.io/servers/robin24-simconnect-mcp/simconnect-mcp.md), [page](https://verifymcp.io/servers/robin24-simconnect-mcp/simconnect-mcp)

## Channel facts

- Registry: `pypi`
- Package: `simconnect-mcp`
- Version: `1.0.2`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-09-21.

- **Supply Chain Security**: 50/100
  - Malware scan not yet available for this package.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised native-build step with no shell scripting around it.
  - 1 of 30 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 32/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - License check failed: no license is declared.
  - Actively maintained (last published 19 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 81/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 6221 tokens (~163/item across 38 items; 32 tools + 6 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 67/100
  - Stability observed for 20 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 3 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 33 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the SimConnect MCP server?

SimConnect MCP runs locally as a PyPI package, launched with uvx simconnect-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add robin24-simconnect-mcp -- uvx simconnect-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "robin24-simconnect-mcp": {
      "command": "uvx",
      "args": [
        "simconnect-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "robin24-simconnect-mcp": {
      "command": "uvx",
      "args": [
        "simconnect-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add robin24-simconnect-mcp -- uvx simconnect-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "robin24-simconnect-mcp": {
      "type": "local",
      "command": [
        "uvx",
        "simconnect-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add robin24-simconnect-mcp --command uvx --arg simconnect-mcp
```

### Hermes

```yaml
mcp_servers:
  robin24-simconnect-mcp:
    command: "uvx"
    args: ["simconnect-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "robin24-simconnect-mcp": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "simconnect-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add robin24-simconnect-mcp -t stdio -c uvx -a simconnect-mcp
```

### Other

```json
{
  "mcpServers": {
    "robin24-simconnect-mcp": {
      "command": "uvx",
      "args": [
        "simconnect-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-09-20 (score 63, +1)

No change was recorded against any check on this day. Stability & Change Management went from 60 to 63. That category is still filling its 30-day observation window: 18 days of observed history at the previous scan, 19 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-18 (score 62, +1)

No change was recorded against any check on this day. Stability & Change Management went from 53 to 57. That category is still filling its 30-day observation window: 16 days of observed history at the previous scan, 17 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-15 (score 61, +1)

No change was recorded against any check on this day. Stability & Change Management went from 43 to 47. That category is still filling its 30-day observation window: 13 days of observed history at the previous scan, 14 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-13 (score 60, +1)

No change was recorded against any check on this day. Stability & Change Management went from 37 to 40. That category is still filling its 30-day observation window: 11 days of observed history at the previous scan, 12 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-11 (score 59, +1)

No change was recorded against any check on this day. Stability & Change Management went from 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-09 (score 58, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-08 (score 57, +3)

- [functional improvement] Stability: unverified → 0.23

### 2026-09-07 (score 54, −15)

- [security regression] Malware scan: pass → unverified

## MCP tools (32)

### `msfs_connect` (~42 tokens)

Connect to MSFS

Establish SimConnect connection to MSFS.

Must be called before using any other tools. Automatically attempts
to load MobiFlight WASM extension for L-var support.

Output parameters:

- `result`

### `msfs_disconnect` (~18 tokens)

Disconnect from MSFS

Close the SimConnect connection to MSFS.

Output parameters:

- `result`

### `msfs_get_connection_status` (~24 tokens)

Get Connection Status

Check SimConnect connection state, whether sim is running/paused.

Output parameters:

- `result`

### `msfs_get_simvar` (~134 tokens)

Read SimVar

Read a SimVar value by name, in the requested unit.

Returns the value together with the unit it was actually read in.
Use msfs_search_simvars first if you are unsure of the exact name or units.

Input parameters:

- `index`: Index for indexed SimVars such as engine number. Index 0 is valid.
- `name` (string, required): SimVar name, e.g. 'PLANE_ALTITUDE' or 'AIRSPEED_INDICATED'
- `unit`: Unit to read in, e.g. 'feet', 'meters', 'knots'. Defaults to the catalog unit for this variable.

Output parameters:

- `result`

### `msfs_set_simvar` (~113 tokens)

Write SimVar

Write a value to a settable SimVar.

Fails with a specific error if the sim rejects the write, rather than
reporting success. Check the 'settable' flag with msfs_search_simvars first.

Input parameters:

- `index`: Index for indexed SimVars. Index 0 is valid.
- `name` (string, required): SimVar name; must be settable
- `unit`: Unit the value is expressed in. Defaults to the catalog unit.
- `value` (number, required): Value to write

Output parameters:

- `result`

### `msfs_get_simvars_bulk` (~120 tokens)

Read Multiple SimVars

Read several SimVars in one call.

Results are keyed by 'NAME' or 'NAME:index'. A failure on one variable
does not abort the others -- that entry carries an 'error' instead.

Input parameters:

- `variables` (array, required): Variables to read. Each dict takes 'name' and optional 'unit' and 'index'. Example: [{"name": "PLANE_LATITUDE"}, {"name": "ENG_N1_RPM", "index": 1, "unit": "percent"}]. At most 100 entries per call.

Output parameters:

- `result`

### `msfs_search_simvars` (~135 tokens)

Search SimVars

Search the SimVar catalog by keyword.

Returns each variable's units and whether it is settable, so you can call
msfs_get_simvar or msfs_set_simvar with the right arguments. Results are
paginated.

Input parameters:

- `category`: Restrict to one category, e.g. 'Aircraft Position'
- `keyword` (string, required): Search term, e.g. 'altitude', 'engine'
- `limit` (integer): Maximum results
- `offset` (integer): Results to skip, for paging
- `response_format`: 'markdown' for a compact table, 'json' for rows

Output parameters:

- `result`

### `msfs_list_simvar_categories` (~42 tokens)

List SimVar Categories

List every SimVar category with its variable count.

Use this to discover category names for the 'category' filter on
msfs_search_simvars.

Output parameters:

- `result`

### `msfs_watch_simvar` (~120 tokens)

Watch SimVar Over Time

Sample a SimVar over time, returning a time series for debugging.

Fails fast if the first read raises, rather than looping for the full
duration on a name or unit that will never work.

Input parameters:

- `duration_s` (integer): Total sampling duration in seconds
- `index`: Index for indexed SimVars. Index 0 is valid.
- `interval_ms` (integer): Polling interval in milliseconds
- `name` (string, required): SimVar name to watch
- `unit`: Unit to read in. Defaults to the catalog unit.

Output parameters:

- `result`

### `msfs_trigger_event` (~229 tokens)

Trigger Event

Fire a SimConnect event.

Resolves through the library's 994-event catalog first, then falls back to
mapping the name directly, so third-party and newer MSFS events work too.
Either way, the event is sent through the same
MapClientEventToSimEvent + TransmitClientEvent pair, correlated by send ID
on a dispatcher-equipped connection (NAME_UNRECOGNIZED/ERROR mean the
event doesn't exist; other exceptions propagate as errors).

That correlation proves SimConnect accepted the packet -- not that the
aircraft acted on it. An aircraft with its own event system (PMDG, Fenix)
can silently ignore an event it received in favour of its own SDK; see
\`message` and CLAUDE.md's "Known Sim Behaviours".

Input parameters:

- `name` (string, required): Event name, e.g. 'PARKING_BRAKES', 'AP_MASTER', 'THROTTLE_SET'
- `parameter`: Integer parameter for events that take one. Negative values are supported (e.g. AP_VS_VAR_SET_ENGLISH).

Output parameters:

- `result`

### `msfs_search_events` (~128 tokens)

Search Events

Search SimConnect events by keyword, optionally filtered by category.

Spans the library's full 994-event catalog, not just the builtin
fallback list. Results are paginated.

Input parameters:

- `category`: Restrict to one category, e.g. 'Autopilot'
- `keyword` (string, required): Search term, e.g. 'autopilot', 'light', 'engine'
- `limit` (integer): Maximum results
- `offset` (integer): Results to skip, for paging
- `response_format`: 'markdown' for a compact table, 'json' for rows

Output parameters:

- `result`

### `msfs_trigger_custom_event` (~239 tokens)

Trigger Custom Event

Fire a custom event as a key event through the MobiFlight WASM module.

Requires the MobiFlight WASM module. The event is delivered via the WASM
module's RPN interface -- `(>K:NAME)`, or `PARAM (>K:NAME)` when a
parameter is given -- not through native SimConnect event mapping (that
is msfs_trigger_event). This reaches events outside the standard
SimConnect catalog.

An aircraft with its own event system (PMDG, Fenix) may silently ignore
a default key event in favour of its own SDK: measured live against a
PMDG 737, `PARKING_BRAKES` delivered through this path had no effect on
the aircraft's brake state, while a sim-level event (no aircraft can
intercept it) delivered correctly. A no-op result on such aircraft means
the aircraft ignored the event, not that this tool failed.

Input parameters:

- `name` (string, required): Custom event name, e.g. 'MobiFlight.AS1000_PFD_SOFTKEYS_1'
- `parameter`: Optional integer parameter

Output parameters:

- `result`

### `msfs_get_lvar` (~94 tokens)

Read L-Var

Read an L-var (local variable) value from the current aircraft.

L-vars are aircraft-specific local variables used by add-on developers.
Requires the MobiFlight WASM extension.

Input parameters:

- `name` (string, required): L-var name, e.g. 'A32NX_EFIS_L_OPTION', 'WT_CJ4_HDG_ON'. The 'L:' prefix and RPN wrapping are added automatically if missing.

Output parameters:

- `result`

### `msfs_set_lvar` (~150 tokens)

Write L-Var

Write a value to an L-var on the current aircraft.

Uses native SimConnect data definitions (AddToDataDefinition +
SetDataOnSimObject), which works with proprietary aircraft like the
Fenix A320/A321. Does NOT require MobiFlight and does NOT use the
MobiFlight RPN set() command.

Reads the variable back afterwards and reports 'verified': true if the
value landed, false if it did not, null if the read-back could not be
completed. A false or null is never reported as success.

Input parameters:

- `name` (string, required): L-var name; the 'L:' prefix is optional
- `value` (number, required): Numeric value to write

Output parameters:

- `result`

### `msfs_list_lvars` (~484 tokens)

List Aircraft L-Vars

Enumerate the L-vars registered by the currently loaded aircraft.

Asks the MobiFlight WASM module for its L-var list and collects the
response. The module caps its reply at 1000 names but still reports the
list as complete when it does -- see 'truncated' in the result, which is
set whenever that cap was hit. A busy add-on setup (e.g. GSX) can crowd
an aircraft's own L-vars out of a capped response entirely; msfs_get_lvar
reads any name directly regardless of whether it showed up here.

Returns bare names only -- no description, category, or writability per
variable, unlike msfs_search_lvars' catalogued rows. Use msfs_search_lvars
/ msfs_browse_lvar_catalog for aircraft with a bundled catalog when that
detail is what you need; use this tool for aircraft that have none, or
to see everything currently registered regardless of catalog coverage.

Internally sends a harmless no-op RPN command immediately before the
WASM request, to re-arm the module against a quirk where it otherwise
gives no response to a request byte-identical to the one it just
answered (see _send_list_request's own docstring below for the full
story). This creates no variable and has no effect on the aircraft, so
calling this repeatedly is safe -- but the underlying quirk is a
third-party module behavior this project does not control, so
NO_LVARS_RETURNED below stays the honest report for the rare case
where even the re-arm doesn't help, rather than this call ever
assuming success. Requires the MobiFlight WASM extension.

A listing that stops without the module's end-of-list marker returns
LVAR_LIST_INCOMPLETE rather than the names collected so far: an
arbitrary prefix of the list is indistinguishable from a complete
listing of that size once returned, so it is refused the same way
msfs_get_nearby_airports refuses a timed-out facility collection.

Input parameters:

- `filter_prefix`: Only return names starting with this prefix, e.g. 'A32NX', 'WT_CJ4', 'XMLVAR'. Case-insensitive.
- `limit` (integer): Maximum results
- `offset` (integer): Results to skip

Output parameters:

- `result`

### `msfs_execute_calculator_code` (~236 tokens)

Execute RPN Code

Execute RPN calculator code in the simulator.

Runs arbitrary RPN (Reverse Polish Notation) calculator code via the
MobiFlight WASM bridge. Can read or write any variable type and perform
complex operations. Requires the MobiFlight WASM extension.

The 'auto' mode's heuristic -- code starts with '(', ends with ')', and
contains no '(>' -- misclassifies compound read expressions such as
'(L:A) (L:B) max' as an execute, because they don't end in ')'. Pass
mode='read' explicitly for those.

Input parameters:

- `code` (string, required): RPN calculator code, e.g. '(A:PLANE ALTITUDE, feet)' to read a SimVar, '(L:MyCustomVar) 1 + (>L:MyCustomVar)' to increment an L-var, or '1 (>K:PARKING_BRAKES)' to trigger an event.
- `mode` (string): 'read' returns a value, 'execute' runs the code for effect. 'auto' guesses from the syntax, which is unreliable for compound expressions.

Output parameters:

- `result`

### `msfs_search_lvars` (~551 tokens)

Search L-Vars

Search known aircraft L-vars by keyword.

Searches the embedded L-var catalog for the current aircraft, or every
known aircraft catalog if none is loaded or auto-detected. Results are
paginated. Auto-detection tries, in order: PMDG's own client-data-area
probe (authoritative -- confirms which SDK the aircraft is actually
running, independent of what TITLE/ATC_MODEL say), every catalog's own
title_pattern matched against TITLE/ATC_MODEL (the only mechanism for a
third-party catalog dropped into data/), then honest absence.

When no aircraft catalog could be auto-detected and 'catalog' was not
given, this searches every catalog ('filters.catalog' reads "all") and
'message' explains how to scope the search instead. Otherwise, 'message'
still discloses how the catalog was resolved -- a probed detection is a
materially stronger signal than a title-text match, and a caller
deciding how much to trust the result should be able to tell them apart.
When the search was not scoped to one confirmed catalog, the markdown
table also carries a 'Catalog' column per row -- with the Fenix catalog
removed, every bundled catalog is PMDG, so a table of PMDG variables
must not render as if it were confirmed for whatever aircraft is
actually loaded.

Input parameters:

- `catalog`: Explicit catalog key to search, e.g. 'pmdg_737', 'pmdg_777', overriding auto-detection. Use this when the loaded aircraft isn't auto-detected, or to search a specific aircraft's catalog regardless of…
- `category`: Filter by panel/system category, e.g. 'Signs', 'FCU', 'Electrical'
- `keyword` (string, required): Search term, e.g. 'seatbelt', 'autopilot', 'heading', 'fuel'
- `limit` (integer): Maximum results
- `offset` (integer): Results to skip, for paging
- `prefix`: Filter by the catalog's variable-type prefix, matched exactly against each entry's 'prefix' field, e.g. PMDG's 'MCP', 'ELEC', 'EVT'. A catalog you build yourself (see msfs_browse_lvar_catalog) may us…
- `response_format`: 'markdown' for a compact table, 'json' for rows
- `writable_only` (boolean): Only return variables that can be written to

Output parameters:

- `result`

### `msfs_browse_lvar_catalog` (~363 tokens)

Browse L-Var Catalogs

Browse the aircraft L-var catalogs.

Three levels, narrowing as you supply arguments:
  \* no catalog resolved -- every available aircraft catalog
  \* catalog only        -- the panels in that catalog
  \* catalog+panel       -- the variables on that panel, with their valid values

With no 'catalog', the loaded aircraft is auto-detected: PMDG's own
client-data-area probe first (authoritative -- confirms which SDK is
actually running, independent of what TITLE/ATC_MODEL say), then every
catalog's own title_pattern matched against TITLE/ATC_MODEL (the only
mechanism for a third-party catalog dropped into data/). A successful
detection acts as if that catalog had been passed explicitly, and
'message' names which of the two resolved it -- a probed detection is a
materially stronger signal than a title-text match. When detection
fails entirely, 'catalog' comes back None, 'message' explains why, and
(with 'panel' also given) the panel is looked up across every catalog --
the first match is returned, but that is a guess, not a detection, and
'message' says so.

Input parameters:

- `catalog`: Catalog key, e.g. 'pmdg_737', 'pmdg_777'. Omit to auto-detect from the loaded aircraft, or to list all available catalogs.
- `limit` (integer): Maximum results
- `offset` (integer): Results to skip
- `panel`: Panel name to open, e.g. 'Signs', 'FCU', 'Electrical'. Omit to list the panels in the catalog.
- `response_format`: 'markdown' for a table, 'json' for rows

Output parameters:

- `result`

### `msfs_get_aircraft_snapshot` (~103 tokens)

Get Aircraft Snapshot

Read a snapshot of the current aircraft state.

Narrow with 'sections' to keep the response small -- for example
sections=['position'] for a position fix, or ['engines', 'systems']
when debugging a systems issue. All variables across the chosen
sections are read in a single batched call.

Input parameters:

- `sections`: Sections to include: identity, position, engines, systems, autopilot, environment. Omit for all of them.

Output parameters:

- `result`

### `msfs_get_nearby_airports` (~221 tokens)

Get Nearby Airports

List airports near a point, nearest first.

Filters SimConnect's airport facility list by great-circle distance from
the given (or current) position. That list is not scoped to the
aircraft's location at all -- measured live, it is the entire world
(85,249 airports) regardless of where the aircraft is -- so a radius
that finds nothing means there is genuinely no airport that close, not
that the sim "hasn't loaded" one. The distance filter always runs over
the complete list before pagination, so a later page can never miss a
match an earlier page's filtering already found.

Input parameters:

- `latitude`: Centre latitude. Defaults to the aircraft's position.
- `limit` (integer): Maximum results
- `longitude`: Centre longitude. Defaults to the aircraft's position.
- `offset` (integer): Results to skip, for paging
- `radius_nm` (number): Search radius in nautical miles
- `response_format`: 'markdown' for a table, 'json' for rows

Output parameters:

- `result`

### `msfs_get_facility_info` (~150 tokens)

Get Facility Info

Look up one airport, waypoint, NDB or VOR by ICAO identifier.

Only facilities the sim currently has loaded are visible. Airports are
the exception: SimConnect's airport facility list is the complete
worldwide set (measured live -- see module docstring), not scoped to
the aircraft's location, so an airport miss means the identifier is
wrong rather than out of range.

Input parameters:

- `facility_type` (string): Kind of facility to look up: one of 'airport', 'waypoint', 'ndb', or 'vor'
- `icao` (string, required): ICAO identifier, e.g. 'KJFK', 'EGLL', 'SEA'

Output parameters:

- `result`

### `msfs_send_sim_text` (~78 tokens)

Show Text In Sim

Display a text overlay message in the simulator (debug feedback).

Input parameters:

- `color` (string): One of white, red, green, blue, yellow, magenta, cyan, black
- `duration_s` (number): How long to display it, in seconds
- `text` (string, required): Text message to display in the sim

Output parameters:

- `result`

### `msfs_set_aircraft_position` (~293 tokens)

Reposition Aircraft

Reposition the aircraft (test scenario setup).

Uses SimConnect's SIMCONNECT_DATA_INITPOSITION, which repositions the
aircraft atomically. Writing PLANE_LATITUDE/LONGITUDE individually, as
this used to, is unreliable and cannot set the on-ground state.

The response reports the position read back from the sim after the
move, in `latitude`/`longitude`/etc -- never the request, which is
echoed separately under `requested` for comparison. A field the
read-back could not confirm is null (and listed in `unverified`), not
silently replaced by what was asked for. `status` still reports "ok"
since the reposition command itself may well have succeeded even if the
confirming read did not; check `unverified`/`warning` for that.

Input parameters:

- `airspeed` (integer): Target airspeed in knots (0 for a stationary placement)
- `altitude`: Target altitude in feet. Omit to keep the current altitude.
- `bank` (number): Bank in degrees
- `heading`: Target heading in degrees true. Omit to keep the current heading.
- `latitude` (number, required): Target latitude, degrees
- `longitude` (number, required): Target longitude, degrees
- `on_ground` (boolean): Place the aircraft on the ground at the position
- `pitch` (number): Pitch in degrees

Output parameters:

- `result`

### `msfs_get_pmdg_var` (~166 tokens)

Read PMDG Variable

Read a PMDG aircraft data field by name (777 or 737 NG3).

Uses the PMDG SDK data broadcast to read switch positions, annunciators,
knob positions, MCP values, fuel quantities, FMC data, and more.

Requires ``EnableDataBroadcast=1`` in the aircraft's options.ini
(``777_Options.ini`` or ``737NG3_Options.ini``).

Input parameters:

- `name` (string, required): Variable name from the PMDG catalog. Use msfs_search_lvars() to discover available variables. Examples: 'ELEC_Battery_Sw_ON', 'MCP_IASMach', 'FUEL_QtyCenter'.
- `variant`: Optional aircraft SDK variant. When omitted, it is auto-detected from the loaded aircraft.

Output parameters:

- `result`

### `msfs_get_pmdg_cdu` (~138 tokens)

Read PMDG CDU Screen

Read a PMDG CDU screen (777 has 3 CDUs, 737 NG3 has 2).

Returns the CDU display as text rows and an optional structured grid
with per-cell color and formatting information.

Requires ``EnableCDUBroadcast.N=1`` in the aircraft's options.ini.

Input parameters:

- `cdu` (integer): CDU unit number. 777: 0=left (Captain), 1=center, 2=right (F/O). 737 NG3: 0=Captain, 1=F/O.
- `variant`: Optional aircraft SDK variant. Defaults to auto-detect.

Output parameters:

- `result`

### `msfs_send_pmdg_event` (~179 tokens)

Send PMDG Event

Send a PMDG control event (777 or 737 NG3).

Triggers cockpit controls (switches, buttons, knobs) using the PMDG SDK
event system. Use msfs_search_lvars() to find events — look for entries with
an 'events' field.

Input parameters:

- `event_name` (string, required): PMDG event name (e.g., 'EVT_OH_ELEC_BATTERY_SWITCH').
- `parameter`: Optional position value. For toggle switches, omit this. For selectors, pass the desired position (0, 1, 2, etc).
- `variant`: Optional aircraft SDK variant. When omitted, the variant is detected from the loaded aircraft; if detection fails, the event name is looked up in both catalogs and the first match wins (PMDG 777 take…

Output parameters:

- `result`

### `msfs_search_hubhop` (~457 tokens)

Search HubHop Presets

Search the MobiFlight HubHop community preset database.

HubHop covers far more aircraft than the bundled catalogs, so this is
the place to look when msfs_search_lvars finds nothing for the loaded
aircraft. Each result's `code` field holds RPN -- typically `(>K:...)`
or `(>H:...)` -- that you can pass directly to
msfs_execute_calculator_code or msfs_trigger_custom_event, so a match
here is immediately actionable, not just informational.

The first call in this server's session downloads the full preset
database (roughly 32,000 presets, ~17 MB) and keeps it in memory; that
call alone can take several seconds. This is expected, not a hang.
Later calls, including to msfs_list_hubhop_aircraft, reuse the same
in-memory copy and return quickly, for up to 6 hours -- after that the
next call re-fetches automatically, since HubHop is a community
database that keeps growing. Pass refresh=True to force an immediate
re-fetch instead of waiting on that, e.g. right after publishing a new
preset yourself.

Requires internet access. Supply at least one of query, vendor,
aircraft or system -- the database is too large to browse unfiltered.

Input parameters:

- `aircraft`: Aircraft model, e.g. 'A320', 'B737-800'
- `limit` (integer): Maximum results
- `offset` (integer): Results to skip, for paging
- `query`: Text to match against preset labels and RPN code, e.g. 'autopilot', 'landing light'
- `refresh` (boolean): Bypass the cached preset database and re-fetch from HubHop before searching. Use this if you just added or changed a preset on HubHop and want to see it immediately, rather than waiting for the norma…
- `response_format`: 'markdown' for a table, 'json' for rows
- `system`: System, e.g. 'Autopilot', 'Lights', 'Electrical'
- `vendor`: Vendor name, e.g. 'FenixSim', 'PMDG', 'Asobo'

Output parameters:

- `result`

### `msfs_list_hubhop_aircraft` (~253 tokens)

List HubHop Aircraft

List the aircraft that HubHop has presets for.

Use this to find the exact vendor and aircraft spelling to pass to
msfs_search_hubhop -- HubHop matches those filters exactly, so getting
the spelling from here first avoids a filtered search that silently
finds nothing because of a mismatched name.

Like msfs_search_hubhop, the first call in this server's session
downloads the full preset database (roughly 32,000 presets, ~17 MB),
which can take several seconds; the two tools share the same in-memory
copy afterwards, refreshed automatically every 6 hours. Pass
refresh=True to force an immediate re-fetch instead of waiting on that.
Requires internet access.

Input parameters:

- `limit` (integer): Maximum results
- `offset` (integer): Results to skip, for paging
- `refresh` (boolean): Bypass the cached preset database and re-fetch from HubHop before listing. Use this if an aircraft was added to HubHop recently and is not showing up.
- `response_format`: 'markdown' for a table, 'json' for rows
- `vendor`: Restrict to one vendor, e.g. 'FenixSim'

Output parameters:

- `result`

### `msfs_load_flight` (~166 tokens)

Load Saved Flight

Load a saved flight, replacing the current one.

Use this to restore a known starting state before a test run. The
current flight is discarded without prompting.

Does not return as soon as the load call succeeds -- it waits for MSFS
to resume answering SimConnect first (bounded; see
_wait_for_sim_responsive and msfs_save_flight's docstring for the
measurement behind this). FlightLoad's own stall was short in the one
round trip measured live (~0.9s), but a heavier scenery load could take
much longer, so this does not assume load is always cheap.

Input parameters:

- `path` (string, required): Absolute path to a .FLT file, e.g. 'C:\Users\you\Documents\approach-test.FLT'

Output parameters:

- `result`

### `msfs_save_flight` (~320 tokens)

Save Current Flight

Save the current flight to a .FLT file.

Capture a known state so a later msfs_load_flight call can restore it.
Refuses to replace an existing file unless overwrite=True.

The library's `sm.save_flight()` ends with an unconditional `return False`,
so its return value says nothing about success -- this checks whether
the file was actually written instead. Its body also reads the file
straight back (flight_to_dic) immediately after issuing an asynchronous
FlightSave; if MSFS has not finished writing yet, that read-back can
raise rather than return False. Both a clean return and a raised
exception are followed by the same polling existence check below, since
the file on disk is the only signal either path can be trusted to leave
behind.

Does not return once the file appears, either. MSFS keeps SimConnect
entirely unresponsive for a further ~14s (measured live) while it
actually finishes the save; this waits that out too, bounded, so a
caller never gets `status: "ok"` while the sim still cannot answer
anything -- see _wait_for_sim_responsive's docstring for the full
measurement and why the wait is structured the way it is.

Input parameters:

- `description` (string): Flight description
- `overwrite` (boolean): Replace the file at `path` if one already exists there
- `path` (string, required): Absolute path for the .FLT file to write
- `title` (string, required): Flight title shown in MSFS

Output parameters:

- `result`

### `msfs_load_flight_plan` (~104 tokens)

Load Flight Plan

Load a .PLN flight plan into the aircraft's GPS or FMS.

The aircraft is not repositioned; only the plan is loaded.

Does not return as soon as the load call succeeds -- see
msfs_save_flight's docstring and _wait_for_sim_responsive for why this
waits (bounded) for MSFS to resume answering SimConnect first.

Input parameters:

- `path` (string, required): Absolute path to a .PLN flight plan

Output parameters:

- `result`

### `msfs_create_ai_object` (~283 tokens)

Create AI Object

Spawn an AI aircraft or object at a position.

Useful for building traffic or collision-avoidance test scenarios. The
title must match an installed aircraft exactly. When it does, SimConnect
confirms the object was actually created with an ASSIGNED_OBJECT_ID
reply, and `object_id` on the result carries it -- also the id
SimConnect_AIRemoveObject would need to remove it again. When the title
matches nothing installed, MSFS ignores the request silently: no error,
no reply, so `object_id` stays null. Treat that null as "not confirmed
to exist," not as a definite failure of this call -- a request registry
being briefly slow to answer, or a connection with none at all (the
plain SimConnect fallback), leaves the same null for a different reason;
see `message` for which applies.

Input parameters:

- `airspeed` (integer): Airspeed in knots
- `altitude_ft` (number): Altitude in feet
- `heading` (number): Heading in degrees true
- `latitude` (number, required): Latitude
- `longitude` (number, required): Longitude
- `on_ground` (boolean): Place the object on the ground
- `title` (string, required): Exact aircraft or object title as MSFS knows it, e.g. 'Boeing 747-8i Asobo'

Output parameters:

- `result`

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/robin24-simconnect-mcp/simconnect-mcp#diagnostics

## Score history

- 2026-09-21: 63
- 2026-09-20: 63
- 2026-09-19: 62
- 2026-09-18: 62
- 2026-09-17: 61
- 2026-09-16: 61
- 2026-09-15: 61
- 2026-09-14: 60
- 2026-09-13: 60
- 2026-09-12: 59
- 2026-09-11: 59
- 2026-09-10: 58
- 2026-09-09: 58
- 2026-09-08: 57
- 2026-09-07: 54
- 2026-09-06: 69
- 2026-09-05: 69
- 2026-09-04: 54
- 2026-09-03: 54
- 2026-09-02: 54
- 2026-09-01: 36

## Common questions

### What is the SimConnect MCP server?

SimConnect MCP is listed in the public MCP registry as io.github.robin24/simconnect-mcp. MCP server for MSFS SimConnect - full read/write access to SimVars, L-vars and events. This page covers its PyPI package (simconnect-mcp).

### Is the SimConnect MCP server safe to use?

SimConnect MCP scores 63 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 21 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the SimConnect MCP server expose?

SimConnect MCP exposes 32 tools: msfs_connect, msfs_disconnect, msfs_get_connection_status, msfs_get_simvar, msfs_set_simvar, and 27 more. Their descriptions and schemas cost roughly 6,133 tokens of context every time the server is loaded.

### Is the SimConnect MCP server still maintained?

SimConnect MCP is still listed as active in the MCP registry. We last reached this channel on 21 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- PyPI project: https://pypi.org/project/simconnect-mcp/
- Socket report: https://socket.dev/pypi/package/simconnect-mcp
- Repository: https://github.com/robin24/simconnect-mcp
- Changelog RSS feed: https://verifymcp.io/servers/robin24-simconnect-mcp/simconnect-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/robin24-simconnect-mcp/simconnect-mcp.json
- HTML version of this page: https://verifymcp.io/servers/robin24-simconnect-mcp/simconnect-mcp
