MCP.Harness.linux-arm64
0.1.2
dotnet add package MCP.Harness.linux-arm64 --version 0.1.2
NuGet\Install-Package MCP.Harness.linux-arm64 -Version 0.1.2
<PackageReference Include="MCP.Harness.linux-arm64" Version="0.1.2" />
<PackageVersion Include="MCP.Harness.linux-arm64" Version="0.1.2" />
<PackageReference Include="MCP.Harness.linux-arm64" />
paket add MCP.Harness.linux-arm64 --version 0.1.2
#r "nuget: MCP.Harness.linux-arm64, 0.1.2"
#:package MCP.Harness.linux-arm64@0.1.2
#addin nuget:?package=MCP.Harness.linux-arm64&version=0.1.2
#tool nuget:?package=MCP.Harness.linux-arm64&version=0.1.2
MCP.Harness
Servidor MCP (Model Context Protocol) em .NET 10 que expõe o sprint
harness de engenharia como ferramentas para qualquer cliente MCP (Claude
Code, IDEs, agentes). Em vez de depender de scripts soltos (bootstrap.sh) e
de convenções que vivem apenas no CLAUDE.md, o MCP.Harness entrega o ciclo
de vida de tarefas — bootstrap do board, criação de Issues e transição de
Status — como tools versionadas, testáveis e reaproveitáveis entre repos.
Contexto — o que é o sprint harness
O harness organiza todo trabalho não-trivial em torno de um GitHub Project (v2) por repositório, com campos padronizados:
| Campo | Tipo | Valores |
|---|---|---|
Status |
single select | Backlog, Todo, Doing, Done |
Sprint |
iteration | ciclo/iteração atual (14 dias) |
Story Points |
number | estimativa de esforço |
Ciclo de vida de uma task:
- Criação — Issue real + item no Project,
Status = Backlog. - Início —
Status = Todoe, ao começar de fato,Status = Doing. - Execução — commits referenciam a Issue (
refs #N/Closes #N). - Conclusão —
Status = Donee Issue fechada. Trabalho interrompido fica emDoingcom o estado registrado no corpo da Issue.
A Issue é a fonte de verdade — nunca arquivos .md soltos no repo.
O que o servidor expõe
Tools
| Tool | Estado | Descrição |
|---|---|---|
harness_bootstrap |
✅ | Cria o Project v2 a partir do template padronizado e vincula ao repo (porta do bootstrap.sh). |
harness_create_task |
✅ | Cria a Issue, adiciona ao Project, Status = Backlog, Sprint atual e Assignees (default: usuário do token). Dedup por título. |
harness_move_task |
✅ | Move o Status de um item (Backlog / Todo / Doing / Done); valida a opção. |
harness_complete_task |
✅ | Define Status = Done e fecha a Issue com state_reason = completed. Idempotente. |
harness_board |
✅ | Snapshot da sprint (default: corrente), agrupado por Status com soma de Story Points. |
Resources
| Resource | Estado | Conteúdo |
|---|---|---|
harness://board/{owner}/{repo} |
✅ | Snapshot JSON da sprint corrente do board do repo. |
harness://board/current |
✅ | Idem, para o repo padrão (Harness:DefaultRepo). |
harness://config |
✅ | Configuração efetiva + fonte do token (sem o valor). |
Stack
- .NET 10 / C#
- SDK oficial
ModelContextProtocolpara C# - Transporte stdio (padrão para Claude Code); HTTP/SSE opcional
- Acesso ao GitHub via GraphQL (Projects v2) + REST (Issues),
autenticando com PAT (
GITHUB_TOKEN) ou com o token doghCLI
Configuração
Duas fontes, nesta ordem de precedência: variáveis de ambiente →
appsettings.json (ao lado do binário) → defaults.
| Env | Chave (appsettings.json) |
Default | Uso |
|---|---|---|---|
GITHUB_TOKEN / GH_TOKEN |
GitHub:Token |
— | PAT com escopos repo, project, read:org |
| — | GitHub:RestBaseUrl |
https://api.github.com/ |
base REST (troque para GitHub Enterprise) |
| — | GitHub:GraphQlUrl |
https://api.github.com/graphql |
endpoint GraphQL |
HARNESS_TEMPLATE_OWNER |
Harness:TemplateOwner |
semog-projects |
dono do Project-template v2 |
HARNESS_TEMPLATE_NUMBER |
Harness:TemplateNumber |
7 |
número do Project-template v2 |
HARNESS_DEFAULT_REPO |
Harness:DefaultRepo |
— | owner/repo do resource harness://board/current |
O token nunca é logado nem exposto. O resource harness://config mostra
a configuração efetiva e a fonte do token (env GITHUB_TOKEN, gh CLI, …),
nunca o valor. Ver docs/configuracao.md.
Tools já implementadas:
harness_bootstrap (assinatura e diferenças
vs scripts/bootstrap.sh),
harness_create_task,
harness_move_task,
harness_complete_task e
harness_board.
Erros de domínio (status inválido, Issue fora do board, token sem escopo…)
voltam como texto ❌ … no resultado da tool, não como falha crua.
Registrar no Claude Code
Consumir sem clonar o repo — pacote NuGet via dnx (precisa do .NET 10 SDK):
// .mcp.json (na raiz do repo que vai usar o harness)
{
"mcpServers": {
"harness": {
"command": "dotnet",
"args": ["dnx", "MCP.Harness", "--yes"],
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
}
}
}
Sem .NET na máquina — imagem de container (GHCR):
{
"mcpServers": {
"harness": {
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "GITHUB_TOKEN",
"ghcr.io/semog-projects/mcp-harness:latest"]
}
}
}
Ou baixe o binário do SO na página de Releases.
Publicação: docs/publicacao.md.
Durante o desenvolvimento deste repo — dotnet run:
// .mcp.json (na raiz do repo que vai usar o harness)
{
"mcpServers": {
"harness": {
"command": "dotnet",
"args": ["run", "--project", "/caminho/para/MCP.Harness/src/MCP.Harness/MCP.Harness.csproj"],
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
}
}
}
Build local self-contained: dotnet publish src/MCP.Harness/MCP.Harness.csproj -c Release -r <RID> -o <destino> e aponte command para <destino>/mcp-harness.
O appsettings.json publicado ao lado do binário carrega
Harness:TemplateOwner, Harness:DefaultRepo, etc. sem env vars.
Passo a passo num repo novo
- Gere um PAT com escopos
repo,project,read:org→export GITHUB_TOKEN=…. Para oharness_bootstrapvincular o Project ao repo, use um PAT clássico — a mutationlinkProjectV2ToRepositorynão funciona com PAT fine-grained. As demais tools funcionam com fine-grained (Projects RW + Issues RW + Contents R). - Adicione o
.mcp.jsonacima na raiz do repo. - Rode o harness uma vez: tool
harness_bootstrapcomowner/repodo repo novo — cria o Project v2 e vincula. Se aparecer⚠️ NÃO vinculado, siga ogh project linkda mensagem e rode de novo. - A partir daí,
harness_create_task/harness_move_task/harness_complete_task/harness_board.
Troubleshooting
| Sintoma | Causa provável / correção |
|---|---|
❌ … token sem permissão / token inválido ou expirado |
PAT sem escopo project ou read:org, ou expirado. Gere outro. |
❌ … rate limit do GitHub atingido |
Espere o horário do reset informado na mensagem. |
❌ Nenhum Project v2 vinculado a … |
Rode harness_bootstrap primeiro. |
harness_bootstrap: ⚠️ Board criado, mas NÃO vinculado |
linkProjectV2ToRepository exige token clássico com scope project (PAT fine-grained não serve). Rode o gh project link da mensagem, ou linke na UI, e rode harness_bootstrap de novo. |
❌ … template #7 … pode estar desconfigurado |
HARNESS_TEMPLATE_OWNER/NUMBER apontam para um Project sem os campos padrão. |
❌ Issue #N não está no board |
Use harness_create_task (ou adicione a Issue ao Project na UI). |
| Nenhum token encontrado | export GITHUB_TOKEN=…, ou gh auth login, ou preencha GitHub:Token. |
harness://board/current devolve { "error": … } |
Defina HARNESS_DEFAULT_REPO=owner/repo ou use harness://board/{owner}/{repo}. |
Desenvolvimento
dotnet build
dotnet test # unidade
HARNESS_IT=1 GITHUB_TOKEN=$(gh auth token) \
dotnet test --filter Category=Integration # ponta-a-ponta (GitHub real)
dotnet run --project src/MCP.Harness
Estrutura
src/MCP.Harness/ # host do servidor MCP: tools, resources, appsettings.json, .mcp/server.json
src/MCP.Harness.GitHub/ # cliente GitHub (GraphQL Projects v2 + REST Issues) + serviços do harness
tests/MCP.Harness.Tests/ # testes de unidade e integração
docs/ # uma página por tool + configuracao.md + publicacao.md
Dockerfile # imagem stdio (GHCR)
.github/workflows/ # ci.yml (build+test) · release.yml (tag v* → NuGet/GHCR/Release)
scripts/bootstrap.sh # script legado — referência para a tool harness_bootstrap
Camada de acesso ao GitHub
src/MCP.Harness.GitHub isola toda a conversa com o GitHub e é registrada
com services.AddHarnessGitHub(configuration):
IssuesClient(REST) — criar/ler/fechar Issue, comentar.ProjectsV2Client(GraphQL) — resolver o board de um repo, ler campos e opções (Status/Sprint/Story Points), adicionar item, atualizar valor de campo (single-select, iteration, number) e remover item.GitHubClient— fachada com o atalhoPlaceOnBoardAsync(add + status + sprint + pontos).GitHubTokenProvider— resolve o token:GitHub:Token→GITHUB_TOKEN/GH_TOKEN→gh auth token. Erros da API viramGitHubApiExceptioncom mensagem acionável (escopo faltando, rate limit, 404).
Os testes de integração (Category=Integration) batem no GitHub real e só
rodam com HARNESS_IT=1 e GITHUB_TOKEN no ambiente:
HARNESS_IT=1 GITHUB_TOKEN=$(gh auth token) dotnet test --filter Category=Integration
Relação com o bootstrap.sh
scripts/bootstrap.sh copia um Project-template v2 (com os campos
Status / Sprint / Story Points já configurados) para um novo owner e
vincula ao repositório, usando o gh CLI. A tool harness_bootstrap
replica exatamente esse fluxo pela API do GitHub, sem depender do gh
instalado na máquina do cliente:
gh project copy <template> --source-owner … --target-owner …→ mutationcopyProjectV2gh project link <n> --owner … --repo …→ mutationlinkProjectV2ToRepository- valida o campo
Sprint(iteration) e reporta o calendário de ciclos.
Roadmap
Sprint 1 (atual) — fundação: scaffold do projeto, camada de acesso ao GitHub, tool de bootstrap e CRUD de tasks.
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.