MCP server
Connect agents to System Bridge over the Model Context Protocol to query system data and trigger actions.
System Bridge includes a Model Context Protocol (MCP) server, letting agents and other MCP clients query your system and trigger actions.
The primary endpoint uses Streamable HTTP:
http://{host}:9170/api/mcp
Replace {host} with the hostname or IP address of the machine running System Bridge. The port can be changed with the SYSTEM_BRIDGE_PORT environment variable. Use https:// when System Bridge is exposed through SSL configuration or TLS termination.
All connections require your API token. Pass it as a token query parameter:
http://{host}:9170/api/mcp?token=YOUR_TOKEN
Clients that support custom headers can instead send:
Authorization: Bearer YOUR_TOKEN
A missing or invalid token is rejected with 401 Unauthorized. See how to find your token.
Home Assistant
Home Assistant’s Model Context Protocol integration can connect directly to System Bridge. No command or WebSocket bridge is required.
- In Home Assistant, go to Settings > Devices & services.
- Select Add integration, then search for Model Context Protocol.
- Enter the token-bearing Streamable HTTP URL, for example
http://192.168.1.10:9170/api/mcp?token=YOUR_TOKEN. - Complete the setup flow.
- Configure your conversation agent to use the System Bridge MCP tools.
Use a hostname or IP address that Home Assistant can reach. Use https:// if the endpoint is exposed over HTTPS.
Other MCP clients
For a remote MCP client, choose its Streamable HTTP transport and use the token-bearing endpoint:
http://{host}:9170/api/mcp?token=YOUR_TOKEN
Client configuration formats and option names vary. Some clients accept a remote MCP URL directly, while others require a transport type, URL field, or custom Authorization header. Follow the client’s documentation rather than assuming a particular configuration key.
Legacy WebSocket transport
The SDK-backed WebSocket transport remains available at the same path for compatibility:
ws://{host}:9170/api/mcp?token=YOUR_TOKEN
Use wss:// when connecting through TLS. Streamable HTTP is the primary setup for clients that support remote MCP servers.
For a stdio-only client, websocat can bridge the client’s standard input and output to the legacy WebSocket:
websocat "ws://localhost:9170/api/mcp?token=YOUR_TOKEN"
Configure the client to launch websocat with the WebSocket URL as its argument. The exact command and argument fields depend on the client.
Results and Code Mode
Every tool declares an output schema and returns its result as structured content, with the same JSON as text for clients that only read text. Actions return { "success": true, "message": "..." }. system_bridge_list_commands and system_bridge_list_command_prefabs wrap their lists in an object, as commands and prefabs, since structured content has to be an object.
Clients with a Code Mode, such as OpenCode, use the schemas to type each tool, so an agent can chain calls in one script rather than one tool call at a time. For example, with the server named system-bridge:
const sb = tools["system-bridge"]
const { processes } = await sb.system_bridge_get_data({ modules: ["processes"] })
const top = processes.toSorted((a, b) => (b.cpu_usage ?? 0) - (a.cpu_usage ?? 0)).slice(0, 3)
await sb.system_bridge_send_notification({
title: "Busiest processes",
message: top.map((p) => `${p.name}: ${(p.cpu_usage ?? 0).toFixed(1)}%`).join("\n"),
})
Tools
system_bridge_audio_control
Set an audio output’s, input’s or app’s volume or mute state, make an output or input the default, or move an app to another output. See audio control for what each platform supports.
id(required): Anidfrom theaudiomodule’soutputs,inputsorapps.volume(optional): Volume in percent, 0-100.muted(optional):trueto mute it,falseto unmute it.default(optional):trueto make it the default output or input.output(optional): An output’sid, to move an app’s sound to it. Linux only.
Example arguments:
{ "id": "alsa_output.pci-0000_00_1f.3.analog-stereo", "volume": 40 }
system_bridge_bluetooth_connect
Connect a paired Bluetooth device. See Bluetooth control for what each platform supports.
address(required): The device’saddressfrom thebluetoothmodule’sdevices.
system_bridge_bluetooth_disconnect
Disconnect a paired Bluetooth device.
address(required): The device’saddressfrom thebluetoothmodule’sdevices.
system_bridge_bluetooth_forget
Forget a paired Bluetooth device, unpairing it. It has to be paired again before it can connect.
address(required): The device’saddressfrom thebluetoothmodule’sdevices.
system_bridge_bluetooth_set_power
Turn Bluetooth on or off.
powered(required):trueto turn it on,falseto turn it off.
system_bridge_camera_capture
Take a picture with a webcam, returned as an image and as its base64 JPEG. Needs the cameras.capture setting on. See camera capture. Linux only.
id(required): The camera’sidfrom thecamerasmodule.widthandheight: One of the camera’ssizesto take it at, instead of its current size.
system_bridge_camera_control
Set one of a webcam’s controls, such as its brightness or zoom. See camera control. Linux only.
id(required): The camera’sidfrom thecamerasmodule.control(required): The control’sidfrom that camera’scontrols.value(required): A whole number within the control’s range. A boolean’s is0or1, and a menu’s is one of its options’value.
system_bridge_desktop_close_window
Ask a window to close, as its close button does. See desktop control.
id(required): The window’sidfrom thedesktopmodule’swindows.
system_bridge_desktop_focus_window
Focus a window, switching to its workspace.
id(required): The window’sidfrom thedesktopmodule’swindows.
system_bridge_desktop_focus_workspace
Show and focus a workspace. Not available on Windows.
id(required): The workspace’sidfrom thedesktopmodule’sworkspaces.
system_bridge_desktop_set_keyboard_layout
Switch the keyboard to one of its layouts. Not available on Wayland desktops other than Hyprland.
layout(required): One of thedesktopmodule’skeyboard.layouts.
system_bridge_desktop_set_window_state
Make a window fullscreen, maximised or minimised, or not. Set any of them together.
id(required): The window’sidfrom thedesktopmodule’swindows.fullscreen(optional):trueorfalse. Not available on Windows.maximised(optional):trueorfalse.minimised(optional):trueorfalse. Not available on Hyprland.
Example arguments:
{ "id": "0x555dbf21c9e0", "fullscreen": true }
system_bridge_discord_control
Control Discord, which must be set up first. It takes the same actions and fields as Discord control.
action(required): What to do, such asJOIN_VOICE_CHANNEL,TOGGLE_MUTEorPLAY_SOUND.channel_id,user_id,sound_id,device_id,modeandvalue(optional): What the action needs, with ids from thediscordmodule.
Example arguments:
{ "action": "TOGGLE_MUTE" }
system_bridge_display_control
Set a display’s brightness or power state. See display control for what each display supports.
id(required): The display’sidfrom thedisplaysmodule.brightness(optional): Brightness in percent, 0-100.power_state(optional):on,standby,suspendoroff.
Example arguments:
{ "id": "HDMI-A-2", "brightness": 40 }
system_bridge_get_clipboard
Read the text on the clipboard. It takes no arguments. Works on Linux, with wl-clipboard, xclip or xsel, on Windows and on macOS. See clipboard.
system_bridge_get_data
Get current system information from one or more data modules. The tool returns each requested module’s latest data as JSON.
modules(required): An array of module names to fetch.
Available modules:
| Module | Description |
|---|---|
audio |
Output and input devices, their volume, mute state and which are the defaults. |
battery |
Charge level, charging state, and time remaining. |
bluetooth |
Paired Bluetooth devices and whether they’re connected. |
cameras |
Webcams and their settings, such as brightness, zoom and focus. Linux only. |
cpu |
Usage, frequency, core counts, and per-core load. |
desktop |
Open windows, workspaces, the keyboard layout, on Hyprland its displays, input devices, binds and global shortcuts, and the Omarchy shell’s menus and panels. |
disks |
Mounted devices, partitions, and used/free space. |
displays |
Connected displays, resolution, refresh rate, brightness and power state. |
gpus |
GPU model, load, memory, and temperature. |
media |
Currently playing media: title, artist, and playback state. |
memory |
Physical and virtual memory usage. |
networks |
Network interfaces, addresses, and throughput. |
processes |
Running processes with CPU and memory usage. |
sensors |
Hardware sensors such as temperatures and fan speeds. |
system |
Hostname, OS, uptime, users, and version details. |
Example arguments:
{ "modules": ["cpu", "memory", "battery"] }
system_bridge_get_history
Get the recent readings System Bridge keeps for its charts, the same as the GET_HISTORY event. Each series is a list of { "time", "value" } samples, with time in Unix milliseconds.
since(optional): Only readings after this time, in Unix milliseconds. Omit it for the whole history.modules(optional): Only these modules’ readings:battery,cpu,disks,gpus,memory,networks,sensorsorsystem. Omit it for every module.
Example arguments:
{ "since": 1792857600000, "modules": ["cpu", "memory"] }
system_bridge_hyprland_dispatch
Run a dispatcher on the focused window on Hyprland, or another window after focusing it, as its bind would. See Hyprland control for what each does.
dispatcher(required):center_window,cycle_next_window,cycle_previous_window,group_next,group_previous,lock_group,lock_groups,move_focus,swap_window,toggle_group,toggle_split,unlock_grouporunlock_groups.direction(optional):down,left,rightorup. Needed formove_focusandswap_window.id(optional): Theidof a window from thedesktopmodule’swindowsto focus first.
system_bridge_hyprland_move_window
Move a window to another workspace on Hyprland, leaving the focus where it is. See Hyprland control.
id(required): The window’sidfrom thedesktopmodule’swindows.workspace(required): The workspace to move it to.
system_bridge_hyprland_move_workspace
Move a workspace to another display on Hyprland.
id(required): The workspace’sidfrom thedesktopmodule’sworkspaces.display(required): The display’sidfrom thedisplaysmodule.
system_bridge_hyprland_reload_config
Reload Hyprland’s config. It takes no arguments.
system_bridge_hyprland_rename_workspace
Rename a workspace on Hyprland.
id(required): The workspace’sidfrom thedesktopmodule’sworkspaces.name(optional): The new name. Leave it out to give the workspace back its default name.
system_bridge_hyprland_run_global_shortcut
Trigger a global shortcut an app registered with Hyprland, such as one that opens a panel.
name(required): Anamefrom thedesktopmodule’shyprland.global_shortcuts.
system_bridge_hyprland_set_option
Set any Hyprland config option, such as turning animations off, until the config reloads. Read its type first with system_bridge_hyprland_get_option. See options for the values each type takes.
name(required): The option, such asanimations.enabledorgeneral:layout.value(required):trueorfalse, a number, text, or two numbers as[5, 10], by the option’s type. The options in thedesktopmodule’shyprland.optionsonly take a number of 0 or more.
system_bridge_hyprland_get_option
Read any Hyprland config option: its type, its value, and whether the config sets it rather than leaving the default.
name(required): The option, such asgeneral.col.active_borderorgeneral:layout.
system_bridge_hyprland_get_cursor_position
Get where the pointer is on Hyprland, in pixels across every display. It takes no arguments.
system_bridge_hyprland_move_cursor
Move the pointer on Hyprland.
xandy(required): Where to put it, in pixels across every display.
system_bridge_hyprland_get_log
Get the end of Hyprland’s log, oldest line first. It takes no arguments.
system_bridge_hyprland_send_event
Send a custom Hyprland event, as a bind to the event dispatcher would. Listeners get it as a Hyprland event.
name(required): The event’s text.
system_bridge_hyprland_exec
Run a command through Hyprland, in its environment. Needs the desktop.hyprlandCode setting on. See running code.
command(required): The command line, such askitty --class scratch.
system_bridge_hyprland_dispatch_raw
Run any Hyprland dispatch, written as the running config takes it: Lua when the desktop module’s hyprland.version.config_provider is lua, otherwise classic. Needs the desktop.hyprlandCode setting on.
dispatch(required): The dispatch, such ashl.dsp.focus({ workspace = "2" })orworkspace 2.
system_bridge_hyprland_eval
Run one line of Lua in Hyprland, with a Lua config. Hyprland only replies whether it ran. Needs the desktop.hyprlandCode setting on.
code(required): The Lua.
system_bridge_hyprland_set_submap
Switch Hyprland’s binds to a submap, such as a resize mode, or back to the default.
name(optional): A submap one of thedesktopmodule’shyprland.bindsis in. Leave it out for the default.
system_bridge_hyprland_set_window
Float or tile a window on Hyprland, pin or unpin it, and move or resize it. Pinning a tiled window floats it first.
id(required): The window’sidfrom thedesktopmodule’swindows.floating(optional):trueto float the window,falseto tile it.pinned(optional):trueto show it on every workspace,falseto unpin it.xandy(optional, together): Where to put the window’s top-left corner, in pixels across every display.widthandheight(optional, together): The window’s size in pixels.
system_bridge_hyprland_kill_window
Kill a window’s app on Hyprland without asking it to close, so anything unsaved is lost. system_bridge_desktop_close_window asks it to close instead.
id(required): The window’sidfrom thedesktopmodule’swindows.
system_bridge_keyboard_keypress
Press a key in whichever window has focus. See keyboard keypress.
key(required): The key to press, such asa,enterorspace.modifiers(optional): Keys to hold while pressing it:shift,ctrl,altorcmd.delay(optional): Milliseconds to wait first.
system_bridge_keyboard_text
Type text in whichever window has focus. See keyboard text.
text(required): The text to type.delay(optional): Milliseconds to wait first.
system_bridge_kill_process
End a process. See process control.
id(required): The process’sidfrom theprocessesmodule.force(optional):trueto end it straight away rather than asking it to stop, losing anything unsaved.
system_bridge_list_command_prefabs
List the prefab commands, with whether each can run on this system, what it would run, and why not. It takes no arguments. An assistant can’t add them: a prefab only runs once you add it to your commands.
system_bridge_list_commands
List the commands you’ve allowed System Bridge to run, with each one’s id, name, command, arguments, workingDir and prefab. It takes no arguments.
system_bridge_lock
Lock the screen. It takes no arguments.
system_bridge_media_control
Control playback of the system’s current media session, or another player.
action(required): The action to perform. Must be uppercase.player: A player’sidfrom themediamodule’splayers. Leave it out for the player the module reports.position: Seconds from the start of the track, forSEEK.volume: 0-1, forSET_VOLUME.shuffle:trueorfalse, forSET_SHUFFLE.repeat:NONE,TRACKorLIST, forSET_REPEAT.
Available actions:
| Action | Effect |
|---|---|
MUTE |
Toggle mute. |
NEXT |
Skip to the next track. |
PAUSE |
Pause playback. |
PLAY |
Resume playback. |
PREVIOUS |
Return to the previous track. |
STOP |
Stop playback. |
VOLUME_DOWN |
Lower the volume. |
VOLUME_UP |
Raise the volume. |
SEEK |
Move to position. |
SET_VOLUME |
Set the player’s volume to volume. |
SET_SHUFFLE |
Turn shuffle on or off. |
SET_REPEAT |
Set what repeats. |
On Windows, only the actions up to VOLUME_UP work, and not with player.
Example arguments:
{ "action": "PAUSE" }
{ "action": "SEEK", "player": "vlc", "position": 90 }
system_bridge_omarchy_menu
Open, close or toggle the Omarchy menu at one of its routes, while the Omarchy shell runs. See Omarchy control.
action(required):open,closeortoggle.id(optional): A menuidor one of itsaliasesfrom thedesktopmodule’somarchy.menus, such asroot. Not needed to close the menu.
system_bridge_omarchy_panel
Open, close or toggle a panel or overlay of an Omarchy shell plugin.
action(required):open,closeortoggle.id(required): A panelidfrom thedesktopmodule’somarchy.panels, such asomarchy.audio.
system_bridge_open
Open a URL in the default browser, or a file or folder with its default app. See open a path.
url(optional): A URL to open.path(optional): A file or folder to open.
Give one of them.
system_bridge_run_command
Run a command from the allowlist and wait for it to finish. It returns the command’s exitCode, stdout and stderr, and error when it couldn’t run or timed out. Commands time out after 5 minutes.
id(required): The command’sidfromsystem_bridge_list_commands.
Example arguments:
{ "id": "backup" }
Only commands in the allowlist can run. Power actions such as shutdown and restart aren’t available as tools, so an assistant can’t trigger them by mistake. Locking is, with system_bridge_lock, as it loses nothing.
system_bridge_send_notification
Send a desktop notification to the machine running System Bridge.
title(required): The notification title.message(required): The notification body text.icon(optional): An icon name to display with the notification.urgency(optional):low,normalorcritical. Critical notifications stay until dismissed. Linux only.
Example arguments:
{ "title": "Build finished", "message": "All tests passed", "icon": "dialog-information" }
system_bridge_set_clipboard
Put text on the clipboard, ready to paste. Linux only, with wl-clipboard, xclip or xsel. See clipboard.
text(required): The text to put on the clipboard.
system_bridge_set_power_profile
Switch the power profile. Linux with power-profiles-daemon or tuned-ppd only. See system control.
profile(required): One of thesystemmodule’spower_profiles, such aspower-saver,balancedorperformance.
system_bridge_set_keep_awake
Keep the system from idling, so it doesn’t lock, blank the screen or sleep for being left alone, or let it idle again. On Omarchy this is the bar’s stay awake switch. Linux only.
enabled(required):trueto keep it awake,falseto let it idle.duration(optional): Seconds until it may idle again.
Troubleshooting
Connection refused
- Confirm System Bridge is running. See Running.
- Check the port (default
9170) andSYSTEM_BRIDGE_PORTif you changed it. - Verify the host in your config matches the machine running the backend.
- Confirm the client uses Streamable HTTP unless it explicitly needs the legacy WebSocket transport.
Unauthorized (401)
- The token is missing or incorrect. Run
system-bridge client tokenon the host running the backend. - Pass the token as a
tokenquery parameter orAuthorization: Bearer {token}header.
Tool execution fails
- Check backend logs for the underlying error.
- For
system_bridge_get_data, use valid module names (see the table above). - For
system_bridge_media_control, actions must be uppercase (PLAY,PAUSE, and so on). - For
system_bridge_run_command, theidmust be in the allowlist. Get the ids fromsystem_bridge_list_commands.