No description
  • TypeScript 94.2%
  • JavaScript 5.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-07-28 22:44:49 +02:00
deploy full features 2026-07-25 13:40:17 +02:00
scripts mono stereo fix 2026-07-25 14:27:52 +02:00
src mono stereo fix 2026-07-25 14:27:52 +02:00
test mono stereo fix 2026-07-25 14:27:52 +02:00
tmp/pdfs end phase 3 2026-07-23 21:56:24 +02:00
.dockerignore release ready 2026-07-24 19:10:23 +02:00
.env.docker.example full features 2026-07-25 13:40:17 +02:00
.env.example full features 2026-07-25 13:40:17 +02:00
.gitignore release ready 2026-07-24 19:10:23 +02:00
076 ENDE ALLES AUS.snip first commit 2026-07-23 21:48:35 +02:00
CH30_HARDWARE_TEST_ACTIVE.md docu to english 2026-07-28 22:44:49 +02:00
CH30_HARDWARE_TEST_RESTORE.json phase 8 final test 2026-07-24 18:48:43 +02:00
DEPLOYMENT.md docu to english 2026-07-28 22:44:49 +02:00
docker-compose.yml mono stereo fix 2026-07-25 14:27:52 +02:00
Dockerfile release ready 2026-07-24 19:10:23 +02:00
FIRST SETTINGS.snap first commit 2026-07-23 21:48:35 +02:00
FIXTURE_ANALYSIS.md docu to english 2026-07-28 22:44:49 +02:00
Funkenflug.show first commit 2026-07-23 21:48:35 +02:00
IMPLEMENTATION_PLAN.md docu to english 2026-07-28 22:44:49 +02:00
package-lock.json mono stereo fix 2026-07-25 14:27:52 +02:00
package.json mono stereo fix 2026-07-25 14:27:52 +02:00
PHASE2_LIVE_TEST.md docu to english 2026-07-28 22:44:49 +02:00
PHASE3_LIVE_TEST.md docu to english 2026-07-28 22:44:49 +02:00
PHASE4_LIVE_TEST.md docu to english 2026-07-28 22:44:49 +02:00
PHASE5_FILE_TEST.md docu to english 2026-07-28 22:44:49 +02:00
PHASE6_FILE_TEST.md docu to english 2026-07-28 22:44:49 +02:00
PHASE7_NATIVE_TEST.md docu to english 2026-07-28 22:44:49 +02:00
PHASE8_NATIVE_WRITE_TEST.md docu to english 2026-07-28 22:44:49 +02:00
README.md docu to english 2026-07-28 22:44:49 +02:00
tsconfig.json first commit 2026-07-23 21:48:35 +02:00

WING MCP 1.4.1

Production-ready MCP server for Behringer WING consoles and WING files. It runs locally over stdio or as a secured Streamable HTTP server on the host or in Docker.

Status

Version 1.4.1 provides:

  • MCP over stdio and stateful Streamable HTTP
  • compact and full tool profiles
  • authenticated HTTP, session limits, health checks, and graceful shutdown
  • hardened multi-stage Docker deployment
  • UDP discovery with model, firmware, and IP identity checks
  • OSC and native TCP reads, definitions, writes, and metering
  • allowlisted writes with type, range, enum, and expected-value checks
  • read-after-write verification with WING-aware quantization handling
  • automatic rollback and reusable transaction records
  • managed OSC event subscriptions with keepalive and a FIFO event buffer
  • guarded live show control
  • validated and atomic .snap, .snip, and .show file operations
  • semantic channel plans, presets, DCA assignments, buses, and mains
  • semantic input/output routing, source metadata, and user routing
  • semantic control of all documented effects and plug-ins
  • full strip control for channels, auxes, buses, mains, matrices, DCAs, and mute groups
  • monitor, solo, talkback, Automix, RTA, health, meter, and media services
  • USB Player, USB Recorder, and W-Live control
  • 24 compact-profile tools and 48 full-profile tools
  • 150 automated tests

The server has been tested against a WING Fullsize running firmware 3.1.1. All hardware write tests used channel 30 or explicitly approved show files, verified every result, and restored the previous state.

Version 1.4.1 adds dependency-aware semantic execution phases. A combined plan is ordered as follows:

  1. route group
  2. route input
  3. source pair mode
  4. stable strip and processing values
  5. source metadata
  6. headamp gain and phantom power

This ordering prevents stale-source preflight checks, source metadata writes to the previous patch, and stereo-pair side effects. The server performs one identity check per batch and verifies each phase before continuing.

Successful responses expose both an explicit boolean and numeric counts:

{
  "verificationComplete": true,
  "verified": 31,
  "verification": {
    "complete": true,
    "verified": 31,
    "warnings": []
  }
}

The MCP instructions tell clients to continue automatically when verificationComplete=true and warnings is empty. Processing inspection is also resilient: a timed-out leaf is reported as unavailable while the other requested values are still returned.

Target console

Model:    wing-fullsize
Firmware: 3.1.1
IP:       192.168.6.177

Development

npm install
npm run check
npm test
npm run build

Start the default stdio server:

npm start

Start a local HTTP server:

MCP_TRANSPORT=http \
MCP_TOOL_PROFILE=compact \
MCP_RESPONSE_DETAIL=summary \
MCP_HTTP_AUTH_TOKEN="$(openssl rand -hex 32)" \
npm start

The stdio transport reserves stdout for MCP messages. Diagnostics are written to stderr.

The explicitly authorized channel-30 quantization round trip is:

WING_LIVE_TEST_CONFIRM=channel-30-roundtrip npm run smoke:quantization

It reads the original value, verifies WING's 30 Hz quantization, restores the original value in a finally block, and runs a state-neutral 16-operation batch.

Configuration

See .env.example. Environment variables are read directly and optionally from .env. Network and write access are disabled by default:

WING_NETWORK_ENABLED=false
WING_WRITE_ENABLED=false
WING_SHOW_CONTROL_ENABLED=false
WING_FILE_WRITE_ENABLED=false
WING_NATIVE_ENABLED=false

Complete local, Docker, and ChatGPT Desktop instructions are in DEPLOYMENT.md. Docker defaults are documented in .env.docker.example.

Token-efficient semantic mode

Recommended runtime configuration:

MCP_TOOL_PROFILE=compact
MCP_RESPONSE_DETAIL=summary

A complete channel request only needs the desired end state:

{
  "channel": 30,
  "presets": ["female-vocal-clean"],
  "set": {
    "route.source": "AES50A:30",
    "name": "ELSE",
    "color": "green",
    "icon": 100,
    "input.gain.db": 20,
    "input.phantom": false
  },
  "dryRun": false,
  "confirm": true
}

wing_apply_channel compiles the required WING commands, reads previous values, skips values already at the target state, verifies the console once, checks each write, and normally returns a compact result:

{
  "dryRun": false,
  "changed": 31,
  "verified": 31,
  "verificationComplete": true,
  "skipped": 7,
  "warnings": [],
  "transactionId": "wing-20260724153000-a1b2c3d4"
}

npm run measure:tools currently reports 48 tools and 45,271 serialized bytes for the full profile versus 24 tools and 24,704 bytes for compact mode. The processing catalog is not sent in every tool context. Capability tools return model or parameter details only when requested.

Transactions remain available to wing_rollback while the MCP process is running. Rollback uses verified post-values as preconditions and therefore does not overwrite later third-party changes. Failed preflight and write transactions are recorded as well; completed writes are automatically restored in reverse order.

Built-in deterministic starting presets:

  • female-vocal-clean
  • speech-clean
  • processing-bypass

Explicit set values are applied after presets and override them. wing_plan_capabilities returns semantic keys, types, ranges, and enums only on demand.

Visible source metadata and stereo sources

The patched source can override a strip's name, color, and icon. Set source.* values when the console display must match:

{
  "channel": 1,
  "set": {
    "route.source": "AES50A:1",
    "source.name": "KICK",
    "source.color": "red",
    "source.icon": "kick"
  }
}

WING channels are stereo-capable. One odd/even input pair must therefore be represented by one channel:

{
  "channel": 14,
  "set": {
    "route.source": "AES50A:15",
    "source.name": "KEYS",
    "source.color": "purple",
    "source.icon": "keyboard",
    "source.mode": "stereo"
  }
}

AES50 A15/A16 become left and right. Do not create an additional channel for A16. Stereo and mid-side sources must start on an odd input.

Use "source.target": "AES50A:1" to keep the current channel route unchanged. wing_inspect_channel compares route, strip overrides, source metadata, and effective $name/$col/$icon values. Source writes require /io/in/ in WING_WRITE_PREFIXES.

Hardware-learned horn icon aliases are preserved as functional inputs: Saxophone 312, trombone and bass trombone 313, and trumpet 314. Both English and German aliases are accepted for compatibility.

Additional channel keys include:

  • dca.assignments
  • main.1..4.on|level.db|pre
  • send.bus.1..16.on|level.db|mode|preAlways|pan

The optional console object accepted by wing_apply_plan supports:

  • dca.1..16.name|color|icon|led|mute|fader.db
  • bus.1..16.name|color|icon|mono|mute|fader.db|pan
  • bus.1..16.main.1..4.on|level.db|pre
  • main.1..4.name|color|icon|mono|mute|fader.db|pan

Setting a DCA color automatically enables its scribble-strip LED unless an explicit led value is supplied.

Effects and plug-ins in compact mode

wing_apply_processing accepts desired states instead of OSC addresses. For example, load Room Reverb into FX 8 and insert it post-processing on channel 30:

{
  "items": [{
    "kind": "effect",
    "slot": 8,
    "model": "Room Reverb",
    "mixPercent": 100,
    "parameters": {
      "pre-delay": 25,
      "decay": 1.8,
      "low cut": 120,
      "high cut": 9000
    },
    "insert": {
      "target": "channel",
      "index": 30,
      "position": "post",
      "enabled": true
    }
  }],
  "dryRun": true,
  "confirm": false
}

Channel plug-in example:

{
  "items": [{
    "kind": "plugin",
    "target": "channel",
    "index": 30,
    "section": "filter",
    "model": "AP180",
    "enabled": true,
    "parameters": {
      "frequency": 1200,
      "q": 1.4
    }
  }],
  "dryRun": true,
  "confirm": false
}

Plug-ins support channel filter, gate, EQ, and dynamics sections, plus EQ and dynamics on auxes, buses, mains, and matrices. Premium effects are limited to FX 1-8. FX 9-16 accept standard and channel effects. Existing insert assignments are only replaced when insert.replaceExisting=true.

The generated catalog covers protocol pages 150-180: 34 standard effects, 28 premium effects, 13 channel effects, 4 filter plug-ins, 32 gate/dynamics plug-ins, and 8 EQ plug-ins. Live definitions remain authoritative after every model change.

Compact processing tools:

  • wing_processing_capabilities
  • wing_inspect_processing
  • wing_apply_processing

Read-only and authorized hardware checks:

npm run smoke:processing
WING_LIVE_TEST_CONFIRM=processing-channel-30-roundtrip npm run smoke:processing

I/O routing in compact mode

wing_apply_routing accepts up to 64 semantic routing items:

{
  "items": [
    {
      "kind": "input",
      "target": "channel",
      "index": 30,
      "path": "main",
      "source": "AES50A:30"
    },
    {
      "kind": "output",
      "target": "LOCAL:1",
      "source": "MAIN:1"
    },
    {
      "kind": "source",
      "target": "AES50A:30",
      "set": {
        "name": "ELSE",
        "color": "green",
        "icon": "vocal",
        "phantom": false
      }
    },
    {
      "kind": "user",
      "index": 1,
      "source": "CHANNEL:30",
      "tap": "post",
      "side": "sum"
    }
  ],
  "dryRun": true,
  "confirm": false,
  "response": "summary"
}

User 1-24 are internal User Signals and support tap and left/right/sum. User 25-56 are physical User Patches and intentionally reject those attributes. Output routing requires /io/out/; source and user routing require /io/in/ in WING_WRITE_PREFIXES.

npm run smoke:routing

The routing smoke test is read-only and inspects channel 30, Local Out 1, AES50 A30, one User Signal, and one User Patch.

Strips, monitoring, diagnostics, and media

wing_apply_strips and wing_inspect_strips cover channels, auxes, buses, mains, matrices, DCAs, and mute groups. Friendly aliases cover filters, sidechains, sends, inserts, delays, Automix, solo, and process order. Any other documented leaf can be supplied as a validated relative path.

{
  "items": [{
    "kind": "channel",
    "index": 30,
    "set": {
      "filter.highcut.on": true,
      "filter.highcut.frequency.hz": 16000,
      "send.matrix.1.level.db": -12,
      "automix.weight": 0
    }
  }],
  "dryRun": true,
  "confirm": false
}

wing_monitor_plan controls Monitor A/B, solo preferences, Talkback A/B, Automix X/Y, RTA, and meter taps. Physical Fullsize monitor knobs are read-only and are not forced.

wing_health returns a compact overall status. wing_meter_snapshot reads selected meter groups or the complete console in bounded batches. wing_media_status covers USB Player, USB Recorder, and both W-Live slots. wing_media_control supports transport, sessions, markers, seek, track count, and play mode. Delete and format actions require exact additional confirmation phrases such as DELETE SESSION 4 ON WLIVE 1 or FORMAT WLIVE 2.

npm run smoke:priorities

Permission model

Read-only live access:

WING_NETWORK_ENABLED=true npm start

Native reads and metering:

WING_NETWORK_ENABLED=true \
WING_NATIVE_ENABLED=true \
npm start

Write access for channel 30 only:

WING_NETWORK_ENABLED=true \
WING_WRITE_ENABLED=true \
WING_WRITE_PREFIXES=/ch/30/ \
npm start

Native writes additionally require WING_NATIVE_ENABLED=true, a typed expected value, confirm=true, and an allowlisted path. Native hashes are never accepted as write targets.

Faders accept -144 dB for negative infinity and the continuous range from -90 to +10 dB. Dynamic headamp leaves $g and $vph are allowed only at /ch/1..40/in/set/ and /aux/1..8/in/set/. All other unapproved $ paths remain blocked.

Live writes are restricted to validated leaves under:

/ch /aux /bus /main /mtx /dca /mgrp /fx /io/in /io/out
/cfg /$ctl/cfg /cards/wlive /cards/wmadi /play /rec

Every destination must also match WING_WRITE_PREFIXES. Identity, type, range, enum, precondition, and read-back checks still apply.

File operations

File tools are jailed to WING_FILE_ROOTS. Enable an actual mutation with WING_FILE_WRITE_ENABLED=true, dryRun=false, and confirm=true.

Snapshot inspection and diff are read-only. Snapshot patching only accepts scalar leaves under ae_data, ce_data, ae_globals, ce_globals, or scopes. Replace and remove operations require the exact current value. Writes use a versioned byte-identical backup, same-directory temporary file, fsync, atomic rename, hash verification, and schema revalidation.

wing_snippet_create requires a genuine .snip metadata template and never overwrites an existing path. It maps OSC addresses into the correct data section and calculates num_pars.

Show inspection validates up to 1,000 sequential scenes and their SNAP, SNIP, and WAV references. Show patches support update, move, insert, and remove, require expected target filenames, reindex every scene, and block new broken references.

Tool profiles

The compact profile exposes the 24 high-level tools needed for normal console operation:

  • semantic channel plans, presets, inspection, transactions, and rollback
  • processing capabilities, inspection, and apply
  • routing capabilities, inspection, and apply
  • strip capabilities, inspection, and apply
  • monitor capabilities, inspection, and apply
  • health and metering
  • media status and control

The full profile additionally exposes low-level discovery, OSC, native, events, show-control, snapshot, snippet, and show-file tools. Use it for diagnostics and specialized workflows.

Events and live show control

The WING permits one global OSC subscription; the most recent subscription wins. wing_events_start therefore requires confirmation. The server renews the explicit callback subscription every seven seconds, below the documented ten-second timeout. Multiple MCP clients can read the FIFO buffer with independent sequence cursors.

wing_show_action supports IDLE, GOPREV, GONEXT, GO, PREV, NEXT, and GOTAG. Execution requires all write opt-ins, dryRun=false, confirm=true, exact expected show/scene/index values, OSC read-only mode disabled, and current action IDLE. Preconditions are checked again immediately before sending the action.

Test records

See also IMPLEMENTATION_PLAN.md and FIXTURE_ANALYSIS.md.