Skip to content

MCP Server Overview ​

Control foobar2000 from an AI agent through the Model Context Protocol (MCP). The server registers 11 tools by default: 10 Bridge tools and fb2k_page_inspect. Setting FB2K_ENABLE_EVAL to 1 or true adds fb2k_page_evaluate; setting FB2K_READ_ONLY leaves only the 5 read-only tools.

What is MCP? ​

MCP is an open protocol that lets AI clients such as VS Code, Claude Desktop, and Cursor call external tools through a standard interface. foo-ui-webview2-mcp exposes a controlled part of the foobar2000 Bridge API as MCP tools for playback control, playlist management, library queries, track tags and artwork, and page inspection.

Architecture ​

text
AI agent (VS Code / Claude Desktop / Cursor)
    │  MCP (stdio, JSON-RPC)
    ▼
foo-ui-webview2-mcp (Node.js)
    │  CDP (localhost:9222)
    ▼
WebView2 (running inside foobar2000)
    │  window.fb2k.invoke('namespace.method', params)
    ▼
C++ BridgeCore -> foobar2000 SDK

Data flow ​

  1. The AI agent calls a tool with an action, such as fb2k_playback_control { "action": "playback.play" }.
  2. The server checks the other arguments against the declaration of playback.play and fills in its declared defaults.
  3. The CDP client evaluates window.fb2k.invoke('playback.play', {}) in WebView2.
  4. The C++ Bridge handles the request and returns a JSON-compatible value.
  5. The MCP server returns the result to the client as compact JSON; the cover of artwork.getCurrent or artwork.getForTrack comes with it as an image.

Implementation characteristics ​

CharacteristicBehavior
Pre-connectInitiates a CDP connection on startup; retries on the first tool call if disconnected
Screenshot warm-upEach successful CDP connection performs a best-effort 1×1 PNG capture before real screenshots
Automatic reconnectReconnects automatically with 1 s, 2 s, and 4 s exponential backoff delays
Console recordingBuffers console messages and uncaught exceptions (including pre-existing logs, up to 200)
Rate limitAllows bursts of up to 40 calls, sustained at 20 calls/second
Structured loggingWrites JSON Lines to stderr to keep stdout clear for MCP JSON-RPC traffic

Tools ​

ToolKindScope
fb2k_playback_readread-onlyPlayback state, current track, position, volume, order, and the queue
fb2k_playback_controlchanges stateTransport, seeking, volume, mute, order, and playing a file or playlist row
fb2k_playlist_readread-onlyPlaylists, their tracks, selection, focus, lock and autoplaylist state
fb2k_playlist_managedestructiveCreating, removing, renaming, duplicating and reordering playlists; autoplaylists
fb2k_playlist_editdestructiveAdding, removing, moving, sorting and replacing a playlist's tracks; undo and redo
fb2k_playlist_selectchanges stateThe active playlist, selection and focus
fb2k_library_readread-onlyLibrary search, albums, artists and statistics
fb2k_queue_editdestructiveEvery change to the playback queue
fb2k_track_readread-onlyTags, technical info, ratings and artwork of track files
fb2k_track_writedestructiveWriting tags, ratings and artwork
fb2k_page_inspectread-onlyScreenshot, DOM snapshot and console messages of the page
fb2k_page_evaluatedestructive, conditionalJavaScript in the page, with FB2K_ENABLE_EVAL only

Every action of every tool, with its parameters, is listed on the Tools page.

Relationship to the SDK and Bridge API ​

DimensionMCP toolsSDK (fb.*)Low-level API (fb2k.invoke)
CallerAI agentWeb frontendWeb frontend
Transportstdio + CDPWebView2 postMessageWebView2 postMessage
Typical useAI automation and testingTheme and application developmentDirect Bridge access
Parametersaction plus the method's parametersSDK function argumentsJSON object

Parameters come from the declarations

The Bridge tools are generated from the same host method declarations as the C++ parameter parsers and the SDK types, so an action takes exactly what its method takes. The server checks every argument against the chosen method's declaration, with its ranges, enums, array element types and nested required fields, before the call; an argument the method would refuse comes back as a tool error that lists what the method takes. A few actions are narrower than their methods, for example page sizes capped at 500 rows so one call cannot flood the client's context.

Usage examples ​

Query current playback ​

text
User: What's playing right now?
AI → fb2k_playback_read { action: "playback.getCurrentTrack" }
AI: "Redo" by Mili is playing.

Search and play ​

text
User: Find songs by Mili and play the first result.
AI → fb2k_library_read { action: "library.search", query: "artist IS Mili", limit: 20 }
AI → fb2k_playback_control { action: "playback.playPath", path: "D:\\Music\\Mili\\Redo.flac" }
AI: Started playing "Redo" by Mili.

Verify the UI with a screenshot ​

text
User: Take a screenshot of the current UI.
AI → fb2k_page_inspect { action: "screenshot", fullPage: true }
AI: [shows screenshot] The theme loaded and the playback bar is visible.