Ephys
PYPI · EPHYS-MCP
Read-only analysis of intracortical BCI recordings (NWB, DANDI, WAV): spikes, PSTHs, decoding, plots
Available components
Last scanned (22 hours ago)
Scores higher than 78% of PyPI servers
Category Health and Science
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 Security100
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- Runs uv_build at install time, a recognised build step with no custom scripting around it. View diagnostics → Pass
- 2 of 54 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency32
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- License check failed: the license (CC0-1.0) isn't a recognized OSI-approved license. See how to fix → Fail
- Actively maintained (last published 30 days ago).Pass
- Disclosure check failed: no security disclosure policy was found in the source repository. See how to fix → Fail
Schema Quality & AI Usability80
- 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
- AI-judged instruction clarity (good).Pass
- Tool/resource definitions use about 2000 tokens (~80/item across 25 items; 24 tools + 1 resources), lean.Pass
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
- No destabilizing schema changes in the last 30 days.Pass
Tool Coverage67
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 0% of tool parameters carry a description.Fail
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 24 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 26 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
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.
- 22 Oct 26 0
- Stability: 0.97 → pass security
- 21 Oct 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.
- 19 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 87 to 90. That category is still filling its 30-day observation window: 26 days of observed history at the previous scan, 27 at this one. The score rises as the window fills, whether or not the server changes.
- 17 Oct 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.
- 15 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 73 to 77. That category is still filling its 30-day observation window: 22 days of observed history at the previous scan, 23 at this one. The score rises as the window fills, whether or not the server changes.
- 13 Oct 26 +12
- Known CVEs: unverified → pass ▲ security
- Dependency health: unverified → 0.98 ▲ functional
- 12 Oct 26 −10
- Known CVEs: pass → unverified ▼ security
- Dependency health: 0.98 → unverified ▼ functional
- 8 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 47 to 53. That category is still filling its 30-day observation window: 14 days of observed history at the previous scan, 16 at this one. The score rises as the window fills, whether or not the server changes.
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 23 Oct 2026 · Analysed pypi/ephys-mcp@0.5.1
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | pypi |
| Reason | No attestation published |
Background: How many MCP packages publish verified provenance →
Install scripts 1 script
| Hook | Tier | Command |
|---|---|---|
| build_backend | allowlisted | uv_build |
Background: Why install scripts are a supply-chain risk →
Dependencies 54 packages
| Packages resolved | 54 |
|---|---|
| Stale | 1 |
| No linked repository | 1 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
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 →
close_session ~27
Close a session and drop any decoder fitted on it.
| Name | Type | Req | Description |
|---|---|---|---|
| session_id | string | yes | – |
No output schema declared.
No examples provided.
decode_window ~60
Decode a window with the fitted decoder; returns a downsampled decoded-vs-true preview.
| Name | Type | Req | Description |
|---|---|---|---|
| duration_s | number | – | – |
| max_points | integer | – | – |
| session_id | string | yes | – |
| t0 | number | yes | – |
No output schema declared.
No examples provided.
detect_spikes ~71
Threshold-crossing spike detection on a broadband snippet (max 10 s). Where the session has ground-truth spikes, precision and recall are reported.
| Name | Type | Req | Description |
|---|---|---|---|
| duration_s | number | – | – |
| session_id | string | yes | – |
| t0 | number | – | – |
| threshold_sigma | number | – | – |
No output schema declared.
No examples provided.
evaluate_cross_session ~148
Fit a decoder on one session and score it, unchanged, on other sessions: the question benchmarks such as FALCON ask (does a decoder survive to a later day?). All sessions must be open and share the same units/channels. `mask` names a boolean behaviour signal restricting which bins are scored (FALCON files carry `eval_mask`; pass null when the sessions have none). Also reports same-session held-out R² for comparison.
| Name | Type | Req | Description |
|---|---|---|---|
| bin_s | number | – | – |
| kind | string | – | – |
| mask | – | – | – |
| target | – | – | – |
| test_session_ids | array | yes | – |
| train_session_id | string | yes | – |
No output schema declared.
No examples provided.
fit_decoder ~136
Fit a decoder from spike counts to a behaviour signal and score it on held-out data. The first `train_fraction` of the session trains; the remainder tests. With no `target`, the first velocity-like behaviour signal is used. Unrecorded gaps are skipped. `mask` names a boolean behaviour signal (such as FALCON's eval_mask); only bins where it is true are used for fitting and scoring.
| Name | Type | Req | Description |
|---|---|---|---|
| bin_s | number | – | – |
| kind | string | – | – |
| mask | – | – | – |
| session_id | string | yes | – |
| target | – | – | – |
| train_fraction | number | – | – |
No output schema declared.
No examples provided.
fit_latent_factors ~170
Fit low-dimensional latent factors to trial-aligned population activity. GPFA (Yu et al. 2009) gives denoised single-trial trajectories and a timescale per factor; PCA is the fast, noisier baseline. Look for an elbow in variance_explained_per_factor to judge dimensionality. If the session has a velocity-like signal, reports how well the top factors explain it. Then plot_latent_factors draws the trajectories.
| Name | Type | Req | Description |
|---|---|---|---|
| bin_s | number | – | – |
| event | – | – | – |
| group_by | – | – | – |
| method | string | – | – |
| n_factors | integer | – | – |
| session_id | string | yes | – |
| t_after | number | – | – |
| t_before | number | – | – |
| units | – | – | – |
No output schema declared.
No examples provided.
get_firing_rates ~47
Population firing-rate summary over a time range (defaults to the whole session).
| Name | Type | Req | Description |
|---|---|---|---|
| session_id | string | yes | – |
| t0 | number | – | – |
| t1 | – | – | – |
No output schema declared.
No examples provided.
get_probe ~63
Contact geometry and brain-area labels per channel, where known. Use the `channel` indices with the `units` argument of get_psth / fit_latent_factors to analyse one area.
| Name | Type | Req | Description |
|---|---|---|---|
| max_rows | integer | – | – |
| session_id | string | yes | – |
No output schema declared.
No examples provided.
get_psth ~178
Peri-stimulus time histogram: firing aligned to a trial event and averaged over trials. `event` is one of the session's event_columns (default: movement onset if present). `group_by` splits trials by one of its group_columns, e.g. reach direction. `units` restricts the analysis to some units; tuning that cancels in the population average (such as direction preference) only shows up per unit. Unit numbers in the result index into `units` when it is given. Returns the population time course, its peak, and the units that change most.
| Name | Type | Req | Description |
|---|---|---|---|
| bin_s | number | – | – |
| event | – | – | – |
| group_by | – | – | – |
| session_id | string | yes | – |
| t_after | number | – | – |
| t_before | number | – | – |
| units | – | – | – |
No output schema declared.
No examples provided.
get_session_info ~36
Metadata for a session: duration, channels, sampling rates, behaviour signals, licence, citation.
| Name | Type | Req | Description |
|---|---|---|---|
| session_id | string | yes | – |
No output schema declared.
No examples provided.
get_signal_quality ~53
Noise level, SNR and dead/noisy channels from a broadband snippet (max 10 s).
| Name | Type | Req | Description |
|---|---|---|---|
| duration_s | number | – | – |
| session_id | string | yes | – |
| t0 | number | – | – |
No output schema declared.
No examples provided.
get_stream_status ~37
For a live session: how much signal is buffered, whether data is still arriving, and drops.
| Name | Type | Req | Description |
|---|---|---|---|
| session_id | string | yes | – |
No output schema declared.
No examples provided.
list_dataset_files ~59
Licence, citation and NWB files of a DANDI dataset. Pass a file's path to open_session(source='dandi').
| Name | Type | Req | Description |
|---|---|---|---|
| dandiset_id | string | yes | – |
| limit | integer | – | – |
| version | string | – | – |
No output schema declared.
No examples provided.
list_lsl_streams ~35
Lab Streaming Layer streams visible on the local network (needs the lsl extra).
| Name | Type | Req | Description |
|---|---|---|---|
| wait_s | number | – | – |
No output schema declared.
No examples provided.
list_sources ~24
List the data source types this server can open, with their parameters and status.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
open_session ~46
Open a recording session and return its session_id and metadata. `params` overrides the source's default_params (see list_sources).
| Name | Type | Req | Description |
|---|---|---|---|
| params | – | – | – |
| source | string | – | – |
No output schema declared.
No examples provided.
plot_decoding ~70
Figure: decoded against actual behaviour for a window (max 60 s), one panel per dimension. Requires fit_decoder first. Pick a window in the test split for an honest picture.
| Name | Type | Req | Description |
|---|---|---|---|
| duration_s | number | – | – |
| session_id | string | yes | – |
| t0 | number | yes | – |
No output schema declared.
No examples provided.
plot_latent_factors ~73
Figure: the top three latent factors over time (single trials thin, group means bold), the trajectory in the plane of the first two factors, and variance explained per factor. Requires fit_latent_factors first.
| Name | Type | Req | Description |
|---|---|---|---|
| max_trials_drawn | integer | – | – |
| session_id | string | yes | – |
No output schema declared.
No examples provided.
plot_probe ~75
Figure: the array map, each contact coloured by its firing rate over a window, with area labels and sorted units marked when a sort has been run. Needs geometry from the file or set_probe_geometry.
| Name | Type | Req | Description |
|---|---|---|---|
| duration_s | number | – | – |
| session_id | string | yes | – |
| t0 | number | – | – |
No output schema declared.
No examples provided.
plot_psth ~99
Figure: population PSTH per group (mean ± SEM over trials) above a unit-by-time heatmap of change from baseline. Same arguments as get_psth. Returns the PNG path and the image.
| Name | Type | Req | Description |
|---|---|---|---|
| bin_s | number | – | – |
| event | – | – | – |
| group_by | – | – | – |
| session_id | string | yes | – |
| t_after | number | – | – |
| t_before | number | – | – |
| units | – | – | – |
No output schema declared.
No examples provided.
plot_raster ~62
Figure: spike raster for a time window (max 60 s), with unrecorded spans shaded.
| Name | Type | Req | Description |
|---|---|---|---|
| duration_s | number | – | – |
| max_units | integer | – | – |
| session_id | string | yes | – |
| t0 | number | – | – |
No output schema declared.
No examples provided.
search_datasets ~54
Search the DANDI Archive for datasets. An empty query returns a short curated list of intracortical datasets that work well with this server.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | – |
| query | string | – | – |
No output schema declared.
No examples provided.
set_probe_geometry ~162
Tell the server where the recording's contacts are, for sessions whose file does not say. Named layouts: 'utah' (square grid, e.g. 96 contacts at 400 um), 'grid' with n_columns, 'linear' (one column at pitch_um, e.g. a laminar probe), 'tetrode_linear' (groups of four). 'explicit' takes positions_um as [[x, y], ...] in channel order. Geometry is used by sort_spikes and plot_probe. Contacts under 100 um apart are sorted jointly.
| Name | Type | Req | Description |
|---|---|---|---|
| layout | string | – | – |
| n_columns | integer | – | – |
| pitch_um | number | – | – |
| positions_um | – | – | – |
| session_id | string | yes | – |
No output schema declared.
No examples provided.
sort_spikes ~135
Spike-sort a broadband window (needs the sort extra). Afterwards the session's spike times are the sorted units, restricted to that window, so rates, PSTHs, rasters and decoders use them. Uses the session's probe geometry (from the file or set_probe_geometry) so nearby contacts are sorted jointly; without geometry each channel is treated as an independent electrode. Sorting takes seconds to a few minutes depending on duration and channel count.
| Name | Type | Req | Description |
|---|---|---|---|
| channels | – | – | – |
| duration_s | number | – | – |
| session_id | string | yes | – |
| sorter | string | – | – |
| t0 | number | – | – |
No output schema declared.
No examples provided.
How do I install the Ephys MCP server?
Ephys runs locally as a PyPI package, launched with uvx ephys-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 · ephys-mcp
claude mcp add happyc0der-ephys-mcp -- uvx ephys-mcp
What is the Ephys MCP server?
Ephys is an MCP server listed in the public MCP registry as io.github.happyc0der/ephys-mcp. Read-only analysis of intracortical BCI recordings (NWB, DANDI, WAV): spikes, PSTHs, decoding, plots. This page covers its PyPI package (ephys-mcp).
Is the Ephys MCP server safe to use?
Ephys scores 80 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 23 October 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 Ephys MCP server expose?
Ephys exposes 24 tools: list_sources, open_session, close_session, get_session_info, get_signal_quality, and 19 more. Their descriptions and schemas cost roughly 1,920 tokens of context every time the server is loaded.
Is the Ephys MCP server still maintained?
Ephys is still listed as active in the MCP registry. We last reached this channel on 23 October 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 Ephys MCP server under?
Ephys declares the CC0-1.0 licence, which is not on the OSI-approved list. Read the terms before using it at work, and note this covers the source only, not the cost of any service it calls.