OBS MCP
Provides tools for interacting with OBS Studio through its WebSocket v5 interface, enabling management of scenes, sources, audio, transitions, filters, recording, streaming, canvas, profiles, and other OBS functionality.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@OBS MCP check the OBS connection and report the current scene and stream status"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
OBS MCP
OBS MCP helps agents and operators inspect OBS Studio, plan scene changes, and supervise recordings. Preview a change before taking it to program, watch a bounded take as it records, and retain operation receipts when a command's outcome needs review.
Start with obs-observe, resolve a layout with obs-plan-scene-template, then stage and inspect the preview before calling obs-take-scene. The observation tool and obs://status resource share their consistency checks and missing-evidence contract. See production workflows and Linux support for examples, platform boundaries, and verification limits.
The server uses MCP 2026-07-28 and accepts legacy 2025-era clients. Tool discovery remains available while OBS is closed.
Native runtime and qualification
The executable runs the retained Rust service directly over stdio or loopback HTTP. The native MCPB layout contains no Node runtime, JavaScript SDK or TypeScript server payload. TypeScript remains a development oracle.
Production is the default immutable profile and exposes up to 165 ordinary tools with approved host/media adapters. Advanced exposes 163 and excludes guarded Take, media, Stage and recovery owners. Their union contains 179 ordinary names; stdio dynamic mode can add three group controllers. Filters, read-only mode and available adapters narrow discovery. See native profiles.
Core checkpoint d3bb516 (PRs #26 and #27) passed ten CI jobs. Its physical-Mac qualification passed 736 Source unit cases, 21 Source transport cases, 1,050 default-feature Rust cases, 214 all-feature bin/library cases, four resolver process contracts, seven component checks and 1,016 public cases with no skips. The public suite includes 17 actual HTTP-entry and 58 TCP cases. These suites overlap; their counts are not a unique-test total.
The matching extracted Mac MCPB passed three package checks and the bounded OBS 32.2.2 fixture journey. Its 2.837-second silent A/B clip passed strict decoding, sampled content and exact presented-frame cadence checks. Conflict-preserving recovery, manual Restore and an offline snapshot restart passed; the original, restored and final state snapshots were byte-identical and all owned helpers closed. The fractional-FPS export correction is merged.
A separate tester ran focused cadence, HTTP, raw stdio and method-header checks on the exact Linux main executable. That VM had no Source oracle or package qualification; Linux CI has separate results. Real XComposite capture remains unqualified because the software display lacks EGL_KHR_image_pixmap; an XShm whole-display control does not establish exact-window capture.
Default TLS remains off. The opt-in TLS evaluation passed seven optimized/extracted Mac read-only WSS cases against actual OBS through an owned proxy, including DNS/IP custom-CA TLS1.2/1.3 and early trust refusals. Its qualification is separate from the core checkpoint and does not establish general production TLS admission. Cutover status binds both compositions to exact artifacts and limits; native distribution gives normal setup and the explicit evaluation pack command. Each delivered archive needs its own source and artifact binding; installed-client activation remains separate.
Related MCP server: obs-mcp-server
How it works
MCP clients <-- stdio or loopback HTTP --> Rust OBS MCP <-- WebSocket v5 --> OBS StudioOBS MCP runs as a separate MCP server process using the native executable. It does not patch OBS or require an OBS plugin; it uses the WebSocket server built into OBS Studio. MCP handles tool discovery, schemas, results, and approval hints. OBS WebSocket handles the live application state.
What is covered
The 179-name ordinary catalog spans both profiles; it is not a promise of 179 simultaneous tools in one process.
Descriptions for all 147 request types in the pinned OBS WebSocket protocol; profile policy controls dispatch
Explicit read-only, destructive, idempotent, and open-world annotations on every tool
Runtime capability checks against the requests advertised by the connected OBS instance
Structured MCP results for automation, with readable text retained for people and older clients
Source screenshots returned as MCP image content instead of clipped base64 text
Protocol inspection through
obs-describe-requestAdvanced-profile raw, batch, vendor and hotkey tools with explicit policy and durable guarded-reentry barriers
A host-specific
.mcpbbuilt from checked native assets and corresponding Rust source, with profile-conditional inventory
Use the explicit tools for normal workflows. Advanced raw tools accept the bundled request names and retain destructive/open-world policy even when a wrapped request is a read. They do not borrow Production Take, Stop, file or recovery authority.
Requirements
A qualified native executable for your host (or the pinned Rust toolchain to build it)
An existing approved private state directory; optional recording root and trusted FFmpeg/ffprobe for local media workflows
OBS Studio 28 or newer with the WebSocket server enabled
An MCP client that supports MCP 2026-07-28 or the compatible legacy protocol
OBS includes WebSocket v5. Enable it under Tools > WebSocket Server Settings. Newer OBS requests are available only when the connected version advertises them; unsupported calls return a descriptive error.
Install from source
Build the runtime directly from its checked native inputs; Node and a TypeScript build are unnecessary:
cd native
RUSTUP_AUTO_INSTALL=0 cargo build --locked --offline --release --bin obs-mcp-nativeThe pinned toolchain and Cargo sources must already be available. A missing
cache is an explicit prerequisite, not permission for an automatic fetch.
Create and approve a safe state directory inside your chosen project, then
configure the absolute native executable and OBS_MCP_STATE_DIR in your MCP
client. Native distribution gives the complete
setup, optional recording/media paths and immutable profile behavior. No home
directory is initialized or history erased as part of source qualification.
Verify the connection
Open OBS, start a new agent session, and ask:
Check the OBS connection. Report the OBS version, current scene, stream status, and recording status. Do not change anything.
The client should request only read-only tools and return live values from OBS. If discovery works while OBS is closed, start OBS and request the read-only connection check again. Native operation history never authorizes automatic mutation replay; a lost owned session may require a fresh MCP process while retained unknown effects remain refused.
Install the MCPB package
With the explicit development archive tools installed, node scripts/pack.mjs
builds dist/obs-studio-native.mcpb for the build host. It compiles from checked
native assets, keeps corresponding Rust source/configuration and notices, and
uses no staging dependency install or Source server build. Node/MCPB CLI are
development packaging tools; the installed extension contains no Node, JavaScript
SDK or server payload.
The MCPB setup requires an existing approved private state directory and exposes profile and optional recording/media paths. Discovery works while OBS is offline after valid local startup. The 2 November macOS candidate passed extraction and a bounded live journey; a changed artifact or another platform needs its own checks. Package contents alone prove neither production TLS nor Linux desktop support. See native distribution.
Configuration
Variable | Required | Default | Purpose |
| No |
| Address of the OBS WebSocket server |
| Only when OBS authentication is enabled | None | Password configured in OBS |
| No |
| When |
| No |
| Maximum decoded size of a screenshot returned through MCP; the hard ceiling is 6 MiB |
| No | all tools | Comma-separated tool groups to register: |
| No | none | Comma-separated tool names to register in addition to |
| No |
| Register only read-only tools; overrides both lists |
| No |
| Start with only the |
| No |
| Ask before starting a stream/output or stopping or toggling a stream, recording, or output (see Confirming live actions) |
| No | none (stdio) | Serve MCP over Streamable HTTP at |
| No | none | With |
| An existing approved namespace is required | Prefer an explicit canonical path | Endpoint-bound snapshots, recovery journals and receipts; startup does not create an unsolicited namespace or clear history |
| No |
| Immutable |
| For Production recording/file workflows | None | Existing approved recording directory; does not grant recording or file authority |
| For media workflows | Trusted executable on PATH | Explicit existing media-tool bindings; the package installs neither |
| TLS evaluation build | None | Optional absolute safe certificate-only PEM file adding process-local trust anchors; requires the feature-on evaluation build |
Passwords and HTTP tokens are not printed. Stdio reserves stdout for MCP; HTTP keeps it empty and announces its loopback endpoint on stderr. Default builds refuse encrypted wss: OBS endpoints before connection. Conditional macOS Network.framework and Linux GnuTLS backends remain behind platform-tls-evaluation; see transport status.
Tool surface
The profile-conditional tool catalog covers:
server status, version information, statistics, hotkeys, and studio mode
scenes, groups, sources, filters, and scene items
input settings, audio tracks, volume, mute state, media controls, and deinterlacing
recording, streaming, replay buffer, virtual camera, and output settings
transitions, transition overrides, the transition cursor, and the T-Bar
canvases, screenshots, profiles, scene collections, and persistent data
a recording preflight (
obs-preflight) that catches the conditions under which OBS silently refuses or botches a recordingobs-audit-scene, which inspects one selected scene for missing or hidden required items, incomplete observations, and structural problems without changing OBSobs-record-clip, which preflights, records up to 50 seconds with chapter markers, stops, and checks the file's length and audio with ffprobe/ffmpeg when they are installed. While it records, it watches the take (see Watching a take)obs-take-start,obs-take-mark,obs-take-status, andobs-take-stopfor watched recordings, with chapters and duration policy (see Watching a take)obs-trim-take, which cuts dead time out of a recording, andobs-contact-sheet, which tiles frames from it into one image (see Trimming a take)obs-apply-scene, which takes a description of a scene and makes OBS match it (see Describing a scene)obs-snapshotandobs-restore, which save the state of inputs and scene items and later undo changes to them (see Undoing changes)obs-capture-window, which plans or selects macOS or Linux X11 windows from an existing capture inventory, or fits an existing user-authorized Wayland portal captureinput and transform changes that return the resulting settings, size, and an optional screenshot, warning when a source renders at 0×0
protocol description and Advanced raw/batch tools, which send several requests in one message, in order or one per rendered frame (so a change to two sources lands on the same frame), with
Sleepbetween them. OBS's parallel mode is not offered: in obs-websocket 5.7, concurrent parallel batches deadlock its WebSocket server until OBS restarts
Tools that send a single OBS request declare an outputSchema generated from the pinned protocol, so clients receive typed structuredContent with the documented response fields. Fields are optional and nullable because OBS omits newer fields in older versions and returns undocumented nulls.
Tool discovery works without an OBS connection. Calls that need OBS return an MCP error until the WebSocket connection is ready.
Choosing tools
Every available tool in the selected profile is registered by default. Clients load these definitions into the model's context, so a smaller set is cheaper and easier to choose from. Filters cannot enable a tool excluded by its profile or missing adapter.
Group | Covers |
| status, version, statistics, hotkeys, vendor requests, custom events, sleep, control of a shared server |
| scenes, canvases, program and preview scene, |
| scene items, groups, transforms, ordering, locking, blend modes, |
| source screenshots and active state |
| inputs, input settings and properties, audio, deinterlacing, and |
| media input playback |
| source filters |
| transitions, overrides, the T-Bar |
| recording, chapters, |
| streaming and captions |
| virtual camera, replay buffer, and generic outputs |
| profiles, scene collections, video settings, persistent data |
| studio mode, dialogs, projectors |
|
|
core expands to general, scenes, scene-items, sources, inputs, and record. Add OBS_MCP_READ_ONLY=true for inspection-only discovery. Counts depend on profile and adapters. Unknown groups or names refuse at startup.
With OBS_MCP_DYNAMIC_TOOLSETS=true, every group is registered but only the groups in OBS_MCP_TOOLSETS (by default just general) and the tools in OBS_MCP_TOOLS start enabled. Three more tools manage the rest: obs-list-toolsets shows each group and how many of its tools are on, and obs-enable-toolset and obs-disable-toolset switch groups for the session. Each change sends notifications/tools/list_changed, so clients that support it (Claude Code, VS Code, Cursor) reload the list. Read-only mode still applies: enabling a group adds only its read-only tools.
Resources and prompts
Resources give clients that support them a live view without tool calls. Each one duplicates a read-only tool, since many clients read resources rarely or not at all.
URI | Contents | Updated on |
| connection, recording, streaming, program scene | output and scene changes |
|
| scenes added, removed, renamed, or switched |
|
| items added, removed, reordered, shown, hidden, locked |
| 960px JPEG of the scene | (read on demand) |
| the running take: audio levels, skipped frames, black or unchanging picture, chapters, warnings | a warning or chapter |
Legacy stdio clients receive updates for subscribed URIs; modern clients choose updates on their subscriptions/listen stream. Legacy HTTP requests do not retain initialize offers or subscription state as authority for later exchanges.
Three prompts appear as slash commands in clients that show MCP prompts: record-demo (capture a window silently, preflight, record a clip), software-demo (the bounded demo recipe below), and pre-stream-check (a read-only go/no-go review).
Confirming live actions
With OBS_MCP_CONFIRM_LIVE=true, obs-start-stream, generic StartStream/StartOutput requests, obs-stop-stream, obs-toggle-stream, obs-stop-record, obs-toggle-record, obs-take-stop, obs-stop-output, and obs-toggle-output ask before they run, as do obs-call-request and obs-batch when they carry one of those requests. The generic output tools are included because the stream and the recording are outputs too. Clients that support elicitation (Claude Code, VS Code, Cursor) show the user a confirmation, and confirm: true from the model does not skip it. Other clients get an error asking the model to get the user's agreement and call again with confirm: true. These tools are also marked destructive, so clients that ask before destructive tools already prompt without this setting.
Confirmation never enables a profile-excluded tool or bypasses a durable barrier. Native grants are single-use and bound to the caller and original request; re-enabling a hidden tool cannot revive a consumed grant.
Where it fits
OBS MCP is well suited to operational work that already has a clear outcome: inspecting a scene collection, creating or arranging sources, changing audio state, switching scenes, taking screenshots, checking output status, or carrying out a repeatable recording setup.
It does not replace visual or editorial judgment. Framing, color, transition timing, audio balance, and the decision to go live still need a person watching and listening to the result.
Safety and approvals
Every tool publishes all four MCP behavior hints. Read-only inspection is separated from state changes, and actions with broader consequences are marked destructive or open-world as appropriate.
Get explicit user permission before capture, recording, streaming, file publication or destructive changes. Keep qualification bounded to an approved collection and fixture. Tool hints and a successful preflight are not permission. Pay particular attention to tools that:
start or stop streaming, recording, virtual camera, replay buffer, or another output
switch profiles or scene collections
trigger hotkeys or interact with OBS UI elements
invoke vendor requests
save files or use Advanced
obs-call-request
In Advanced, obs-call-request and obs-batch accept only request types in the bundled OBS protocol, but their payloads are intentionally generic. With OBS_MCP_CONFIRM_LIVE=true, they ask before sending StartStream, StartOutput, StopStream, ToggleStream, StopRecord, ToggleRecord, StopOutput, or ToggleOutput. Both are always advertised as destructive and open-world so a client does not silently treat an unfamiliar operation as safe.
Watching a take
obs-record-clip records up to 50 seconds in one call. For anything longer, or a demo whose steps happen while it records, use a take:
obs-take-startruns the preflight, starts recording, and waits for OBS to confirm. Only one take runs at a time.obs-take-markadds a named chapter before each step, both in the file (Hybrid MP4/MOV) and in the take log.obs-take-statusreports what the take has seen so far.obs-take-stopstops recording, checks the file, and reports.
While a locked take records, profile, collection and output-setting changes refuse. Use the owned Take Stop for that recording. Explicit Stop admission is separately bounded; unavailable storage or uncertain ownership can still refuse it. lock: false changes the take lock, not immutable profile rules or durable barriers. Advanced raw/batch tools cannot be used to bypass those rules in a guarded Production process.
While a take records, the server watches OBS instead of waiting for the file:
Audio: it subscribes to OBS's
InputVolumeMetersevents for the length of the take and records each input's loudest level after volume and mute. An input on a recorded track that rises above −60 dBFS is logged, and withexpectSilentit is a problem. Muted inputs and inputs on unrecorded tracks are not.Frames: it polls
GetStatsevery 2 seconds and warns when OBS misses frames rendering or the encoder skips them.Picture: once a second it takes a 96-pixel-wide PPM screenshot of the program scene. Two black samples in a row raise a warning (a capture that lost its window or permission looks like this). Stretches of 3 seconds or more where the picture holds still are recorded as stills, which mark dead time to trim. A spinner or a shimmering "thinking" label counts as still; text that appears and stays does not (see below).
The result lists the findings, and when OBS records to this machine the server writes them next to the recording as <name>.take.json, with chapter times and OBS events (scene switches, mutes, output state) in seconds from the start. obs://take/current shows the same data while the take runs.
Bounded software demos
The software-demo MCP prompt and obs-demo agent skill use the version 1 recipe. The skill remains in the development checkout and native MCPB source bundle. Open this checkout in your agent host and explicitly load the linked skill, or request the software-demo prompt through MCP. Merely installing an MCPB does not install a skill into every host. Automatic host discovery and real rendered OBS output have not been qualified by the hermetic checks.
V1 uses local OBS on macOS or Linux, an existing current scene, and one enabled, preconfigured window capture. Linux supports XComposite on X11 and an existing portal-authorized PipeWire capture on Wayland. A portal selection still needs visual inspection for window identity. Video-only Linux capture sources have no mute or audio tracks to change; preflight checks the complete recording audio path. The capture must appear exactly once in a collection without groups or nested scenes. The tools require stable OBS object identifiers and complete state; they refuse unsupported setups rather than create or retarget sources. Streaming, recording, virtual camera, replay buffer, and every listed generic output must be inactive during preparation and recovery. Missing or failed output status blocks the operation. OBS code 604 explicitly reporting an unavailable virtual camera or replay buffer is accepted as an unavailable feature; named output statuses must still establish inactivity.
Plan with
obs-prepare-demoand exactsceneCollection,sceneName, andinputName. After authorization, repeat withapply: true. It mutes the capture, clears its audio tracks, fits it to the canvas, and returns anoperationIdwhen changes require recovery.Inspect a screenshot for the intended window and framing. Run silent preflight and require every check named in the recipe to pass. A required unknown or missing check blocks this workflow.
Start a take with
maxDurationSeconds(120 by default in the prompt, at most 3600), mark steps, and stop it when finished. The server attempts to stop its own take at the deadline and retains the result forobs-take-stopto read. The deadline requires a running server; process death and sleep prevent an unattended cleanup guarantee.Inspect the final file and contact sheet. Chapters may be in the
.take.jsonsidecar. After trimming, verify the exported copy and its remapped chapters. Use the local verifier below to bind measurements to the delivered file hash.Plan
obs-recover-demowith the retainedoperationId; apply recovery when requested. It restores only the preparation's changed fields after checking collection/object identity and expected values. A conflict stops recovery. It does not lock OBS's UI or other processes; incomplete recovery needs operator inspection. Existingobs-restoreremains a manual tool for legacy snapshots.
node scripts/verify-demo.mjs --file /path/demo.mp4 --reference /path/expected.png --seconds 30 --chapter Intro --checkpoint 10=/path/step-two.png --report /path/demo.verification.jsonThe verifier uses local ffmpeg and ffprobe; it never contacts OBS. It reports strict full-file decoding separately from metadata and sampled pictures. A decode timeout is unavailable evidence. It checks duration within 2 seconds, a video stream, every audio track at or below -60 dB, requested chapters, and reference frames scaled to 160×90 grayscale (mean absolute error at most 12). These frame comparisons test selected checkpoints, not semantic recognition or every frame. Use reference images from the intended scene. Missing tools or evidence produce unavailable; failed requirements produce fail. The report must be a new file. Synthetic-media tests cover the verifier; a real recording still needs visual review.
Trimming a take
obs-trim-take finds dead time: stretches where the picture holds still (and, if the recording has sound, where it is also silent). It samples the video twice a second at 96 pixels wide and looks for steps: pixels whose median over the three samples before a moment differs from their median over the three after it. Text that appears and stays is a step. A spinner, a shimmering "thinking" label, or a blinking cursor comes and goes, so waiting on one still counts as dead time. On a 1080p ChatGPT recording, this separated waiting from streaming answers where ffmpeg's freezedetect could not with any single noise threshold.
By default, a still stretch of 4 seconds or more loses its middle, keeping 1 second at each side. Nothing is cut from 3 seconds before to 1.5 seconds after each chapter start, or in the last 3 seconds, so each step's finished result stays on screen long enough to read. Chapters come from the file, or from the take log when the file has none, and are moved to their new times.
Without apply: true it returns only the plan: the cuts, the new length, and the new chapter times. With it, the tool validates a staged copy before publishing <name>.trimmed.mp4 next to the original. Validation checks the planned duration, video dimensions, audio stream count, remapped chapters, and strict full-file decoding. Publication refuses an existing destination. Cancellation before publication discards the staged copy; after publication, optional contact-sheet failure retains the output path and SHA-256 in the result.
Exports retain the first audio track and use H.264 with yuv420p. Other audio tracks are omitted; choose a separate workflow when they must remain independent. High bit depth and explicitly tagged PQ/HLG HDR inputs are refused; no implicit tone mapping occurs. Missing color tags remain unknown, so a successful export does not establish color fidelity. The contact sheet shows frames on either side of each seam for review.
obs-contact-sheet tiles frames from a recording into one JPEG: one second after each chapter start by default, or at the times you give. Both tools work only on files inside OBS's recording directory, and need ffmpeg and ffprobe on PATH.
Auditing a scene
obs-audit-scene reads one scene in the current collection without changing OBS. The selected scene can be off program. It is available in the scenes group and in read-only mode:
{
"sceneCollection": "Demo collection",
"sceneName": "Demo",
"requiredItems": [{ "sourceName": "Application" }],
"includeScreenshot": false
}For a secondary canvas, add canvasUuid from obs-get-canvas-list. The audit uses that canvas for scene discovery, item and group reads, transform rereads, and the optional screenshot. Omitting it keeps OBS's default-canvas behavior. The report includes the supplied canvas UUID in its target.
The report lists individual source occurrences with their container, source UUID, scene-item ID, and containment path. A required source that is missing or hidden fails its check. Repeated occurrences need a more specific selector: add sourceUuid, containerUuid, or sceneItemId to the required item. Ambiguous selectors remain unknown.
Checks report pass, fail, or unknown, with observation times and evidence. Missing fields, unreadable state, cycles, traversal limits, unsupported geometry, or detected changes during collection make the affected evidence unknown. Nested scene and group membership can be inspected, but composed geometry is not qualified. The report covers a sampling interval; it is not an atomic snapshot or a promise that OBS will stay unchanged.
Zero-size media sources remain unknown: a filename extension does not prove that a file has no video. Inputs whose source kind establishes audio-only capture are exempt from visual dimension checks.
Set includeScreenshot: true to request a bounded scene image for inspection. An unavailable image is reported as unknown. The tool does not save screenshots or reports to disk. A structural pass leaves renderedContent as unverified: it does not establish the intended capture content, readability, freedom from occlusion, audio policy, or readiness to record. Continue to use the recording preflight and inspect the rendered picture separately.
Describing a scene
obs-apply-scene takes the scene you want instead of the steps to build it:
{
"sceneName": "Review",
"sources": [
{ "name": "Background", "kind": "color_source_v3", "settings": { "color": 4278190080 }, "locked": true },
{ "name": "ChatGPT Window", "kind": "screen_capture", "settings": { "type": 1 }, "muted": true, "audioTracks": [], "fit": "canvas" }
],
"order": true,
"apply": true
}Sources are listed back to front. The tool reuses existing inputs (including ones shown in other scenes), creates missing scenes, inputs, and items, and changes only the settings, visibility, lock, mute, volume, audio tracks, transforms, and order that differ. fit: "canvas" scales a source to fit the canvas, centered. removeOthers: true removes unlisted items from the scene; their inputs remain.
Without apply: true it returns the plan. When applying, it creates what is missing in one request batch, then plans again with the new items' IDs and makes the remaining changes in a second. It then plans a third time to confirm OBS matches, and warns about any listed source that renders at 0×0. For an existing scene it first saves a snapshot, so obs-restore can undo the changes to existing sources.
Undoing changes
obs-snapshot saves the settings, mute, volume, and audio tracks of inputs, and the transform, visibility, lock, and order of scene items: by default the program scene and the inputs in it. obs-restore compares OBS with a snapshot and sends only what differs, in one request batch; dryRun: true lists the changes first. It cannot recreate a removed input or item, and leaves items added since in place; it reports both. obs-capture-window takes a snapshot automatically before it changes an existing capture.
Snapshots are saved in the server's state directory (the last 20 you take, plus the last 10 taken automatically before a change, readable only by you), so obs-restore works after a restart and from another agent's session. Each server lists only the snapshots of the OBS instance it connects to. They contain input settings, such as file paths and browser source URLs. OBS's own scene collection file is not a substitute: OBS rewrites it while running.
Sharing one server
By default, each stdio client starts its own server and OBS owner. To share one retained service, start the native executable in HTTP mode:
OBS_MCP_STATE_DIR=/absolute/canonical/approved-state \
OBS_MCP_HTTP_PORT=8765 \
native/target/release/obs-mcp-native
# Point each MCP client at http://127.0.0.1:8765/mcp?client=its-nameThe server binds only to 127.0.0.1 and checks Host and Origin headers. Set an opaque OBS_MCP_HTTP_TOKEN through approved secret configuration to require bearer authentication; without it, local programs can reach the server. HTTP uses static tool groups and ignores OBS_MCP_DYNAMIC_TOOLSETS.
The port accepts trimmed decimal digits from 0 through 65535, including leading zeros. 0 chooses a free port. An absent, empty or JavaScript-whitespace-only value selects stdio; signed, fractional, exponent and hexadecimal forms refuse. HTTP ignores stdin EOF and joins its service and drivers on SIGINT or SIGTERM. Closing one client does not shut down peer work or a Take.
While agents share a server, obs-claim-control gives one of them control of OBS for a set time (30 minutes by default). Until it calls obs-release-control or the time runs out, tools that change OBS refuse calls from other clients. Read-only inspection and explicitly admitted Stop routes retain their own policy and capacity limits. obs-control-status shows who holds control. obs-take-start claims control for the length of the take. Clients are told apart by name: the client parameter of the URL they connect with, or else the name a 2026-07-28 client sends with each request. Clients using the 2025 protocol over HTTP send each request without a name, so give each agent its own ?client= name. An unnamed client cannot claim control and is refused while another client holds it. Two agents given the same name share control. The names are not credentials; control is for agents cooperating on one machine, not for keeping out someone who can reach the server.
Troubleshooting
Tools appear, but OBS calls fail: make sure OBS is open and its WebSocket server is enabled. Discovery is local; the shared OBS connection starts lazily. A failed or lost owned session can require a fresh MCP process. Keep its receipts and do not replay an uncertain mutation.
Authentication fails: copy the password from Tools > WebSocket Server Settings into OBS_WEBSOCKET_PASSWORD, then restart the MCP server process. When the server runs on the same machine as OBS, OBS_MCP_READ_OBS_CONFIG=true reads the saved password instead, so it never has to be copied into an agent's configuration. The server logs which file it used, never the password.
The agent cannot see the tools: restart the agent session or the MCP host so it creates a fresh stdio connection and reloads the tool list.
A request is unsupported: the connected OBS build did not advertise that WebSocket request. Use an operation supported by that version or update OBS.
The process exits or emits protocol errors: inspect stderr. stdio stdout is reserved for MCP traffic; HTTP stdout stays empty. Keep ordinary logs on stderr.
Verified replay files use obs-save-replay-verified; see verification and naming limits. Multitrack trim preserves qualified tracks independently; see the workflow matrix.
Development
After approving the project-scoped dependency fetch, install the pinned development tooling and run the native gate:
npm ci --ignore-scripts --no-audit
npm run native:checkThe gate uses the checked Rust toolchain/assets and explicit TypeScript/SDK oracles. It runs default and all-feature Rust checks, path-crate and resolver lifetime controls, then both MCP eras, actual HTTP entry and TCP controls against a pinned optimized executable and fake OBS. License and migration checks also run. This command does not record live OBS. npm run check remains the development Source-oracle gate; Node tooling is not part of the native runtime.
Test the file users will actually install with:
npm run test:packageThat command builds the host-specific dist/obs-studio-native.mcpb, extracts it, and checks its manifest, corresponding source and native entry. Verify profile-conditional inventories rather than treating the 179-name union as one runtime. The recorded macOS artifact passed all three package checks; later artifacts and other platforms need their own receipts.
Live OBS tests
The development live suite is separate from CI and native release acceptance. It exercises the explicit Source oracle; the extracted native Mac journey recorded above has its own receipts. Changed executables, other platforms and additional live workflows need the relevant authorized checks. By default this development suite is skipped. With OBS open and the standard WebSocket environment variables already available to the process, run the read-only checks with:
OBS_MCP_LIVE_TEST=1 npm run test:obs-liveThe read-only lane checks the OBS version, scenes, active scene collection, streaming state, recording state, resources, and read-only request batches through the compiled MCP stdio server. On the machine running OBS, add OBS_MCP_READ_OBS_CONFIG=1 instead of exporting the password.
There is also a narrowly bounded mutation test. Use a disposable scene collection, select it in OBS first, and make sure streaming and recording are stopped. Then run:
OBS_MCP_LIVE_TEST=1 \
OBS_MCP_LIVE_MUTATION=1 \
OBS_MCP_LIVE_SCENE_COLLECTION="OBS MCP Test" \
npm run test:obs-liveThe suite refuses to mutate if the selected collection does not exactly match OBS_MCP_LIVE_SCENE_COLLECTION or if either output is active. It creates one uniquely named scene and removes it in a finally block.
Add OBS_MCP_LIVE_RECORD=1 to the mutation command to also record a one-second clip. It checks that obs-start-record reports success only after OBS confirms the output is active, then stops the recording in a finally block. The clip is saved to the profile's recording directory and captures whatever the selected collection shows, so select a collection whose sources are safe to record.
Scenario tests
Scenario tests build a real use case through MCP tools, record it, and check the file with ffmpeg and ffprobe instead of trusting what OBS reports. They need both tools on PATH, a disposable scene collection, and stopped outputs. The first scenario checks multi-track recording for editing: two tones stand in for a microphone and a game on tracks 2 and 3, and a flash-and-beep clip on track 1 measures audio/video sync. It fails if a track carries the wrong source or if any flash and its beep are more than 100 ms apart. The pulses are unevenly spaced, so a beep matched to the wrong flash shows up as an error. Correcting sync with an audio sync offset is not covered yet: on OBS 32.2.2, changing the offset on a playing media source did not move the recorded audio by the requested amount.
Set the profile used with the disposable collection to record audio tracks 1, 2 and 3 (Settings > Output > Recording), restart OBS, then run:
OBS_MCP_LIVE_TEST=1 \
OBS_MCP_LIVE_SCENARIOS=1 \
OBS_MCP_LIVE_SCENE_COLLECTION="OBS MCP Test" \
npm run test:obs-live -- test/live/obs-scenarios.test.tsWhile it runs, the test mutes every other audio input, points the recording directory at a temporary folder, and switches the program scene to its own scene. Afterwards it puts all three back and removes its scene and inputs. OBS_MCP_LIVE_SERVER=native runs the same scenario against native/target/release/obs-mcp-native (or OBS_MCP_LIVE_NATIVE_BIN) in the Advanced profile, with a temporary OBS_MCP_STATE_DIR so its operation receipts never reach a real state namespace. The signal checks have hermetic tests in test/unit/media-analysis.test.ts.
Persona tests
Six personas each pursue their goals end to end against a real OBS, through native/target/release/obs-mcp-native (or OBS_MCP_LIVE_NATIVE_BIN) in the Production profile:
a streamer with overlays
a vlogger editing in Resolve
a consultant using the virtual camera
a competitive gamer saving replays
a lecturer switching layouts
a founder recording a product demo
Each check reads what OBS produced: a recording, a replay, what a local RTMP server received, or a screenshot.
Profile setup. Use a disposable collection with a 1920×1080 canvas. Its profile needs:
Simple output mode, with recording format Hybrid MP4
audio tracks 1, 2 and 3
the replay buffer enabled
Restart OBS after changing the profile.
Requirements.
ffmpegandffprobemust be onPATH.The product-demo persona runs on macOS only. It needs Python with
tkinter, and Screen Recording permission for OBS.OBS_MCP_LIVE_VCAM_FRAMES=1also reads frames from the OBS Virtual Camera device. That needs camera permission for the process running the tests.
OBS_MCP_LIVE_TEST=1 \
OBS_MCP_LIVE_PERSONAS=1 \
OBS_MCP_LIVE_SCENE_COLLECTION="OBS MCP Test" \
npx vitest run --config vitest.live.config.ts test/live/personas.test.tsWhat changes while it runs. Each persona creates and removes its own scenes and inputs. It stops any output it started, leaves Studio Mode, and puts back the program scene and recording directory. The streamer persona points the profile's stream service at a temporary local RTMP server, and restores the original settings if they were not empty.
Pull-request CI checks the dependency policy before installation. Native-default delivery must run the hermetic development gate on a supported pinned Node toolchain and separately exercise the extracted executable with Node unavailable. Historical Node20 matrix results are not native-only distribution acceptance. Dependency auditing checks the lockfile in a separate weekly workflow so registry advisories do not make otherwise reproducible pull-request checks flaky.
Dependency safety
Direct dependencies use exact versions. npm run check:dependencies checks that the lockfile matches the manifest, uses npm registry HTTPS tarballs with SHA-512 integrity, and contains no production dependency install scripts. The check runs offline and requires no installed packages:
node scripts/check-dependencies.mjsThe private development project disables dependency lifecycle scripts through .npmrc; native MCPB staging installs no npm dependencies. Explicit commands such as npm run build still run. Dependabot proposes weekly npm and GitHub Actions updates for review. CI actions are pinned to verified commit hashes. The residual development advisory and published SDK license findings are recorded in docs/dependency-security.md.
For a dependency update, inspect its release notes and changes to the lockfile, retain exact direct versions, then run npm run check and npm run test:package. Check current advisories with npm audit --package-lock-only --ignore-scripts --audit-level=low. An audit reports known registry advisories; the offline policy check validates the dependency graph's packaging constraints.
The private development toolchain is pinned in package.json/package-lock.json. The current Vitest5 range supports Node22.12+,24 or26+, independently of the installed native runtime, which requires no Node.
TypeScript policy
The development oracle builds with TypeScript 7.0.2 and does not import the TypeScript compiler API. If a future generator, linter, or build tool needs programmatic compiler access, keep that tool on TypeScript 6 while the application compiler remains on TypeScript 7. TypeScript 7.0 does not ship a programmatic API; Microsoft documents the side-by-side TypeScript 6 compatibility package in the TypeScript 7.0 release notes.
Historical protocol baseline
On October 14, 2026, this revision was compared with local modelcontextprotocol, mcp-typescript-sdk, and obs-studio reference checkouts. Those checkouts were read without modification. The exact reference sources are:
MCP specification:
5ea99602MCP TypeScript server and client SDKs:
2.3.1; reference checkout9bc40e90OBS Studio:
f082210cOBS WebSocket:
e28f8497, the revision pinned by that OBS Studio checkout
The refreshed OBS WebSocket revision has the same 147 requests, 60 events, and 7 enums as the previous baseline; its protocol JSON is byte-for-byte identical. MCP 2026-07-28 remains the released protocol baseline.
The generated protocol files live under docs/. Tests compare every request used by the tool modules with the bundled protocol, so obsolete request names and missing wrappers fail locally.
Project history
This project began with Roy Shilkrot's obs-mcp, including upstream work by Zeke Sikelianos. It also preserves Jag-k's MCPB packaging and registerTool migration work. Their original commits and authorship remain in the Git history.
License
OBS MCP is licensed under the MIT License. The generated OBS WebSocket protocol data under docs/protocol* remains under obs-websocket's GPL-2.0 terms (licenses/obs-websocket/GPL-2.0.txt). The native MCPB layout retains the Rust source, native assets, pinned build inputs and notices. TypeScript remains development oracle code. See LICENSE and NOTICE.md.
Native implementation notes
Native architecture describes retained service, journal, connection and shutdown ownership. Full Rust cutover records the optimized, package and bounded Mac evidence alongside the remaining release gates. Earlier 83/166/167 checkpoint configuration, timings and Mac recordings are artifact-bound historical evidence; their compatibility/opt-in commands are superseded by the current native setup.
Available Tools
155 toolsobs-broadcast-custom-eventBroadcast Custom EventA
Broadcasts a CustomEvent to all WebSocket clients
Inputs: eventData (required).
obs-call-requestCall OBS RequestADestructive
Call any request in the pinned OBS WebSocket protocol; inspect it with obs-describe-request first
Inputs: requestType (required), requestData.
obs-call-vendor-requestCall Vendor RequestCDestructive
Call a request registered to a vendor
Inputs: vendorName (required), requestType (required), requestData.
obs-create-inputCreate InputA
Creates a new input, adding it as a scene item to the specified scene
Inputs: inputKind (required), inputName (required), sceneName (required), canvasUuid, +2 more.
obs-create-profileCreate ProfileA
Creates a new profile, switching to it in the process
Inputs: profileName (required).
obs-create-record-chapterCreate Record ChapterA
Adds a new chapter marker to the file currently being recorded
Inputs: chapterName.
obs-create-sceneCreate SceneB
Create a new scene in OBS
Inputs: sceneName (required), canvasUuid.
obs-create-scene-collectionCreate Scene CollectionA
Creates a new scene collection, switching to it in the process
Inputs: sceneCollectionName (required).
obs-create-scene-itemCreate Scene ItemB
Create a scene item for a source in a scene
Inputs: enabled, sceneName, sceneUuid, canvasUuid, +2 more.
obs-create-source-filterCreate Source FilterA
Creates a new filter, adding it to the specified source
Inputs: filterKind (required), filterName (required), sourceName (required), canvasUuid, +1 more.
obs-describe-requestDescribe OBS RequestARead-onlyIdempotent
Inspect the exact fields and constraints of requests in the pinned OBS WebSocket protocol
Inputs: category, requestType.
obs-duplicate-scene-itemDuplicate Scene ItemA
Duplicate a scene item while preserving its transform and crop
Inputs: sceneItemId (required), sceneName, sceneUuid, canvasUuid, +2 more.
obs-get-canvas-listGet Canvas ListARead-onlyIdempotent
Get all canvases available in OBS
Inputs: no named parameters.
obs-get-current-sceneGet Current SceneBRead-onlyIdempotent
Get the current active scene in OBS
Inputs: no named parameters.
obs-get-current-transitionGet Current TransitionARead-onlyIdempotent
Get the name of the currently active transition
Inputs: no named parameters.
obs-get-filter-default-settingsGet Filter Default SettingsBRead-onlyIdempotent
Gets the default settings for a filter kind
Inputs: filterKind (required).
obs-get-filter-kind-listGet Filter Kind ListARead-onlyIdempotent
Gets an array of all available source filter kinds
Inputs: no named parameters.
obs-get-group-listGet Group ListARead-onlyIdempotent
Get all OBS groups
Inputs: no named parameters.
obs-get-group-scene-itemsGet Group Scene ItemsCRead-onlyIdempotent
Get the scene items contained in an OBS group
Inputs: sceneName, sceneUuid, canvasUuid.
obs-get-hotkey-listGet Hotkey ListARead-onlyIdempotent
Gets an array of all hotkey names in OBS
Inputs: no named parameters.
obs-get-input-audio-balanceGet Input Audio BalanceCRead-onlyIdempotent
Gets the audio balance of an input
Inputs: inputName (required).
obs-get-input-audio-monitor-typeGet Input Audio Monitor TypeCRead-onlyIdempotent
Gets the audio monitor type of an input
Inputs: inputName (required).
obs-get-input-audio-sync-offsetGet Input Audio Sync OffsetARead-onlyIdempotent
Gets the audio sync offset of an input
Inputs: inputName (required).
obs-get-input-audio-tracksGet Input Audio TracksARead-onlyIdempotent
Get the enabled audio tracks for an input
Inputs: inputName, inputUuid.
obs-get-input-default-settingsGet Input Default SettingsARead-onlyIdempotent
Gets the default settings for an input kind
Inputs: inputKind (required).
obs-get-input-deinterlace-field-orderGet Input Deinterlace Field OrderCRead-onlyIdempotent
Get the deinterlace field order of an asynchronous input
Inputs: inputName, inputUuid.
obs-get-input-deinterlace-modeGet Input Deinterlace ModeARead-onlyIdempotent
Get the deinterlace mode of an asynchronous input
Inputs: inputName, inputUuid.
obs-get-input-kind-listGet Input Kind ListARead-onlyIdempotent
Gets an array of all available input kinds in OBS
Inputs: unversioned.
obs-get-input-listGet Input ListARead-onlyIdempotent
Gets an array of all inputs in OBS
Inputs: inputKind.
obs-get-input-muteGet Input Mute StateBRead-onlyIdempotent
Gets the audio mute state of an input
Inputs: inputName (required).
obs-get-input-property-list-itemsGet Input Property List ItemsARead-onlyIdempotent
Get the selectable items for a dynamic input list property
Inputs: propertyName (required), inputName, inputUuid.
obs-get-input-settingsGet Input SettingsCRead-onlyIdempotent
Gets the settings of an input
Inputs: inputName (required).
obs-get-input-volumeGet Input VolumeARead-onlyIdempotent
Gets the current volume setting of an input
Inputs: inputName (required).
obs-get-last-replay-buffer-replayGet Last Replay Buffer FileARead-onlyIdempotent
Gets the filename of the last replay buffer save file
Inputs: no named parameters.
obs-get-media-input-statusGet Media Input StatusCRead-onlyIdempotent
Gets the status of a media input
Inputs: inputName (required).
obs-get-monitor-listGet Monitor ListARead-onlyIdempotent
Gets a list of connected monitors and information about them
Inputs: no named parameters.
obs-get-output-listGet Output ListARead-onlyIdempotent
Gets the list of available outputs
Inputs: no named parameters.
obs-get-output-settingsGet Output SettingsBRead-onlyIdempotent
Gets the settings of an output
Inputs: outputName (required).
obs-get-output-statusGet Output StatusCRead-onlyIdempotent
Gets the status of an output
Inputs: outputName (required).
obs-get-persistent-dataGet Persistent DataARead-onlyIdempotent
Gets the value of a slot from the selected persistent data realm
Inputs: realm (required), slotName (required).
obs-get-preview-sceneGet Preview SceneARead-onlyIdempotent
Get the current preview scene in OBS Studio Mode
Inputs: no named parameters.
obs-get-profile-listGet Profile ListARead-onlyIdempotent
Gets an array of all profiles
Inputs: no named parameters.
obs-get-profile-parameterGet Profile ParameterARead-onlyIdempotent
Gets a parameter from the current profile's configuration
Inputs: parameterName (required), parameterCategory (required).
obs-get-record-directoryGet Record DirectoryARead-onlyIdempotent
Gets the current directory that the record output is set to
Inputs: no named parameters.
obs-get-record-statusGet Record StatusBRead-onlyIdempotent
Gets the status of the record output
Inputs: no named parameters.
obs-get-replay-buffer-statusGet Replay Buffer StatusBRead-onlyIdempotent
Gets the status of the replay buffer output
Inputs: no named parameters.
obs-get-scene-collection-listGet Scene Collection ListARead-onlyIdempotent
Gets an array of all scene collections
Inputs: no named parameters.
obs-get-scene-item-blend-modeGet Scene Item Blend ModeBRead-onlyIdempotent
Get the blend mode of a scene item
Inputs: sceneItemId (required), sceneName, sceneUuid, canvasUuid.
obs-get-scene-item-enabledGet Scene Item EnabledARead-onlyIdempotent
Get whether a scene item is enabled
Inputs: sceneItemId (required), sceneName, sceneUuid, canvasUuid.
obs-get-scene-item-idGet Scene Item IDARead-onlyIdempotent
Get the ID of a scene item by its source name
Inputs: sceneName, sceneUuid, canvasUuid, sourceName, +2 more.
obs-get-scene-item-indexGet Scene Item IndexCRead-onlyIdempotent
Get the index position of a scene item
Inputs: sceneItemId (required), sceneName, sceneUuid, canvasUuid.
obs-get-scene-item-lockedGet Scene Item LockedARead-onlyIdempotent
Get whether a scene item is locked
Inputs: sceneItemId (required), sceneName, sceneUuid, canvasUuid.
obs-get-scene-itemsGet Scene ItemsARead-onlyIdempotent
Get a list of all scene items in a scene
Inputs: sceneName, sceneUuid, canvasUuid.
obs-get-scene-item-sourceGet Scene Item SourceARead-onlyIdempotent
Get the source associated with a scene item
Inputs: sceneItemId (required), sceneName, sceneUuid, canvasUuid.
obs-get-scene-item-transformGet Scene Item TransformARead-onlyIdempotent
Get the position, rotation, scale, or crop of a scene item
Inputs: sceneItemId (required), sceneName, sceneUuid, canvasUuid.
obs-get-scene-listGet Scene ListBRead-onlyIdempotent
Get a list of scenes in OBS
Inputs: canvasUuid.
obs-get-scene-transition-overrideGet Scene Transition OverrideARead-onlyIdempotent
Get the transition override configured for a scene
Inputs: sceneName, sceneUuid, canvasUuid.
obs-get-source-activeGet Source Active StateBRead-onlyIdempotent
Gets the active and show state of a source
Inputs: canvasUuid, sourceName, sourceUuid.
obs-get-source-filterGet Source FilterCRead-onlyIdempotent
Gets the info for a specific source filter
Inputs: filterName (required), sourceName (required), canvasUuid.
obs-get-source-filter-listGet Source Filter ListARead-onlyIdempotent
Gets an array of all of a source's filters
Inputs: sourceName (required), canvasUuid.
obs-get-source-screenshotGet Source ScreenshotARead-onlyIdempotent
Gets a Base64-encoded screenshot of a source
Inputs: imageFormat (required), canvasUuid, imageWidth, sourceName, +3 more.
obs-get-special-inputsGet Special InputsBRead-onlyIdempotent
Gets the names of all special inputs
Inputs: no named parameters.
obs-get-statsOBS StatisticsBRead-onlyIdempotent
Gets statistics about OBS, obs-websocket, and the current session
Inputs: no named parameters.
obs-get-statusOBS Server StatusARead-onlyIdempotent
Get the current status of the OBS MCP server and OBS connection
Inputs: no named parameters.
obs-get-stream-service-settingsGet Stream Service SettingsARead-onlyIdempotent
Gets the current stream service settings
Inputs: no named parameters.
obs-get-stream-statusGet Stream StatusARead-onlyIdempotent
Get the current streaming status
Inputs: no named parameters.
obs-get-studio-modeGet Studio ModeARead-onlyIdempotent
Gets whether studio mode is enabled
Inputs: no named parameters.
obs-get-transition-cursorGet Transition CursorBRead-onlyIdempotent
Get the current scene transition cursor position
Inputs: no named parameters.
obs-get-transition-durationGet Transition DurationARead-onlyIdempotent
Get the duration of the current transition in milliseconds
Inputs: no named parameters.
obs-get-transition-kindGet Transition KindARead-onlyIdempotent
Get the kind/type of the current transition
Inputs: no named parameters.
obs-get-transition-kind-listGet Transition Kind ListARead-onlyIdempotent
Get all available OBS transition kinds
Inputs: no named parameters.
obs-get-transition-listGet Transition ListARead-onlyIdempotent
Get a list of available transitions in OBS
Inputs: no named parameters.
obs-get-transition-settingsGet Transition SettingsBRead-onlyIdempotent
Get the settings of the current transition
Inputs: no named parameters.
obs-get-versionOBS Version InfoARead-onlyIdempotent
Get OBS Studio version information
Inputs: no named parameters.
obs-get-video-settingsGet Video SettingsARead-onlyIdempotent
Gets the current video settings
Inputs: no named parameters.
obs-get-virtual-cam-statusGet Virtual Camera StatusARead-onlyIdempotent
Gets the status of the virtualcam output
Inputs: no named parameters.
obs-offset-media-input-cursorOffset Media Input CursorA
Offsets the current cursor position of a media input
Inputs: inputName (required), mediaCursorOffset (required).
obs-open-input-filtersOpen Input FiltersAIdempotent
Opens the filters dialog of an input
Inputs: inputName, inputUuid.
obs-open-input-interactOpen Input InteractAIdempotent
Opens the interact dialog of an input
Inputs: inputName, inputUuid.
obs-open-input-propertiesOpen Input PropertiesBIdempotent
Opens the properties dialog of an input
Inputs: inputName, inputUuid.
obs-open-source-projectorOpen Source ProjectorCIdempotent
Opens a projector for a source
Inputs: canvasUuid, sourceName, sourceUuid, monitorIndex, +1 more.
obs-open-video-mix-projectorOpen Video Mix ProjectorBIdempotent
Opens a projector for a specific output video mix
Inputs: videoMixType (required), monitorIndex, projectorGeometry.
obs-pause-recordPause RecordingAIdempotent
Pauses the record output
Inputs: no named parameters.
obs-press-input-property-buttonPress Input Property ButtonCDestructive
Press a button exposed by an input property
Inputs: propertyName (required), inputName, inputUuid.
obs-remove-inputRemove InputADestructiveIdempotent
Removes an existing input
Inputs: inputName (required).
obs-remove-profileRemove ProfileADestructiveIdempotent
Removes a profile. If the current profile is chosen, it will change to a different profile first
Inputs: profileName (required).
obs-remove-sceneRemove SceneADestructiveIdempotent
Remove a scene from OBS
Inputs: sceneName (required), canvasUuid.
obs-remove-scene-itemRemove Scene ItemADestructiveIdempotent
Remove a scene item from a scene
Inputs: sceneItemId (required), sceneName, sceneUuid, canvasUuid.
obs-remove-source-filterRemove Source FilterADestructiveIdempotent
Removes a filter from a source
Inputs: filterName (required), sourceName (required), canvasUuid.
obs-resume-recordResume RecordingBIdempotent
Resumes the record output
Inputs: no named parameters.
obs-save-replay-bufferSave Replay BufferA
Saves the contents of the replay buffer output
Inputs: no named parameters.
obs-save-source-screenshotSave Source ScreenshotCDestructive
Saves a screenshot of a source to the filesystem
Inputs: imageFormat (required), imageFilePath (required), canvasUuid, imageWidth, +4 more.
obs-send-stream-captionSend Stream CaptionB
Sends CEA-608 caption text over the stream output
Inputs: captionText (required).
obs-set-current-profileSet Current ProfileAIdempotent
Switches to a profile
Inputs: profileName (required).
obs-set-current-sceneSet Current SceneBIdempotent
Set the current active scene in OBS
Inputs: sceneName (required).
obs-set-current-scene-collectionSet Current Scene CollectionCIdempotent
Switches to a scene collection
Inputs: sceneCollectionName (required).
obs-set-current-transitionSet Current TransitionAIdempotent
Set the current transition in OBS
Inputs: transitionName (required).
obs-set-input-audio-balanceSet Input Audio BalanceAIdempotent
Sets the audio balance of an input
Inputs: inputName (required), inputAudioBalance (required).
obs-set-input-audio-monitor-typeSet Input Audio Monitor TypeAIdempotent
Sets the audio monitor type of an input
Inputs: inputName (required), monitorType (required).
obs-set-input-audio-sync-offsetSet Input Audio Sync OffsetCIdempotent
Sets the audio sync offset of an input
Inputs: inputName (required), inputAudioSyncOffset (required).
obs-set-input-audio-tracksSet Input Audio TracksBIdempotent
Set the enabled audio tracks for an input
Inputs: inputAudioTracks (required), inputName, inputUuid.
obs-set-input-deinterlace-field-orderSet Input Deinterlace Field OrderAIdempotent
Set the deinterlace field order of an asynchronous input
Inputs: inputDeinterlaceFieldOrder (required), inputName, inputUuid.
obs-set-input-deinterlace-modeSet Input Deinterlace ModeBIdempotent
Set the deinterlace mode of an asynchronous input
Inputs: inputDeinterlaceMode (required), inputName, inputUuid.
obs-set-input-muteSet Input MuteAIdempotent
Sets the audio mute state of an input
Inputs: inputName (required), inputMuted (required).
obs-set-input-nameRename InputAIdempotent
Sets the name of an input (rename)
Inputs: inputName (required), newInputName (required).
obs-set-input-settingsSet Input SettingsCIdempotent
Sets the settings of an input
Inputs: inputName (required), inputSettings (required), overlay.
obs-set-input-volumeSet Input VolumeBIdempotent
Sets the volume setting of an input
Inputs: inputName (required), inputVolumeDb, inputVolumeMul.
obs-set-media-input-cursorSet Media Input CursorAIdempotent
Sets the cursor position of a media input
Inputs: inputName (required), mediaCursor (required).
obs-set-output-settingsSet Output SettingsCIdempotent
Sets the settings of an output
Inputs: outputName (required), outputSettings (required).
obs-set-persistent-dataSet Persistent DataBIdempotent
Sets the value of a slot from the selected persistent data realm
Inputs: realm (required), slotName (required), slotValue (required).
obs-set-preview-sceneSet Preview SceneBIdempotent
Set the current preview scene in OBS Studio Mode
Inputs: sceneName (required).
obs-set-profile-parameterSet Profile ParameterAIdempotent
Sets the value of a parameter in the current profile's configuration
Inputs: parameterName (required), parameterValue (required), parameterCategory (required).
obs-set-record-directorySet Record DirectoryAIdempotent
Sets the current directory that the record output writes files to
Inputs: recordDirectory (required).
obs-set-scene-item-blend-modeSet Scene Item Blend ModeCIdempotent
Set the blend mode of a scene item
Inputs: sceneItemId (required), sceneItemBlendMode (required), sceneName, sceneUuid, +1 more.
obs-set-scene-item-enabledSet Scene Item VisibilityBIdempotent
Show or hide a scene item
Inputs: enabled (required), sceneItemId (required), sceneName, sceneUuid, +1 more.
obs-set-scene-item-indexSet Scene Item IndexCIdempotent
Set the index position of a scene item
Inputs: sceneItemId (required), sceneItemIndex (required), sceneName, sceneUuid, +1 more.
obs-set-scene-item-lockedSet Scene Item LockedBIdempotent
Set whether a scene item is locked
Inputs: sceneItemId (required), sceneItemLocked (required), sceneName, sceneUuid, +1 more.
obs-set-scene-item-transformSet Scene Item TransformBIdempotent
Set the position, rotation, scale, or crop of a scene item
Inputs: sceneItemId (required), scaleX, scaleY, cropTop, +10 more.
obs-set-scene-nameSet Scene NameAIdempotent
Rename an OBS scene
Inputs: newSceneName (required), sceneName, sceneUuid, canvasUuid.
obs-set-scene-transition-overrideSet Scene Transition OverrideAIdempotent
Set or clear the transition override for a scene
Inputs: sceneName, sceneUuid, canvasUuid, transitionName, +1 more.
obs-set-source-filter-enabledSet Source Filter EnabledAIdempotent
Sets the enable state of a source filter
Inputs: filterName (required), sourceName (required), filterEnabled (required), canvasUuid.
obs-set-source-filter-indexSet Source Filter IndexBIdempotent
Sets the index position of a filter on a source
Inputs: filterName (required), sourceName (required), filterIndex (required), canvasUuid.
obs-set-source-filter-nameRename Source FilterAIdempotent
Sets the name of a source filter (rename)
Inputs: filterName (required), sourceName (required), newFilterName (required), canvasUuid.
obs-set-source-filter-settingsSet Source Filter SettingsCIdempotent
Sets the settings of a source filter
Inputs: filterName (required), sourceName (required), filterSettings (required), overlay, +1 more.
obs-set-stream-service-settingsSet Stream Service SettingsCIdempotent
Sets the current stream service settings
Inputs: streamServiceType (required), streamServiceSettings (required).
obs-set-studio-modeSet Studio ModeAIdempotent
Enables or disables studio mode
Inputs: studioModeEnabled (required).
obs-set-tbar-positionSet T-Bar PositionA
Set and optionally release the OBS Studio Mode T-Bar position
Inputs: position (required), release.
obs-set-transition-durationSet Transition DurationAIdempotent
Set the duration of the current transition in milliseconds
Inputs: duration (required).
obs-set-transition-settingsSet Transition SettingsAIdempotent
Set the settings of the current transition
Inputs: transitionSettings (required).
obs-set-video-settingsSet Video SettingsCIdempotent
Sets the current video settings
Inputs: baseWidth, baseHeight, outputWidth, fpsNumerator, +2 more.
obs-sleepOBS SleepARead-onlyIdempotent
Sleeps for a time duration or number of frames
Inputs: sleepFrames, sleepMillis.
obs-split-record-fileSplit Record FileB
Splits the current file being recorded into a new file
Inputs: no named parameters.
obs-start-outputStart OutputC
Starts an output
Inputs: outputName (required).
obs-start-recordStart RecordingB
Starts the record output
Inputs: no named parameters.
obs-start-replay-bufferStart Replay BufferB
Starts the replay buffer output
Inputs: no named parameters.
obs-start-streamStart StreamB
Start streaming in OBS
Inputs: no named parameters.
obs-start-virtual-camStart Virtual CameraA
Starts the virtualcam output
Inputs: no named parameters.
obs-stop-outputStop OutputBIdempotent
Stops an output
Inputs: outputName (required).
obs-stop-recordStop RecordingAIdempotent
Stops the record output
Inputs: no named parameters.
obs-stop-replay-bufferStop Replay BufferBIdempotent
Stops the replay buffer output
Inputs: no named parameters.
obs-stop-streamStop StreamAIdempotent
Stop streaming in OBS
Inputs: no named parameters.
obs-stop-virtual-camStop Virtual CameraAIdempotent
Stops the virtualcam output
Inputs: no named parameters.
obs-test-connectionTest OBS ConnectionARead-onlyIdempotent
Test the connection to OBS WebSocket
Inputs: no named parameters.
obs-toggle-input-muteToggle Input MuteA
Toggles the audio mute state of an input
Inputs: inputName (required).
obs-toggle-outputToggle OutputC
Toggles the status of an output
Inputs: outputName (required).
obs-toggle-recordToggle RecordingB
Toggles the status of the record output
Inputs: no named parameters.
obs-toggle-record-pauseToggle Record PauseA
Toggles pause on the record output
Inputs: no named parameters.
obs-toggle-replay-bufferToggle Replay BufferA
Toggles the state of the replay buffer output
Inputs: no named parameters.
obs-toggle-streamToggle StreamA
Toggle the streaming state in OBS
Inputs: no named parameters.
obs-toggle-virtual-camToggle Virtual CameraA
Toggles the state of the virtualcam output
Inputs: no named parameters.
obs-trigger-hotkey-by-key-sequenceTrigger Hotkey by Key SequenceCDestructive
Triggers a hotkey using a sequence of keys
Inputs: keyId, keyModifiers.
obs-trigger-hotkey-by-nameTrigger Hotkey by NameBDestructive
Triggers a hotkey using its name
Inputs: hotkeyName (required), contextName.
obs-trigger-media-input-actionTrigger Media Input ActionC
Triggers an action on a media input
Inputs: inputName (required), mediaAction (required).
obs-trigger-studio-transitionTrigger Studio TransitionA
Trigger a transition from preview to program scene in Studio Mode
Inputs: no named parameters.
obs-trigger-transitionTrigger TransitionB
Trigger a scene transition in OBS (Studio Mode must be enabled)
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 155 tools
Most tools map cleanly to distinct OBS resources and actions, and the consistent get/set/toggle/start/stop pattern helps separate them. Only a couple of concepts, such as source active/show state versus scene item enabled state, could cause misselection.
Every tool is prefixed with obs- and follows a predictable hyphenated verb-noun pattern, e.g., get-, set-, create-, remove-, toggle-, start-, stop-. Despite the large number of tools, the naming convention remains highly consistent throughout the entire set.
155 tools is far beyond the 25+ threshold and constitutes an extreme tool-surface mismatch for an MCP server. The set is comprehensive, but the sheer count creates excessive selection overhead and is especially redundant given that obs-call-request already provides generic access to the full OBS WebSocket API.
The surface covers nearly all major OBS domains: scenes, scene items, inputs, filters, transitions, audio, outputs, recording, streaming, profiles, collections, hotkeys, media, and more. Any niche gap can likely be addressed through obs-call-request, so agents are unlikely to hit dead ends.
Maintenance
Related MCP Connectors
Remote MCP for RunComfy: ComfyUI deployments, hosted models, LoRA training. 31 tools.
214 tools for AI agents over one MCP endpoint: image, video, audio, 3D, data, storage, mail, GPUs.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Build and run AI workflows, agents, data tables and 1000+ API integrations from any MCP client.
Related MCP Servers
- AlicenseBqualityCmaintenanceA server that provides tools to control OBS Studio remotely via the OBS WebSocket protocol, enabling management of scenes, sources, streaming, and recording through an MCP client interface.100598 npm162GPL 2.0
- AlicenseAqualityDmaintenanceAn MCP (Model Context Protocol) server for controlling OBS Studio via the built-in obs-websocket plugin. Lets Claude control your scenes, recording, streaming, audio, and more.2613 npm1MIT
- AlicenseBqualityDmaintenanceMCP server for controlling OBS Studio via obs-websocket, enabling scene switching, source management, streaming, recording, and text overlays through natural language.36114 PyPI5MIT
- AlicenseBqualityDmaintenanceEnables AI assistants to control and automate OBS Studio via natural language, covering scenes, sources, audio, recording, streaming, transitions, filters, media playback, diagnostics, and multi-step workflows over the OBS WebSocket protocol.89MIT