Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

io.github.AImplifier/eeg-mcp

PYPI · EEG-MCP · SCANNED SEP 20

Real-time EEG: BrainFlow streaming, wall-clock replay, online DSP, recording, and stimulation.

Available components

0 this week 78 Trust /100
Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security90
  • No malware found by supply-chain analysis.Pass
  • CVE check failed: a known medium-severity CVE affects setuptools 80.10.2, a direct dependency. A fixed version is available. View diagnostics → Fail
  • Runs setuptools.build_meta at install time, a recognised native-build step with no shell scripting around it. View diagnostics → Pass
  • 5 of 47 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency45
Schema Quality & AI Usability76
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 6246 tokens (~132/item across 47 items; 47 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management83
  • Stability observed for 25 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
  • Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety75
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • 0 of 5 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "clear_filters" implies "remove" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
  • An AI judge read all 48 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
Install

How do I install the io.github.AImplifier/eeg-mcp server?

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

pypi · eeg-mcp

# add to Claude Code
claude mcp add aimplifier-eeg-mcp -- uvx eeg-mcp
// .cursor/mcp.json
{
  "mcpServers": {
    "aimplifier-eeg-mcp": {
      "command": "uvx",
      "args": [
        "eeg-mcp"
      ]
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "aimplifier-eeg-mcp": {
      "command": "uvx",
      "args": [
        "eeg-mcp"
      ]
    }
  }
}
# add to Codex CLI
codex mcp add aimplifier-eeg-mcp -- uvx eeg-mcp
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "aimplifier-eeg-mcp": {
      "type": "local",
      "command": [
        "uvx",
        "eeg-mcp"
      ],
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add aimplifier-eeg-mcp --command uvx --arg eeg-mcp
# ~/.hermes/config.yaml
mcp_servers:
  aimplifier-eeg-mcp:
    command: "uvx"
    args: ["eeg-mcp"]
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "aimplifier-eeg-mcp": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "eeg-mcp"
      ]
    }
  }
}
# add to Vellum
assistant mcp add aimplifier-eeg-mcp -t stdio -c uvx -a eeg-mcp
// mcp.json
{
  "mcpServers": {
    "aimplifier-eeg-mcp": {
      "command": "uvx",
      "args": [
        "eeg-mcp"
      ]
    }
  }
}
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 20 Sept 26 +1

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

  • 19 Sept 26 −3
    • Stability: pass → 0.80 functional
  • 18 Sept 26 0
    • Stability: 0.97 → pass security
  • 17 Sept 26 +1

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

  • 15 Sept 26 +16
    • Malware scan: unverified → pass security
  • 14 Sept 26 −15
    • Malware scan: pass → unverified security
  • 13 Sept 26 +1

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

  • 12 Sept 26 −3
    • Stability: pass → 0.80 functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 20 Sept 2026 · Analysed pypi/eeg-mcp@0.1.0

Provenance No attestation

The registry publishes no build provenance for this version, so there is nothing to verify.

Result No attestation
Ecosystem pypi

Background: How many MCP packages publish verified provenance →

Install scripts 1 script
Hook Tier Command
build_backend allowlisted setuptools.build_meta

Background: Why install scripts are a supply-chain risk →

Vulnerabilities 2 findings
ID CVE Severity Vector Fix available
GHSA-h35f-9h28-mq5c CVE-2026-59890 medium CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N yes
PYSEC-2026-3447 CVE-2026-59890 medium CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N yes

Background: What a vulnerability scan can and cannot prove →

Dependencies 47 packages
Packages resolved 47
Stale 4
No linked repository 1
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 47 exposed · ~5,852 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
arm_stim ~110

Permit hardware stimulation for a bounded window. Arming expires deliberately: an agent that stalls mid-protocol should not be able to resume and fire a stimulator minutes later without a fresh, explicit decision. Re-arm as needed, or disarm the moment a block ends.

NameTypeReqDescription
backendWhich attached backend. Defaults to the session default.
session_idstringyesThe session whose backend to arm.
ttl_secnumberHow long the arming lasts, in seconds.

Structured output declared, but exposes no named fields.

No examples provided.

attach_processor ~141

Attach a processor to a session. A ``streaming`` processor runs inside the acquisition loop on every chunk, so it reacts within one poll interval without an agent round-trip -- that is how closed-loop logic gets fast. The cost is that slow code stalls acquisition; ``processor_status`` reports each one's mean and worst-case time so you can see whether yours is affordable. Non-streaming processors do nothing until you call ``run_processor``.

NameTypeReqDescription
paramsProcessor-specific settings; see its ``params`` in the listing.
processorstringyesName from list_processors.
session_idstringyesThe session to attach to.

Structured output declared, but exposes no named fields.

No examples provided.

attach_stim_backend ~179

Bind a stimulation target to a session and open its transport. Start with backend='log' to rehearse a protocol with no output at all, then switch once the timing looks right.

NameTypeReqDescription
backendstringOne of the names from list_stim_backends.
make_defaultbooleanUse this backend when send_stim_event omits one.
optionsBackend-specific settings. For serial backends: {"port": "COM3"}. For templated devices (tms, tes, template_serial), the commands from your device manual, e.g. {"port": "COM3", "templates": {"fire":…
session_idstringyesThe session to attach to.

Structured output declared, but exposes no named fields.

No examples provided.

check_signal_quality ~116

Per-channel health check: amplitude, flat/railed detection, line noise. Call this before trusting any real-time feature, and definitely before driving stimulation from one. A flat or railed electrode poisons an average reference and a band-power threshold without changing anything you would notice in the feature value itself.

NameTypeReqDescription
line_freqnumberMains frequency to test for (50 or 60).
secondsnumberWindow length to assess.
session_idstringyesThe session to check.

Structured output declared, but exposes no named fields.

No examples provided.

clear_events ~46

Empty the session's event log without stopping the stream. Useful between blocks of an experiment. The signal buffer is untouched.

NameTypeReqDescription
session_idstringyesThe session whose log to clear.

Structured output declared, but exposes no named fields.

No examples provided.

clear_filters ~33

Remove the filter chain; reads return raw signal again.

NameTypeReqDescription
session_idstringyesThe session to clear filters on.

Structured output declared, but exposes no named fields.

No examples provided.

detach_processor ~44

Remove a processor from a session and release its state.

NameTypeReqDescription
processorstringyesThe attached processor's name.
session_idstringyesThe session to detach from.

Structured output declared, but exposes no named fields.

No examples provided.

detach_stim_backend ~45

Close and remove a stimulation backend from a session.

NameTypeReqDescription
backendstringyesThe attached backend's name.
session_idstringyesThe session to detach from.

Structured output declared, but exposes no named fields.

No examples provided.

disarm_stim ~49

Revoke permission to stimulate. Takes effect immediately.

NameTypeReqDescription
backendWhich attached backend. Defaults to the session default.
session_idstringyesThe session whose backend to disarm.

Structured output declared, but exposes no named fields.

No examples provided.

export_report ~123

Write a full review page: traces, spectrum, quality, and the event log. The one artefact to keep from a session. Everything is inlined, so it opens on any machine, needs no internet, and still renders years from now.

NameTypeReqDescription
include_spectrumbooleanAdd the PSD and band-power sections.
notesFree text to record at the top -- indication, montage, observations.
secondsnumberWindow of signal to include in the traces and spectrum.
session_idstringyesThe session to report on.

Structured output declared, but exposes no named fields.

No examples provided.

get_band_power ~188

Band power over the most recent window, per channel and averaged. The workhorse feature for neurofeedback and closed-loop triggering. Prefer the ``_rel`` (relative) values for thresholds: they are largely immune to impedance drift, so a threshold set at the start of a session still means the same thing an hour later.

NameTypeReqDescription
bandsBand names to compute. Defaults to delta, theta, alpha, beta, gamma.
channelsChannel names to include. Defaults to all.
filteredbooleanUse the filtered buffer when a chain is set.
relativebooleanAlso return each band as a fraction of total power.
secondsnumberWindow length. 2 s is a reasonable default; shorter windows are noisier, longer ones respond more slowly.
session_idstringyesThe session to analyse.

Structured output declared, but exposes no named fields.

No examples provided.

get_channels ~33

List the channels a session is producing, with their buffer index.

NameTypeReqDescription
session_idstringyesThe session to inspect.

Structured output declared, but exposes no named fields.

No examples provided.

get_epoch_around_event ~210

Extract the signal window around an event that already occurred. Online epoching: use it to inspect the response to the most recent stimulus, or to verify that a stimulation artifact lands where you expect. The event must still be inside the ring buffer -- for a default 60 s buffer, that means within the last minute.

NameTypeReqDescription
filteredbooleanUse the filtered buffer when a chain is set.
labelEvent label to find. None takes the most recent event of any kind.
max_samplesintegerDecimation cap per channel.
occurrenceintegerWhich matching event; -1 is the most recent, -2 the one before it, 0 the earliest still in the log.
session_idstringyesThe session to read from.
tmaxnumberWindow end relative to the event, in seconds.
tminnumberWindow start relative to the event, in seconds (negative = before).

Structured output declared, but exposes no named fields.

No examples provided.

get_events ~157

Read the session's event log. Everything lands here on one clock: board markers, annotations re-emitted by a replay, stimulation commands we dispatched, and manual notes. That is what makes a closed-loop run reconstructible afterwards without joining clocks.

NameTypeReqDescription
labelFilter to one event label.
last_secondsOnly events from the last N seconds. None for all.
limitintegerMaximum events to return, most recent first-truncated.
originFilter by 'marker' (live board), 'annotation' (from a replayed file), 'stim' (dispatched by us), or 'manual' (logged by hand).
session_idstringyesThe session to read.

Structured output declared, but exposes no named fields.

No examples provided.

get_processor_output ~58

Read a streaming processor's recent outputs.

NameTypeReqDescription
limitintegerHow many recent outputs to return, newest last.
processorstringyesThe attached processor's name.
session_idstringyesThe session to read from.

Structured output declared, but exposes no named fields.

No examples provided.

get_psd ~136

Power spectral density over the most recent window. Use when band power is too coarse -- to find a peak alpha frequency, confirm a stimulation artifact, or check whether a notch actually removed the mains.

NameTypeReqDescription
channelsChannel names to include. Defaults to all.
filteredbooleanUse the filtered buffer when a chain is set.
fmaxnumberHighest frequency to return.
max_binsintegerCap on returned frequency bins, to keep the response readable.
secondsnumberWindow length. Longer gives finer frequency resolution.
session_idstringyesThe session to analyse.

Structured output declared, but exposes no named fields.

No examples provided.

get_tokens ~133

Read discrete tokens from a tokenizing processor. For feeding EEG into sequence models. Returns both the grouped tokens (one group per window) and a flat sequence, plus the vocabulary size and the channel/band layout each position corresponds to. Works with any attached processor exposing ``token_history`` -- the built-in ``band_tokenizer`` is a starting point, and your own tokenizer plugs in the same way.

NameTypeReqDescription
limitintegerHow many recent token groups to return.
processorstringThe tokenizing processor's name.
session_idstringyesThe session to read from.

Structured output declared, but exposes no named fields.

No examples provided.

inspect_recording ~141

Open a recording and describe it without starting playback. Use this before start_replay to see how long the file is, what channels it has, and which annotations will be re-emitted as events during replay.

NameTypeReqDescription
boardRequired only for BrainFlow CSV, which has no header describing its layout (e.g. 'cyton', 'synthetic').
max_eventsintegerCap on how many of the file's events to list.
pathstringyesAbsolute path, or a filename inside the configured recordings dir. EDF/BDF/GDF/SET/FIF and anything else MNE reads; also BrainFlow CSV.

Structured output declared, but exposes no named fields.

No examples provided.

list_boards ~89

List every board BrainFlow can acquire from, with ids and sampling rates. Start here when you do not know what hardware is available. Two entries need no hardware at all: ``SYNTHETIC_BOARD`` generates a signal for development, and ``PLAYBACK_FILE_BOARD`` replays a BrainFlow CSV. Returns: Board names, numeric ids, sampling rates and EEG channel counts.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

list_monitors ~30

List live monitors currently serving, with their URLs. Returns: Active monitors and the URL for each.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

list_processors ~134

List real-time processors available to attach, and where they came from. Built-ins are always present. Your own appear here once the **server** environment points at them -- via the ``eeg_mcp.processors`` entry point, ``EEG_MCP_PLUGINS``, or ``EEG_MCP_PLUGIN_DIR``. They cannot be loaded from a tool call, because importing a module executes it and that would make arbitrary code execution reachable from a model. Returns: Available processors with their parameters, plus any plugin that failed to load, so a typo is visible instead of silently missing.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

list_recording_events ~89

List all events present in a replay session's source file. Distinct from get_events: this is the *complete* event list from the file, including events that have not been reached yet. get_events returns only what has actually been emitted so far.

NameTypeReqDescription
max_eventsintegerCap on the number returned.
session_idstringyesA session created by start_replay.

Structured output declared, but exposes no named fields.

No examples provided.

list_recordings ~91

List recordings in eeg-mcp's own metadata store, newest first. This store belongs to eeg-mcp alone. Analysis tools read from it -- the schema is compatible with neuro-mcp's, so it can open this database and understand every row -- but nothing else writes to it.

NameTypeReqDescription
limitintegerMaximum number to return.
subjectOnly recordings for this participant identifier.

Structured output declared, but exposes no named fields.

No examples provided.

list_sessions ~39

List all active stream and replay sessions with a one-line summary each. Returns: Session ids with their source kind, running state, and buffer fill.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

list_stim_backends ~106

List stimulation targets, their options, and which ones drive hardware. Software backends ('log', 'lsl', 'brainflow_marker') are always available. Hardware backends ('serial_ttl', 'tms', 'tes', 'template_serial') require the server to have been started with EEG_MCP_ALLOW_HARDWARE_STIM=1, and must be armed before each session of use. Returns: The backend catalogue and the currently configured safety ceilings.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

log_event ~194

Record an event against the stream's clock. For anything the server did not generate itself: a task onset, a subject report, an experimenter note. Stimulation commands are logged automatically by send_stim_event, so do not log those by hand.

NameTypeReqDescription
durationnumberEvent duration in seconds. 0 for an instantaneous event.
labelstringyesEvent name, e.g. 'trial_start' or 'eyes_closed'.
mark_in_streambooleanAlso punch the value into the acquisition stream's own marker channel, so the recording carries the event independently.
payloadAny extra structured detail to keep with the event.
session_idstringyesThe session to annotate.
valuenumberNumeric code. Also written to the board's marker channel when mark_in_stream is set; BrainFlow reserves 0, so use a nonzero value.

Structured output declared, but exposes no named fields.

No examples provided.

plot_spectrum ~90

Render the power spectrum and band composition as a standalone HTML file.

NameTypeReqDescription
channelsChannel names to include. Defaults to all.
filteredbooleanUse the filtered signal when a chain is set.
fmaxnumberHighest frequency to draw.
secondsnumberWindow length. Longer gives finer frequency resolution.
session_idstringyesThe session to analyse.

Structured output declared, but exposes no named fields.

No examples provided.

plot_stream ~124

Render the recent signal as a standalone HTML file and return its path. A frozen snapshot, unlike start_monitor -- use it to keep a record, attach to a note, or share. The file inlines everything and needs no internet.

NameTypeReqDescription
channelsChannel names to include. Defaults to all.
filteredbooleanDraw the filtered signal when a chain is set.
secondsnumberHow much recent signal to draw.
session_idstringyesThe session to plot.
show_eventsbooleanOverlay event markers on the traces.

Structured output declared, but exposes no named fields.

No examples provided.

processor_status ~114

Report attached processors, their health, and their cost. ``mean_ms`` and ``max_ms`` are the numbers to watch for a streaming processor: if ``max_ms`` approaches the poll interval (50 ms by default) it is starving acquisition, which shows up as ``throughput_ratio`` below 1.0 in stream_status. A processor that raises 10 times is disabled automatically rather than being retried forever inside the producer loop.

NameTypeReqDescription
session_idstringyesThe session to report on.

Structured output declared, but exposes no named fields.

No examples provided.

read_window ~178

Read the most recent samples from the buffer. Returns filtered signal when a filter chain is set (see set_filters), otherwise raw. Long windows are decimated to ``max_samples`` per channel so the response stays readable -- for numeric work prefer get_band_power or get_psd, which compute on the full-resolution data.

NameTypeReqDescription
channelsChannel names to include. Defaults to all.
filteredbooleanReturn the filtered buffer if a chain is set. False for raw.
include_databooleanWhether to return the sample arrays at all.
max_samplesintegerDecimation cap per channel. Set include_data=False to skip the samples entirely and get only summary statistics.
secondsnumberHow much recent signal to return.
session_idstringyesThe session to read from.

Structured output declared, but exposes no named fields.

No examples provided.

recording_status ~34

Report whether a session is recording, and how much has been written.

NameTypeReqDescription
session_idstringyesThe session to check.

Structured output declared, but exposes no named fields.

No examples provided.

recover_recording ~136

Finish a recording whose process died before it could be closed. Samples are appended to disk as they arrive and the header is written up front, precisely so an interrupted session is not lost. Point this at the orphaned ``.eegmcp.json`` header to convert what was captured into a ``.fif``. Events are not recoverable -- they lived in memory -- so the resulting file carries signal without annotations.

NameTypeReqDescription
header_pathstringyesPath to the ``<stem>.eegmcp.json`` left behind.
keep_sidecarbooleanKeep the raw files after conversion.

Structured output declared, but exposes no named fields.

No examples provided.

replay_control ~89

Pause, resume, seek, or change the speed of a replay session.

NameTypeReqDescription
actionstringyesOne of 'pause', 'resume', 'seek', 'speed', 'status'.
position_secTarget position, required for action='seek'.
session_idstringyesA session created by start_replay.
speedNew playback rate, required for action='speed'.

Structured output declared, but exposes no named fields.

No examples provided.

reset_processors ~58

Clear accumulated processor state and outputs, without detaching them. Useful between experimental blocks, and after a replay seek, so a rolling window does not straddle the discontinuity.

NameTypeReqDescription
session_idstringyesThe session whose processors to reset.

Structured output declared, but exposes no named fields.

No examples provided.

run_processor ~121

Run a processor once on the most recent window, on demand. Works for both modes: for a non-streaming processor this is the only way to execute it, and for a streaming one it is a way to get an answer right now rather than waiting for its next scheduled output.

NameTypeReqDescription
filteredOverride the processor's declared preference for filtered or raw signal.
processorstringyesThe attached processor's name.
secondsnumberWindow length to pass in.
session_idstringyesThe session to read from.

Structured output declared, but exposes no named fields.

No examples provided.

send_stim_event ~314

Deliver one stimulation command, and log it against the EEG clock. The event is written to the session log whether the transport succeeds or fails -- a failed stimulation attempt matters just as much to the record. When the acquisition source supports markers, the same event is also punched into the stream itself so the recording is self-describing.

NameTypeReqDescription
also_mark_sourcebooleanAlso write the code into the acquisition stream's own marker channel.
backendWhich attached backend to use. Defaults to the session default.
duration_msnumberPulse width or stimulation duration.
intensityPhysical dose for hardware backends -- %MSO for TMS, mA for tES. Clamped against the configured ceiling; ignored by software backends.
kindstring'marker' (event code only), 'pulse' (code then clear after duration_ms), 'train', 'ramp', or 'custom'. Backends advertise which kinds they support via list_stim_backends.
labelstringyesEvent name, e.g. 'tms_pulse' or 'cue_left'.
paramsExtra fields made available to command templates.
session_idstringyesThe session to stimulate within.
targetCoil, montage or channel identifier, for the record.
unitUnit label for intensity, for the record.
valuenumberNumeric code for marker streams and trigger lines. Nonzero.

Structured output declared, but exposes no named fields.

No examples provided.

send_stim_train ~216

Deliver a regular train of pulses, blocking until it completes. For rTMS bursts and repeated cues. The call holds until the train finishes, so it is capped at 1000 pulses and 60 seconds total; build longer protocols from several calls so there are decision points in between. Every pulse is logged individually, so the event log reconstructs the exact delivered timing rather than the intended timing.

NameTypeReqDescription
backendWhich attached backend. Defaults to the session default.
duration_msnumberPulse width.
intensityPhysical dose per pulse, clamped against the ceiling.
interval_msnumberyesInter-pulse interval. For rTMS this is 1000/frequency.
labelstringyesBase event name; pulses are logged as '<label>_<n>'.
n_pulsesintegeryesHow many pulses to deliver.
session_idstringyesThe session to stimulate within.
valuenumberNumeric code for each pulse.

Structured output declared, but exposes no named fields.

No examples provided.

set_filters ~297

Install a stateful online filter chain on a running stream. The chain filters continuously in the background as samples arrive, carrying filter state across chunk boundaries. This matters: filtering each query window independently would inject a transient at every boundary and corrupt any phase-sensitive measure. Filtered output goes to a second buffer, so raw signal remains available via read_window(filtered=False). These are causal filters -- there is no zero-phase option, because that needs future samples. Check ``group_delay_sec`` in the response to know how far behind real time your filtered features are.

NameTypeReqDescription
bandpass_highLow-pass corner in Hz. None to skip the bandpass.
bandpass_lowHigh-pass corner in Hz. None to skip the bandpass.
filtersAdvanced -- an explicit stage list that overrides the arguments above, e.g. [{"kind": "highpass", "low": 0.5}, {"kind": "notch", "low": 60, "quality": 30}]. Kinds: bandpass, bandstop, highpass, lowpa…
notch_freqMains frequency to notch out (50 in most of the world, 60 in the Americas). None to skip.
orderintegerButterworth order for the bandpass. 4 is a sensible default.
session_idstringyesThe session to filter.

Structured output declared, but exposes no named fields.

No examples provided.

start_monitor ~285

Open a live browser view of a running session and return its URL. Serves a rolling traces view with event markers, band power and per-channel quality, refreshing continuously. This is the tool for "let me watch the recording" -- a static plot cannot answer whether the signal is good *now*. With ``allow_control`` (the default) the page also carries transport buttons: play/pause, restart, skip, speed, stop, mark an event, and save a report. Pass ``allow_control=false`` for a strictly read-only view, e.g. when showing the screen to someone who should not be able to alter the run. The page is bound to 127.0.0.1 only and requires a random per-monitor token, so it is not reachable from the network. It is still unencrypted: do not expose it through a tunnel or reverse proxy.

NameTypeReqDescription
allow_controlbooleanEnable the transport buttons and the control endpoint.
portintegerTCP port on loopback. 0 lets the OS choose a free one.
refresh_msintegerRedraw interval. 500 ms is smooth without loading the server.
session_idstringyesThe running session to display.
window_secnumberSeconds of signal shown at once. Adjustable in the page too.

Structured output declared, but exposes no named fields.

No examples provided.

start_recording ~263

Begin writing the live signal to disk, continuously. Call this as soon as the session starts if you intend to keep the data. The ring buffer only holds the last minute or so, so anything not recorded is gone -- a session streamed for an hour without recording leaves nothing but whatever reports you exported. The raw, unfiltered signal is written. Filter settings are stored alongside it so a filtered view is reproducible; the amplifier's actual output is not reconstructible from anything else.

NameTypeReqDescription
datasetStudy or collection name that groups recordings together.
nameExplicit filename stem, overriding the BIDS-style name built from subject/session/task/run.
notesFree text kept with the recording.
runRun number within the task, e.g. '01'.
session_idstringyesThe running session to record.
session_labelVisit or session label, e.g. '01' or 'baseline'.
subjectParticipant identifier, e.g. 'sub-04' or a study code. Becomes the subject row in the metadata store. Avoid direct identifiers.
taskWhat the participant is doing, e.g. 'rest', 'motor-imagery'.

Structured output declared, but exposes no named fields.

No examples provided.

start_replay ~283

Replay a recording against a wall clock, re-emitting its events. This is the safe way to build a real-time pipeline: the session behaves exactly like a live stream -- same buffering, same chunked delivery, same tools -- so code developed here runs unchanged against hardware. The recording's annotations arrive in the event log at their original timings.

NameTypeReqDescription
boardRequired only for BrainFlow CSV files.
loopbooleanRestart from the beginning on reaching the end, emitting a 'replay_loop' event each time. Good for long-running rehearsals.
pathstringyesAbsolute path, or a filename inside the configured recordings dir.
picksMNE channel selection, e.g. 'eeg' or 'mag'. Defaults to EEG.
session_idstringyesName you will pass to every later call for this session.
speednumberPlayback rate. 1.0 is true recording rate; 2.0 is twice as fast; 0.5 is half. Faster-than-real-time is useful for testing a pipeline over a long recording, but stops being a realistic latency test.
start_secnumberOffset into the recording to begin from.
use_stim_channelbooleanAlso extract events from a hardware trigger channel, not just annotations.

Structured output declared, but exposes no named fields.

No examples provided.

start_stream ~189

Open a board and begin buffering EEG in the background. Data flows into a ring buffer from a background thread as soon as this returns, so a subsequent read_window will have samples waiting. The session keeps running until stop_stream is called.

NameTypeReqDescription
boardstringBoard name ('synthetic', 'cyton', 'muse_2', ...) or numeric id. Call list_boards to see the options.
channelsOptional subset of BrainFlow EEG row indices. Defaults to all.
paramsBrainFlow connection settings, e.g. {"serial_port": "COM3"} for a Cyton, {"mac_address": "..."} for a Muse, or {"file": "rec.csv", "master_board": "cyton"} for PLAYBACK_FILE_BOARD.
session_idstringyesName you will pass to every later call for this stream.

Structured output declared, but exposes no named fields.

No examples provided.

stim_status ~35

Report attached stimulation backends, arming state, and dispatch counts.

NameTypeReqDescription
session_idstringyesThe session to report on.

Structured output declared, but exposes no named fields.

No examples provided.

stop_monitor ~33

Close a session's live monitor and free its port.

NameTypeReqDescription
session_idstringyesThe session whose monitor to stop.

Structured output declared, but exposes no named fields.

No examples provided.

stop_recording ~133

Finish the recording, write the ``.fif``, and register it for analysis. The event log becomes annotations inside the file, and -- unless you pass ``register=false`` -- a row is inserted into the metadata store with the subject, task, run and provenance, so neuro-mcp can find and open it.

NameTypeReqDescription
keep_sidecarbooleanKeep the raw crash-recovery files after conversion. Normally removed once the .fif is safely written.
registerbooleanInsert the recording into the metadata database.
session_idstringyesThe session whose recording to finish.

Structured output declared, but exposes no named fields.

No examples provided.

stop_stream ~57

Stop a stream and release the board, serial ports, and LSL outlets. Always call this when finished. A board left prepared can block the next process from acquiring the device.

NameTypeReqDescription
session_idstringyesThe stream to stop.

Structured output declared, but exposes no named fields.

No examples provided.

stream_status ~89

Health and timing report for a session. The fields that matter for closed-loop work: ``throughput_ratio`` below 1.0 means the producer is not keeping up and samples are being dropped; ``filters.group_delay_sec`` is how far behind real time a filtered feature is; ``last_error`` explains a stopped producer.

NameTypeReqDescription
session_idstringyesThe session to report on.

Structured output declared, but exposes no named fields.

No examples provided.

Common questions

What is the io.github.AImplifier/eeg-mcp server?

io.github.AImplifier/eeg-mcp is listed in the public MCP registry as io.github.AImplifier/eeg-mcp. Real-time EEG: BrainFlow streaming, wall-clock replay, online DSP, recording, and stimulation. This page covers its PyPI package (eeg-mcp).

Is the io.github.AImplifier/eeg-mcp server safe to use?

io.github.AImplifier/eeg-mcp scores 78 out of 100 on VerifyMCP. We recorded 2 known advisories against it as of 20 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the io.github.AImplifier/eeg-mcp server expose?

io.github.AImplifier/eeg-mcp exposes 47 tools: list_boards, start_stream, stop_stream, list_sessions, stream_status, and 42 more. Their descriptions and schemas cost roughly 5,852 tokens of context every time the server is loaded.

Is the io.github.AImplifier/eeg-mcp server still maintained?

io.github.AImplifier/eeg-mcp is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What licence is the io.github.AImplifier/eeg-mcp server under?

io.github.AImplifier/eeg-mcp declares the BSD-3-Clause licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.