ephys-mcp

Análise somente leitura de gravações de BCI intracortical (NWB, DANDI, WAV): spikes, PSTHs, decodificação, gráficos.

Documentação

ephys-mcp

Um servidor MCP que permite a um LLM analisar gravações de interface cérebro-computador intracortical (nível de pico neural): qualidade do sinal, detecção de picos, taxas de disparo e decodificação de velocidade do cursor.

Os servidores MCP de BCI existentes têm como alvo o EEG de couro cabeludo. Este tem como alvo o tipo de dados que um implante de alta contagem de canais produz e define um contrato de adaptador somente leitura para que um backend de dispositivo ao vivo possa ser adicionado quando um fornecedor publicar uma API.

Software de pesquisa e educação. Não é um dispositivo médico. Não é para uso clínico. Não é afiliado ou endossado pela Neuralink Corp. ou qualquer outro fabricante de implantes.

Exemplo de saída

Figuras da fonte sintética integrada (32 unidades, 300 s, semente 2), produzidas pelas próprias ferramentas de plotagem do servidor.

PSTH by reach directionKalman decoder on held-out data
plot_psth agrupado por direção de alcance: taxa populacional por direção (média ± SEM em 166 tentativas) acima de um heatmap unidade-por-tempo da mudança em relação à linha de baseplot_decoding após fit_decoder(kind="kalman"): decodificado contra a velocidade real do cursor em uma janela de 10 s retida, R² 0,90 (x) e 0,83 (y)

Status

v0.5. O conjunto de recursos planejado está completo: arquivos NWB locais, gravações WAV de banda larga locais, fluxos Lab Streaming Layer ao vivo, streaming do DANDI Archive, uma fonte sintética de córtex motor com verdade fundamental, detecção de picos, métricas de qualidade, decodificadores ridge e Kalman, PSTHs alinhados a tentativas, ordenação de picos, avaliação entre sessões (estilo FALCON), modelos de fatores latentes (GPFA, PCA), geometria de sonda e figuras. 24 ferramentas. Relatórios de bugs e solicitações de recursos vão para GitHub Issues.

Instalação e execução

Requer uv. Sem etapa de instalação: uvx ephys-mcp busca o pacote e inicia o servidor no stdio.

Claude Code:

claude mcp add ephys -- uvx ephys-mcp

Claude Desktop (claude_desktop_config.json):

{ "mcpServers": { "ephys": { "command": "uvx", "args": ["ephys-mcp"] } } }

A partir de um checkout, use uv run ephys-mcp em vez disso, ou uv --directory /path/to/ephys-mcp run ephys-mcp nas configurações acima.

Transporte HTTP

Para clientes remotos ou agentes hospedados, sirva HTTP transmitível em vez de stdio:

EPHYS_MCP_TOKEN='a-long-random-secret' uvx ephys-mcp --http --host 0.0.0.0 --port 8000

Cada solicitação deve então conter Authorization: Bearer <token>. O servidor se recusa a vincular a um endereço não loopback sem um token, e os tokens devem ter pelo menos 16 caracteres. Coloque TLS na frente dele (um proxy reverso) antes de expô-lo além de uma rede privada: o token viaja em texto claro caso contrário. Em loopback, o token é opcional, então ephys-mcp --http sozinho serve http://127.0.0.1:8000/mcp para testes locais.

Então pergunte, para dados reais: "Encontre um pequeno conjunto de dados de córtex motor no DANDI, abra-o e me diga quão bem a velocidade da mão pode ser decodificada." Ou offline: "Abra uma sessão sintética, verifique a qualidade do sinal, ajuste um decodificador Kalman e mostre-me uma janela decodificada."

Fontes de dados

FonteO que abre
syntheticUnidades simuladas ajustadas à velocidade do cursor, com sinal de banda larga e verdade fundamental
nwbUm arquivo .nwb local (params.path)
wav_dirWAV de banda larga local (params.path): uma pasta de clipes mono, um canal cada, ou um arquivo multicanal
lslUm fluxo de banda larga Lab Streaming Layer ao vivo na rede local; mantém o sinal mais recente de buffer_s. Requer uvx --with 'ephys-mcp[lsl]' ephys-mcp
dandiUm arquivo NWB transmitido do DANDI Archive por solicitações de intervalo HTTP; nada é espelhado
n1_stubNão implementado. Documenta como um adaptador de implante ao vivo seria escrito na mesma base que lsl

A licença e a citação do conjunto de dados vêm do arquivo e são retornadas por open_session, para que o modelo possa atribuir os dados. Muitos conjuntos de dados gravam apenas durante tentativas; o servidor rastreia esses intervalos (recorded_fraction) e deixa as lacunas fora das taxas e da decodificação em vez de lê-las como silêncio.

As amostras WAV não carregam unidade física, então as amplitudes são relatadas como contagens de ADC, a menos que você passe uv_per_count; cada resultado de amplitude nomeia sua unidade. Clipes em uma pasta são gravações separadas, então o servidor diz que o tempo entre esses canais não é significativo. Os tempos de pico de WAV são cruzamentos de limiar, não unidades ordenadas.

Resultados de referência, todos baselines lineares causais simples em vez de estado da arte:

  • MC_Maze_Small (DANDI 000140, 142 unidades, últimos 20% retidos, bins de 50 ms): ridge R² 0,50, Kalman R² 0,34 para velocidade da mão.
  • FALCON H1 (DANDI 000954, velocidade humana de 7 graus de liberdade, 176 canais, bins de 20 ms, eval_mask): ridge treinado no primeiro dia mantido pontua R² 0,43 no minival desse dia, 0,07 uma semana depois e abaixo de zero nos dias retidos. Esse decaimento é o ponto do benchmark; o filtro de Kalman é inadequado para esses dados de calibração roteirizados. Os rótulos de teste oficiais do FALCON são privados, então estes não são pontuações de leaderboard.

Os hiperparâmetros do decodificador (força ridge, lead neural para Kalman) são escolhidos por validação cruzada bloqueada dentro da divisão de treinamento. O histórico ridge é de 0,5 s de contagens de picos, independentemente do tamanho do bin.

GPFA é implementado a partir das equações do artigo em numpy e scipy (EM sobre cargas, deslocamentos, ruído e escalas de tempo por fator; sem dependência de aprendizado profundo) e roda em segundos em cem tentativas. No simulador, cuja verdadeira latente é a velocidade do cursor 2-D, ele encontra dois fatores dominantes que explicam a velocidade com R² 0,95 (PCA: 0,68). No MC_Maze_Small, mostra a trajetória populacional rotativa em torno do início do movimento pela qual o córtex motor é conhecido. Modelos da classe LFADS estão fora do escopo: eles precisam de uma execução de treinamento de minutos e uma pilha de aprendizado profundo.

Ferramentas

FerramentaPropósito
list_sourcesTipos de fonte e seus parâmetros
search_datasetsPesquisar DANDI, ou listar conjuntos de dados intracorticais selecionados
list_dataset_filesLicença, citação e arquivos NWB de um conjunto de dados DANDI
list_lsl_streamsFluxos LSL visíveis na rede
get_stream_statusPara uma sessão ao vivo: intervalo armazenado em buffer, se os dados estão chegando, quedas
open_session / close_sessionCiclo de vida da sessão
get_session_infoCanais, taxas, sinais de comportamento, licença, citação
get_signal_qualityRuído, SNR, canais mortos/ruidosos
detect_spikesCruzamentos de limiar; precisão/revocação quando a verdade existe
sort_spikesOrdenar picos de uma janela de banda larga com spikeinterface (extra sort), usando geometria de sonda quando conhecida; a sessão então usa as unidades ordenadas
set_probe_geometryFornecer posições de contato para uma sessão cujo arquivo não tem nenhuma: layouts Utah, grade, linear, tetrodo ou coordenadas explícitas
get_probePosições de contato e rótulos de área cerebral por canal
plot_probeFigura: mapa do array, contatos coloridos por taxa de disparo, unidades ordenadas por contato
get_firing_ratesResumo da taxa populacional
fit_decoderRidge ou Kalman, pontuado em dados retidos; hiperparâmetros escolhidos dentro da divisão de treinamento
decode_windowPré-visualização decodificado-vs-real para uma janela
evaluate_cross_sessionAjustar em uma sessão, pontuar inalterado em outras: um decodificador sobrevive até um dia posterior? Honra o eval_mask do FALCON
get_psthDisparo alinhado a um evento de tentativa, opcionalmente agrupado por uma coluna de tentativa ou limitado a algumas unidades
fit_latent_factorsGPFA (Yu et al. 2009) ou PCA em atividade alinhada a tentativas: trajetórias latentes de tentativa única, variância por fator, escalas de tempo e quão bem os principais fatores explicam um sinal de velocidade
plot_latent_factorsFigura: três principais fatores ao longo do tempo, o espaço de estado fator-1/fator-2 e variância por fator
plot_psthFigura: PSTH por grupo com SEM, acima de um heatmap unidade-por-tempo da mudança em relação à linha de base
plot_rasterFigura: raster de picos, intervalos não gravados sombreados
plot_decodingFigura: decodificado contra comportamento real, um painel por dimensão

Recurso: ephys://sessions. Prompts: analyze_session, falcon_evaluate.

As ferramentas retornam resumos, nunca arrays brutos, para que os resultados caibam no contexto de um modelo.

Extras opcionais

ExtraAdicionaInstalação
lsla fonte ao vivo lsluvx --with 'ephys-mcp[lsl]' ephys-mcp
sortsort_spikes via ordenadores integrados do spikeinterface (spykingcircus2, tridesclous2); cerca de 330 MB de dependênciasuvx --with 'ephys-mcp[sort]' ephys-mcp

A ordenação usa a geometria da sonda da sessão, da tabela de eletrodos do arquivo ou de set_probe_geometry, para que contatos a menos de 100 µm de distância sejam ordenados em conjunto. Isso importa em sondas densas: em uma sonda laminar simulada de 20 µm, ordenar com a geometria verdadeira encontra as 12 unidades reais, enquanto tratar contatos como independentes relata 15, contando a mesma unidade novamente em contatos vizinhos. Sem geometria, os canais são colocados bem separados e tratados como eletrodos isolados. No simulador, o spykingcircus2 recupera todas as unidades com revocação acima de 0,95.

Os rótulos de área cerebral vêm da tabela de eletrodos NWB quando presente (MC_Maze relata PMd e M1); get_probe os lista por canal para que uma análise possa ser restrita a uma área com o argumento units. Observe que nenhum dos conjuntos de dados DANDI testados até agora armazena coordenadas de contato, então para esses, set_probe_geometry é a maneira de fornecer um layout de array.

As ferramentas de plotagem retornam o PNG inline, para que um modelo com capacidade de visão possa ler a figura, e também o salvam em ~/.cache/ephys-mcp/plots (substituível com EPHYS_MCP_OUTPUT_DIR). As figuras usam uma paleta categórica verificada para separação de daltonismo, com rótulos diretos para que a identidade nunca dependa apenas da cor.

Regras de design

  • Somente leitura. O contrato NeuralSource não tem método de escrita, estimulação ou configuração. Nenhum será adicionado sem um design de segurança separado.
  • Local por padrão. Transporte stdio, sem telemetria. HTTP é opcional e protegido por token. Dados neurais são sensíveis.
  • Sem dados de terceiros incluídos. Veja DATA_LICENSES.md.

Escrevendo um adaptador de fonte

Para gravações, subclassifique ephys_mcp.sources.base.NeuralSource (info, read_raw, spike_times, behavior). Para um dispositivo ao vivo, subclassifique ephys_mcp.sources.live.RingBufferSource e chame push(samples) de uma thread de leitura; sources/lsl.py é um exemplo completo em cerca de 60 linhas, e sources/n1_stub.py lista o que um adaptador de implante precisaria adicionalmente. Registre a classe em ephys_mcp/sources/__init__.py.

Sessões ao vivo relatam o tempo em segundos desde a abertura, e apenas o buffer mais recente é legível, então t_start_s e duration_s avançam.

Desenvolvimento

uv run pytest              # offline
uv run pytest -m network   # also streams a real file from DANDI
uv run ruff check .

Citação

Veja CITATION.cff; o botão "Cite this repository" do GitHub o usa. Cite os conjuntos de dados que você analisa separadamente: get_session_info retorna a citação de cada um.

Licença

CC0 1.0 Universal. Os autores renunciam a todos os direitos autorais e direitos relacionados na medida permitida por lei. Use para qualquer coisa, sem atribuição necessária. CC0 não concede direitos de patente ou marca registrada.