
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
intelliboard-mcp
Advanced tools
MCP server do Kanban Intelliboard — dirija seu board pelo Claude Code / opencode.
MCP server do Kanban do Intelliboard. Pluga no Claude Code, opencode ou qualquer cliente MCP e deixa o agente criar cards estruturados, ler o board, mover/ atualizar cards e marcar como concluído — com validação imposta antes de concluir.
Zero variável de ambiente obrigatória. Auth por device flow e vínculo local de workspace; arquivo no repo só é necessário para self-host ou para configurar o gate de validação.
Registre o servidor no seu agente — um comando:
# Claude Code
claude mcp add intelliboard -- npx -y intelliboard-mcp
# Codex
codex mcp add intelliboard -- npx -y intelliboard-mcp
# opencode (prompt interativo → Type: Local · Command: npx -y intelliboard-mcp)
opencode mcp add
Aponta pra https://intelliboard.aglissilva.dev por padrão. Local/self-host: veja apiUrl abaixo.
Sem argumentos, o binário roda o servidor MCP em stdio — é assim que o agente o inicia.
Com --help ele lista os subcomandos e imprime o caminho real desta instalação; qualquer
subcomando desconhecido falha com essa mesma ajuda, em vez de subir um servidor stdio que
fica pendurado esperando um cliente.
A ordem importa: prepare primeiro, reinicie depois.
check_update → há versão nova?
prepare_update → baixa e prepara AGORA, com a sessão ainda de pé
(depois disso, reabra a sessão do agente)
O processo em execução não se auto-substitui: a versão nova entra ao reabrir a sessão. Sem o preparo, quem baixa é o próprio startup do cliente — e uma instalação fria são ~46 MB e 91 pacotes. Se ela não terminar dentro da janela de startup, o cliente desiste e a sessão abre sem nenhuma tool do Intelliboard. Preparando antes, o start vira cache hit (medido: 4,0s a frio contra 0,57s aquecido).
Equivalente no terminal:
npx -y --prefer-online intelliboard-mcp --version
Não use npx clear-npx-cache: além de garantir o start frio, ele zera o cache de todos os
outros servidores MCP que você instalou por npx. --prefer-online já revalida a versão
publicada reaproveitando os tarballs. E o spec vai sem versão fixada, igual ao que o
cliente lança — o npx guarda a instalação num diretório derivado do spec, então aquecer
intelliboard-mcp@1.2.3 deixaria o lançamento sem versão reinstalando assim mesmo.
Não é preciso relogar: o token do device flow persiste.
Se você prefere eliminar o npx do caminho crítico do startup, instale global e aponte o cliente para o binário — aí o start não depende de instalação nenhuma:
npm i -g intelliboard-mcp
claude mcp add intelliboard -- intelliboard-mcp
Sem terminal. No agente:
login e devolve uma URL + código./device), aprove o dispositivo. É o único passo humano.intelliboard_status e confirma (authenticated: true).O token fica em ~/.config/intelliboard/credentials.json (modo 0600), dura ~7 dias;
refaça login quando expirar. (Alternativa CLI: npx intelliboard-mcp login.)
O vínculo de organização/board não precisa ficar no repositório. Pelo agente, o ciclo inteiro é MCP — nenhum passo sai para o terminal:
list_organizations → descobre as orgs
list_boards({ allOrganizations: true }) → descobre os boards, sem trocar de escopo
link_workspace({ organization: "Python Backend", board: "API" })
link_workspace aceita nome ou id, e o campo pode ser omitido quando só há uma opção
acessível. O board é procurado dentro da organização já resolvida, então um par
cruzado (org de um lado, board de outro) não chega a existir — não é recusado depois, é
impossível de montar. Faltando informação ou havendo ambiguidade, a tool devolve
candidates tipados em vez de escolher sozinha:
{ "ok": false, "code": "BOARD_REQUIRED", "field": "board",
"organization": { "id": "org-…", "name": "Python Backend" },
"candidates": [{ "id": "board-…", "name": "API" }, { "id": "board-…", "name": "Infra" }] }
As demais tools do ciclo: workspace_status (vínculo atual e validade),
list_workspace_links (todos os workspaces vinculados nesta máquina) e
unlink_workspace.
Pelo terminal, o mesmo ciclo existe no CLI:
intelliboard-mcp workspace link # escolhe interativamente
intelliboard-mcp workspace link --org "Minha org" --board Produto # confirma com `yes`
intelliboard-mcp workspace link --org "Minha org" --board Produto --yes
intelliboard-mcp workspace status
intelliboard-mcp workspace list
intelliboard-mcp workspace unlink --yes
--yes (ou --non-interactive) dispensa a confirmação digitada e permite rodar sem TTY,
em script ou CI. Sem TTY e sem --yes, o comando falha na hora, antes de qualquer
chamada remota — não fica esperando um prompt que ninguém vai responder.
Se
intelliboard-mcpnão existir no PATH: é o esperado quando o servidor foi instalado comonpx -y intelliboard-mcp— o binário fica dentro do cache do npx. Não vá atrás do cache: rode--helppelo mesmo caminho que o agente usa, ou simplesmente use as tools MCP acima. Toda mensagem do MCP que sugere um comando já imprime o caminho real desta instalação, pronto para colar.
O vínculo guarda IDs estáveis em ~/.config/intelliboard/workspaces.json (modo 0600,
escrita atômica e lock). Ele vale imediatamente para processos MCP já abertos e é isolado
por API, identidade Git e raiz local — worktrees do mesmo repositório podem usar boards
diferentes.
O vínculo é local à máquina e nunca sai dela — nenhuma chamada de rede escreve esse
estado. Quatro pessoas no mesmo board, cada uma com o repositório clonado num caminho
diferente, ficam isoladas por construção: a chave é (API, identidade Git, raiz local), e
cada ~/.config é o seu. A escolha de board de uma pessoa não alcança as outras, e cada
uma vincula uma vez na própria máquina.
O controle de acesso continua sendo do backend: o vínculo só carrega IDs, e quem não é
membro da organização não passa. Se o board vinculado sair do alcance da conta, o status
marca stale em vez de cair silenciosamente em outro board.
Duas coisas a saber quando várias contas dividem a mesma máquina:
login substitui a anterior.intelliboard_status avisa quando o vínculo é de outra conta, e
workspace_status expõe isso em linkedByAnotherUser. Vínculos gravados antes deste
campo seguem válidos, apenas sem o aviso.A precedência é:
select da sessão > vínculo do workspace > config legada > board/org ativos no app
link_workspace limpa o select da sessão ao gravar: sem isso o vínculo novo ficaria
sombreado por uma seleção anterior e o status mostraria outro board.
Se o board vinculado for removido ou o usuário perder acesso, o MCP não cai silenciosamente
no board ativo. workspace_status e intelliboard_status marcam o vínculo como stale.
Cada processo MCP aberto registra uma sessão local independente. Isso permite distinguir dois agentes do mesmo usuário trabalhando simultaneamente, inclusive no mesmo board:
intelliboard-mcp sessions list
intelliboard-mcp sessions list --all-workspaces
intelliboard-mcp sessions list --remote
intelliboard-mcp sessions show <session-id>
intelliboard-mcp activity list
intelliboard-mcp activity follow
intelliboard-mcp activity list --session <session-id> --limit 100
Os estados observáveis são idle, claiming, working, validating,
waiting_approval, completing, committing, blocked e closed. sessions list
marca uma sessão como stale quando o processo local morreu ou deixou de atualizar o
runtime por mais de cinco minutos. O CLI nunca encerra processos nem executa comandos.
O histórico local fica em ~/.config/intelliboard/runtime.json, modo 0600, com lock,
escrita atômica, retenção de 30 dias e limite de 10.000 eventos. Localmente, a sessão
contém PID, host e raiz do workspace para diagnóstico do próprio usuário. Eventos não
guardam comandos, títulos, caminhos ou conteúdo de aprovações.
--remote consulta os claims do board atual e mostra somente UUID da sessão, cliente,
estado, card e heartbeat. PID, host, workspace local, comandos e aprovações nunca são
enviados ao backend. Clientes antigos continuam funcionando: os três campos de runtime
são opcionais no claim e o heartbeat sem corpo permanece válido.
O gate de validação é o comando que complete_card exige antes de deixar um card chegar
a done. Configure uma vez por workspace. Pelo agente:
validation_status → diz se já há perfil e, se não houver, o que foi detectado do projeto
setup_validation → grava o perfil (detectado, ou o argv exato que você informar)
setup_validation({ commands: [{ executable: "bun", args: ["run", "validate"] }] }) grava
um gate explícito; sem commands, aceita a detecção. Nada é executado durante o setup.
Pelo terminal, o mesmo:
intelliboard-mcp validation setup # confirma com `yes`
intelliboard-mcp validation setup --yes # sem TTY, para script/CI
intelliboard-mcp validation setup -- bun run validate # argv explícito
intelliboard-mcp validation status
intelliboard-mcp validation reset --yes
Nada é criado no seu repositório. Não há validate.sh, não há arquivo de config
obrigatório, não há passo manual. A detecção lê o que o projeto já tem, e o perfil é
gravado fora do repo.
A regra da detecção é uma só: só propõe um comando quando o projeto dá evidência dele.
| projeto | detectado |
|---|---|
package.json com script validate | <runner> run validate |
package.json com lint/typecheck/test/build | os que existirem de fato |
Cargo.toml | cargo fmt --check · clippy · test |
go.mod | go vet ./... · go test ./... |
Django (manage.py) | python3 manage.py test |
pytest declarado (pytest.ini, [tool.pytest], tox.ini, requirements) | python3 -m pytest |
| há testes, sem pytest declarado | python3 -m unittest discover |
| sem evidência | nada — o agente informa commands |
O runner Python é resolvido no PATH: python3 quando existir, senão python. Em boa
parte dos sistemas python não existe, e propor python -m … ali gera um gate que morre
com command not found só na hora de concluir o card.
Quando não há evidência, a saída correta não é criar arquivo: é o agente ler o projeto
e chamar setup_validation({ commands: [...] }). Pelo terminal, o mesmo vem depois de --.
--yes só é lido antes de --: um comando validado que contenha --yes não decide a
própria confirmação.
O perfil fica fora do repositório, em ~/.config/intelliboard/validation.json (0600,
lock e escrita atômica), e registra quem o gravou. Perfil escrito por setup_validation
é marcado actor: "agent" e intelliboard_status avisa — configurar o próprio gate é
permitido, passar despercebido não. Regravar comandos idênticos preserva a autoria
original, então importar a config legada não reetiqueta nada.
Trocar por comandos diferentes um gate que o usuário escolheu exige
setup_validation({ ..., overwrite: true }). Configurar um workspace que ainda não tem
gate não exige nada disso.
Ao validar, o MCP cria um ticket vinculado ao card, sessão, perfil e conteúdo atual do código. O agente executa pela sua ferramenta nativa de terminal um comando desta forma:
<node-em-uso> <entrypoint-do-mcp> validation run <ticket> -- bun run validate
O trecho depois de -- é o comando real e fica visível na autorização do Codex/Claude.
O runner aceita somente a próxima etapa exata do ticket. HEAD, diff completo e arquivos
untracked entram no fingerprint; qualquer mudança depois da validação invalida o
comprovante. complete_card consome o comprovante somente depois que o card chega a done.
Só precisa de intelliboard.config.json para self-host (apiUrl) ou compatibilidade com
o gate legado (validate). Crie na raiz do repositório onde o agente roda:
{
"apiUrl": "http://localhost:3333",
"validate": {
"executable": "bash",
"args": ["scripts/validate.sh"]
}
}
apiUrl — backend do Intelliboard (default https://intelliboard.aglissilva.dev).validate — formato legado de comando. validation setup pode importá-lo para o
perfil local sem exigir que novos projetos mantenham esse arquivo.
Prefira { "executable", "args" }: os argumentos são enviados diretamente ao processo,
sem interpretação por shell. Strings continuam compatíveis, mas são marcadas e executadas
explicitamente como shell legado. complete_card bloqueia a conclusão se falhar.Os campos antigos org e board continuam aceitos como fallback de migração, mas novos
projetos devem usar workspace link.
| Tool | O que faz |
|---|---|
login / intelliboard_status | Autentica (device flow) e checa a conexão — tudo pelo chat. |
check_update / prepare_update / update | Checa versão nova, prepara o download antes do reinício (para o próximo start ser cache hit em vez de instalação fria) e explica o fluxo. |
workspace_status / list_workspace_links | Read-only: vínculo deste repositório (com validade contra o backend e precedência em vigor) e todos os workspaces vinculados nesta máquina. |
link_workspace / unlink_workspace | Vincula/desvincula este repositório a uma organização + board, por nome ou id. O board é buscado dentro da org resolvida — par cruzado não existe. Ambiguidade vira candidates tipados. Recusa com card em andamento. |
validation_status / setup_validation | Lê e grava o perfil de validação do workspace. Sem commands, aceita a detecção do projeto; nada é executado no setup. Substituir por comandos diferentes um gate escolhido pelo usuário exige overwrite: true. |
list_columns | Colunas do board (com role) + cards enxutos por padrão (sem description/executionReport/validationLog, que estouram o contexto). Peça os longos por nome via fields: ['description']. Filtros: summaryOnly (só contagem), sprintId, epic, limit (por coluna), columns. |
search_cards | Acha cards do board por texto (q, em título+descrição) e/ou filtra por epic/sprintId/mine. Resultado enxuto — a via barata num board grande, em vez de listar tudo. |
create_column / delete_column | Cria / remove coluna (role opcional). |
create_card | Cria card estruturado (leia o código antes; markdown com causa raiz, repro, critérios). Descrição: máx. 10.000 caracteres. Título com prefixo [tipo]. A confirmação é compacta e não ecoa a descrição. |
create_cards_bulk | Cria até 100 cards de uma vez (tudo-ou-nada). Aceita os mesmos campos do create_card. Para dependências internas, dê um ref ao pré-requisito e cite-o no dependsOn. A confirmação devolve somente contagem e identificação dos cards, sem ecoar descrições. |
update_card / move_card / delete_card | Edita / move / remove card. update_card altera também validationCommands, residualRisks, knownLimitations, securityNotes e os campos de verificação; null limpa campos textuais nullable e [] limpa comandos/dependências. Campos omitidos permanecem inalterados. Mover para doing faz o claim e o MCP alinha baseline+heartbeat ao resultado. As três respostas são compactas. |
validate | Prepara um ticket e devolve os comandos exatos para execução pela ferramenta nativa de terminal do agente. |
complete_card | Exige comprovante válido para o fingerprint atual e só então move para done. Exige verification (method + evidence). Aceita unverifiedClaims e workPrecededClaim. O fluxo legado já autorizado continua compatível. |
get_next_task | Pega o próximo card desbloqueado de todo (pula os com dependsOn não-done), trava por assignee e move para doing. |
claim_card | Pega um card por id, sem reordenar o board. Mesmo claim atômico e mesmo briefing do get_next_task; recusa card bloqueado, já concluído, com dependências abertas ou já pego por outro agente. Se o card já é seu, readota o claim preservando o baseline. |
amend_execution_report | Acrescenta uma correção datada ao executionReport. O texto original nunca é alterado. |
list_my_cards | Cards atribuídos a você + cards bloqueados por você, agrupados em { active, stalled, blocked, cards }. |
list_sprints / create_sprint / update_sprint / activate_sprint | Gerencia sprints. activate_sprint suporta dryRun (mostra o diff) e force (encerrar sprint com cards abertos). |
get_project_context | Lê o briefing do projeto. Retorna sempre { hasContext, text } — hasContext: false = board sem briefing (não é erro). |
log_decision / list_decisions | Registra decisão arquitetural no log append-only do board (exige confidence); lê o histórico com filtros source, q, cardId, epic, limit. |
As colunas todo/doing/done vêm do backend (board-config) pelo role da coluna
(definido na UI) — com fallback por nome. Sem env de coluna.
O manifesto tools/list acompanha toda requisição ao modelo, então tudo que entra
nele é custo fixo por turno. Hoje ele tem ~48 KB (~12.100 tokens). As decisões abaixo são
medidas, não estilísticas:
| decisão | custo por requisição |
|---|---|
annotations (leitura/destrutividade) em 46 tools | +442 tokens (3,8%) |
outputSchema nas 46 tools | +6.058 tokens (52%) — não adotado |
outputSchema é opcional na spec e o benefício dele (validação estrita) é colhido pelo
cliente, enquanto o custo é pago pelo contexto do modelo em todo turno. Numa sessão de 50
turnos seriam ~303.000 tokens para validar respostas que o agente já consome bem. As
annotations custam 27× menos e resolvem algo concreto: o cliente distingue leitura de
escrita e pode dispensar confirmação nas 16 tools somente-leitura.
structuredContent também não é grátis. A spec manda repetir o mesmo JSON no bloco de
texto por compatibilidade, então o campo duplica a resposta — medido, 708 B viram
1416 B.
O limite separa payload limitado de payload que cresce com os dados. Ele acompanha
respostas até 4 KB — status, confirmação de escrita, erro com code e candidates — e é
omitido acima disso, para um board grande não pagar duas vezes o que list_columns já
enxuga com summaryOnly e campos sob demanda. O teto tem folga deliberada sobre o maior
payload limitado que existe aqui: o intelliboard_status autenticado tem 1.735 B, e
2.045 B com três avisos. Um teste fixa esse formato, então um campo novo que se aproxime do
teto quebra a suíte em vez de fazer o contrato tipado sumir em silêncio.
Tools que devolvem array ficam de fora: o protocolo aceita só objeto, e envolver criaria uma segunda forma do mesmo dado.
O version.latest do status vem de um cache de 24 h, e o status informa
latestCheckedAt para o agente distinguir "não há versão nova" de "não olhei hoje". Um
cache mais antigo que a versão em execução é obsoleto de forma comprovável — acontece logo
depois de publicar — e é reconsultado em vez de exibir um "mais recente" menor que o atual.
complete_card exige um comprovante produzido pelo runner local para o conteúdo exato do
código. Saída ≠ 0, ticket expirado ou código alterado bloqueiam a conclusão. Sem perfil,
a conclusão retorna VALIDATION_SETUP_REQUIRED — com a tool que resolve
(setup_validation) e o comando de terminal equivalente já resolvido para esta
instalação. Sem comprovante, retorna VALIDATION_REQUIRED com os comandos exatos.
O broker abaixo permanece apenas para compatibilidade com perfis antigos já configurados:
intelliboard-mcp approvals list
intelliboard-mcp approvals show <id>
intelliboard-mcp approvals allow-once <id> # uma execução
intelliboard-mcp approvals allow-workspace <id> # este comando exato neste workspace
intelliboard-mcp approvals deny <id> # nega a solicitação
Quando a solicitação veio de uma sessão MCP observável, a aprovação inclui sessionId
e cardId. A decisão humana continua obrigatoriamente no terminal; observabilidade não
concede permissão e não executa a operação.
As decisões persistentes podem ser inspecionadas ou alteradas:
intelliboard-mcp permissions list
intelliboard-mcp permissions set validation ask
intelliboard-mcp permissions set validation allow
intelliboard-mcp permissions set validation deny
intelliboard-mcp permissions revoke validation
Alterações exigem TTY e confirmação digitada (yes). allow é limitado à identidade do
workspace, ao diretório e ao hash do comando; qualquer mudança volta a ask. O store fica em
~/.config/intelliboard/permissions.json, modo 0600, com escrita atômica e lock entre processos.
O comando intelliboard-mcp trust continua funcionando, mas está depreciado. Novos
workspaces devem usar validation setup e a autorização nativa do agente.
Branch e commit usam o mesmo broker, em capabilities separadas (git_branch e
git_commit). commit_card primeiro calcula todas as operações necessárias e não toca em
nenhum repositório enquanto houver uma aprovação pendente/negada. Permissões persistentes
para Git só nascem de uma solicitação exata:
intelliboard-mcp permissions set git_commit deny
intelliboard-mcp permissions set git_branch deny
intelliboard-mcp permissions revoke git_commit
permissions set git_commit allow é recusado por ser amplo demais; execute commit_card,
revise comando/diretório e use approvals allow-workspace <id>. set_git_mode continua
como preferência de fluxo (ask/auto/off), mas não concede autoridade de execução.
Para commits, a aprovação inclui lista de arquivos e hash do diff. Se o conteúdo ou a
branch mudar depois do preflight, a execução é abortada antes de qualquer mutação.
Quando complete_card falha por falta de mudanças desde o claim, o MCP devolve um erro
estruturado com code=NO_CHANGES_SINCE_CLAIM e inclui claimChanges tanto em
structuredContent quanto no fallback textual. O campo resolution distingue as duas
causas: baseline ausente (o claim não passou pelo MCP → rode claim_card) e nada
mudou (se o trabalho antecedeu o claim, reenvie com workPrecededClaim justificando —
a justificativa fica registrada no card, e o gate deixa de induzir commits de enfeite).
Um card vira fonte de verdade para a sessão seguinte: get_next_task entrega
recent_decisions e as afirmações do card ao próximo agente. Por isso o registro carrega
como cada coisa foi verificada, e não só o que foi concluído.
verification (obrigatório no complete_card) — method é measured (executado e
observado), tested (coberto por teste que passou no gate), reviewed (confirmado por
inspeção, sem executar) ou unverified (hipótese não confirmada). evidence exige o
comando rodado, a saída observada ou o arquivo:linha inspecionado.unverifiedClaims — afirmações do relatório que não foram verificadas. Entra no
preset lean das listagens: quem lê o card pelo caminho barato vê o aviso.executionReport é escrita única. Corrigir é acrescentar via
amend_execution_report; o texto original permanece, com data, autor e método da
correção ao lado. O backend recusa sobrescrita com 409 REPORT_IMMUTABLE.log_decision exige confidence. Decisões voltam ao próximo agente marcadas; as
não verificadas vêm com um aviso explícito no get_next_task.intelliboard_status também expõe workspace, readiness e modo de permissão da validação,
além de projectContext. get_next_task avisa antecipadamente se a conclusão dependerá de
aprovação, evitando a surpresa apenas no fim do card.
create_card.get_next_task → implementa →
complete_card (valida) → repete até acabar.claim_card <id> em vez de get_next_task — sem mexer na
ordenação do board, que é estado compartilhado.bun install
bun run dev # roda do source (stdio)
bun run typecheck # tsc --noEmit
bun run build # bundle publicável: dist/index.js, arquivo único
Runtime alvo: Node ≥ 18 (roda via npx/bunx). Publicação: npm publish
(ou bun publish); prepublishOnly reconstrói o bundle.
O pacote publicado tem zero dependências de runtime: scripts/build.ts embute o SDK e
o zod num arquivo só (~460 KB, tarball de ~150 KB). O SDK declara express, hono, cors, ajv
e jose como dependências duras, e um servidor stdio não alcança nenhuma — instalá-las
custava 91 pacotes e 46 MB dentro da janela de startup do cliente, que era o que fazia a
primeira sessão após atualizar abrir sem tool nenhuma. É o mesmo princípio do formato
.mcpb e da imagem Docker do GitHub MCP: nada é resolvido no startup.
Consequências que o build cobre: a versão é injetada em build time (__IB_VERSION__),
porque o arquivo único não tem ../package.json para ler; THIRD-PARTY-LICENSES é gerado
com os avisos dos 91 pacotes embutidos; e server.json — o metadado do registry oficial
MCP — tem a versão sincronizada. O CI executa o bundle e confere que ele serve as tools,
porque typecheck não pega quebra de resolução em runtime.
Antes de publicar uma versão com sessões remotas, aplique no backend a migração
0025_cold_plazm.sql. Ela adiciona somente três colunas nullable ao card, portanto o
backend atualizado aceita MCPs antigos. A publicação do pacote deve vir depois do deploy
do backend.
FAQs
MCP server do Kanban Intelliboard — dirija seu board pelo Claude Code / opencode.
The npm package intelliboard-mcp receives a total of 28 weekly downloads. As such, intelliboard-mcp popularity was classified as not popular.
We found that intelliboard-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.