Tool servers MCP
Declare um servidor como
[tool_servers.<name>] em config.toml. Dê a ele exatamente um transporte. command cria um processo e fala stdio. url fala HTTP streamable sobre https, ou sobre http em loopback. Uma declaração com os dois, ou com nenhum, recusa carregar.
dir, headers, oauth, timeout_ms e enabled. Cada servidor declarado conecta na inicialização a menos que você defina enabled = false.
O Narya mantém uma sessão de vida longa por servidor e reconecta com backoff. Quando um servidor desconecta, o Narya retira as ferramentas dele do registro, então o modelo nunca vê as ferramentas de um servidor que saiu.
Defina oauth = true para um servidor remoto que faz login. O Narya mantém a conexão aberta, imprime a URL de autorização e escuta em 127.0.0.1:7666 pelo callback enquanto o login está aberto. Um login que ninguém responde custa esse único servidor e nada mais. Uma execução de uma só vez não pode completar um login, e ela diz isso.
Árvores de ferramentas OpenAPI
Declare
[tool_trees.<name>] para transformar um documento OpenAPI em uma árvore de ferramentas chamável. As chaves são spec, base_url, headers, timeout_ms e enabled. Um caminho spec relativo resolve contra o seu Narya home. Defina base_url quando o documento não declara servidor próprio. O Narya deriva as ferramentas uma vez na inicialização. Nenhum servidor roda, e nenhuma sessão reconecta.
Scripts confinados
O Narya roda ECMAScript em um motor confinado. O motor não alcança sistema de arquivos, rede, ambiente nem carregador de módulos. Ele não tem avaliação dinâmica. A profundidade de chamadas para em 4.096, e o código-fonte para em 256 KiB. Três chamadores o usam: a ferramenta
run_program do modelo, os workflows e a descoberta de ferramentas.
A API do host
O host serve uma API HTTP sobre um socket Unix, e cada cliente a conduz. A API do host descreve o transporte, o stream de eventos e os envelopes.
Agentes, skills, comandos e hooks
O Narya lê os formatos do próprio Claude Code sem nenhuma mudança. Agentes são arquivos markdown com frontmatter YAML.
name é o único campo que um arquivo deve carregar. Os outros são description, prompt, tools, model, mode e hidden. tools é uma allowlist e nunca uma concessão: o Narya cruza a lista de um filho com a do pai, então um agente filho pode perder ferramentas, nunca ganhar.
O Narya lê agentes do seu Narya home, depois de ~/.claude/agents, depois dos .claude/agents e .narya/agents de um repositório em que você confia. Quatro agentes vêm no binário: explore, general, plan e review.
Skills seguem o padrão Agent Skills: um diretório que guarda um SKILL.md. O Narya lê a mesma escada, ~/.claude/skills incluído, e a relê a cada requisição. Uma skill que você acrescenta no meio da sessão chega no turno seguinte.
Comandos vêm do seu Narya home, de ~/.claude/commands, e dos .claude/commands e .narya/commands de um repositório em que você confia.
Hooks vêm da tabela hooks do ~/.claude/settings.json, e do mesmo arquivo em um repositório em que você confia. O Narya os lê com as chaves de stdin e os códigos de saída que esses scripts já usam. Quatro eventos têm correspondência: PreToolUse, PostToolUse, UserPromptSubmit e SessionStart. Cinco não têm equivalente, então o Narya os pula e escreve uma linha na saída de erro padrão: Stop, SubagentStop, Notification, PreCompact e SessionEnd.
Os hooks do próprio Narya
Declare
[[hooks]] em config.toml com point, command, timeout_ms, fail e match. fail não tem padrão, então declare-o. match filtra um hook before-tool-call para um único nome de ferramenta.
Quatro pontos decidem, e um hook ali pode parar o que ele antecede:
before-tool-call, before-model-request, after-tool-call, at-permission-ask.
Oito pontos observam, e um hook ali fica sabendo o que aconteceu sem mudar nada:
session-started, lane-started, lane-finished, delegation-created, child-asked, skill-invoked, permission-denied, session-compacted.
O arquivo do próprio repositório não pode declarar at-permission-ask.
Delegação
Delegação é uma chamada de ferramenta. Defina os limites dela em
[delegation] no config.toml. A chave max_depth conta os níveis abaixo da sua conversa, e 0 desliga a delegação. Defina max_concurrent para limitar quantas lanes uma conversa roda em qualquer instante.
