Perseus-mcp

Servidor MCP para a Biblioteca Digital Perseus — fornecendo acesso direto a textos gregos antigos, passagens CTS e pesquisa Scaife para modelos de IA.

Documentação

Project Status: Active – The project has reached a stable, usable state and is being actively developed. Docs License: MIT DOI PyPI Version Python Jupyter Ask DeepWiki

Perseus-mcp

Dê ao Claude / Cursor / Windsurf acesso direto à Biblioteca Digital Perseus — textos em grego antigo e latim, navegação CTS precisa, texto simples, busca e muito mais.

Um servidor MCP de alta qualidade para literatura grega e latina clássica. Ele roda como um servidor FastMCP local para que aplicativos compatíveis com MCP possam anexar essas ferramentas Perseus ao provedor de LLM/modelo de sua escolha.

Recursos

Este servidor expõe vinte e três ferramentas MCP. Cada ferramenta retorna um payload de texto: algumas são XML CTS bruto do Perseus ou JSON do Scaife, enquanto os auxiliares de descoberta e texto simples retornam JSON formatado localmente ou texto legível.

  • get_passage(urn) — busca uma passagem CTS por URN.
  • get_passage_plus(urn) — busca o texto da passagem mais metadados contextuais.
  • get_passage_plaintext(urn) — busca uma passagem CTS como texto simples legível.
  • get_valid_references(urn, level=None) — recupera referências de citação navegáveis para uma obra ou edição.
  • get_valid_references_json(urn, level=None, limit=100, offset=0) — recupera referências de citação paginadas como JSON (limit: 1–500).
  • count_valid_references(urn, level=None) — conta referências válidas sem retornar a lista completa.
  • get_capabilities() — lista textos/edições disponíveis do CTS Perseus.
  • get_cache_status() — inspeciona o estado do cache de metadados local.
  • refresh_metadata_cache() — atualiza os metadados em cache do CTS e da biblioteca Scaife.
  • clear_metadata_cache() — limpa entradas de cache de metadados em memória e em disco.
  • list_text_groups(language=None, query=None, limit=100, offset=0) — lista autores/grupos de texto e obras correspondentes com metadados de paginação (limit: 1–500).
  • get_author_resources(author, language=None) — lista obras, edições e traduções para um nome de autor correspondente ou URN de grupo de texto CTS.
  • find_author_names(query, language=None, limit=100, offset=0) — encontra nomes de autores/grupos de texto por correspondência parcial de nome com metadados de paginação (limit: 1–500).
  • get_work_resources(urn_or_title, language=None) — lista edições, traduções e recursos para uma obra, opcionalmente filtrados por idioma original.
  • get_label(urn) — busca rótulos de metadados legíveis para uma URN.
  • get_first_urn(urn) — obtém a primeira URN navegável sob uma obra/edição.
  • get_prev_next_urn(urn) — obtém URNs de passagens vizinhas para navegação.
  • search_perseus(query, language="greek", query_format="auto", author=None, search_kind="form", preserve_operators=False, page_num=1, text_group=None, work=None, result_format="instances") — busca textos via API de busca Scaife. Consultas em grego podem ser inseridas como grego Unicode (por exemplo, μῆνιν) ou Beta Code (por exemplo, mh=nin).
  • search_within_text(query, text_urn, ..., size=10, offset=0) — busca dentro de uma URN de texto/edição Scaife (size: 1–500).
  • get_passage_highlights(query, passage_urn, ...) — obtém posições de destaque de token Scaife para uma passagem.
  • get_scaife_library_metadata(urn) — obtém metadados JSON Scaife para uma URN de biblioteca.
  • get_scaife_passage_json(urn) — obtém JSON Scaife para uma URN de passagem.
  • get_scaife_passage_text(urn) — obtém texto simples Scaife para uma URN de passagem.

Entrada de Busca em Grego

search_perseus normaliza os termos de busca antes de enviá-los à rota de busca JSON do Scaife. As consultas devem conter pelo menos um caractere não-branco. A ferramenta retorna a resposta JSON do Scaife como texto.

EntradaValores aceitosComportamento
queryGrego Unicode, como μῆνιν, ou Beta Code, como mh=nin a)/eideNormalizado para grego Unicode composto (NFC) antes da busca.
query_format"auto" (padrão), "betacode" ou "unicode"auto reconhece marcas Beta Code como =, /, (, ) e *, e termos curtos sem acento com aparência grega como logos. Use um formato explícito para entrada ASCII ambígua.
languageAliases gregos: greek, grc, gr; aliases latinos: latin, lat, laControla a normalização da consulta, não a filtragem do corpus Scaife. Entrada em branco assume grego; valores não reconhecidos geram erro.
search_kind"form" (padrão) ou "lemma"Busca formas flexionadas ou lemas de dicionário.
preserve_operatorsFalse (padrão) ou TrueDefina como True para frases entre aspas ou operadores como -, |, * e ~, evitando que a detecção de Beta Code os consuma.
authorNome do autor/grupo de texto CTS ou URNUma correspondência única torna-se um filtro text_group no lado do servidor. Correspondências ambíguas usam filtragem local por prefixo de URN CTS na página retornada.
text_group, workURNs de escopo ScaifeAplica filtros de escopo no lado do servidor diretamente.
page_numNúmero da páginaSeleciona a página de resultados.

Exemplos de consultas com operadores:

search_perseus(
    '"μῆνιν ἄειδε"',
    query_format="unicode",
    preserve_operators=True,
)

search_perseus(
    "μῆνιν -ἄειδε",
    query_format="unicode",
    preserve_operators=True,
)

search_perseus(
    "λόγος | ἀνήρ",
    search_kind="lemma",
    query_format="unicode",
    preserve_operators=True,
)

Para descoberta de inventário, list_text_groups, find_author_names, get_author_resources e get_work_resources tratam language como um filtro real de idioma da obra. find_author_names mescla o inventário CTS legado com o catálogo da biblioteca Scaife, para que autores exclusivos do Scaife, como Philo Judaeus, permaneçam descobríveis. As ferramentas de passagem e navegação usam URNs CTS, cujo namespace greekLit/latinLit e identificador de edição já selecionam o texto.

Cache de Metadados Local

As ferramentas de descoberta e navegação armazenam em cache metadados CTS estáveis localmente para evitar requisições repetidas de vários megabytes a GetCapabilities e GetValidReff. O cache em disco padrão fica em .cache/perseus-mcp sob o diretório de trabalho atual e também usa um cache em memória para o processo do servidor em execução. Configure-o com:

  • PERSEUS_MCP_CACHE_DIR — substitui o diretório de cache em disco.
  • PERSEUS_MCP_CACHE_TTL_SECONDS — define o TTL do cache; o padrão é 86400 segundos.
  • PERSEUS_MCP_DISABLE_CACHE=1 — desativa leituras/gravações de cache em memória e em disco.

O diretório de trabalho atual é o diretório a partir do qual o processo Python é iniciado. Executar o servidor MCP a partir da raiz do repositório usa .cache/perseus-mcp; executar um notebook a partir de examples/ usaria examples/.cache/perseus-mcp. Isso não é uma segunda instância do servidor, apenas um segundo local de cache para um processo Python separado. Para manter um único local de cache entre notebooks e clientes MCP, defina PERSEUS_MCP_CACHE_DIR para um caminho absoluto como /path/to/Perseus-mcp/.cache/perseus-mcp. As entradas em disco são gravadas em arquivos temporários irmãos exclusivos e substituídas atomicamente, para que vários processos locais possam compartilhar esse diretório com segurança sem expor arquivos de cache parcialmente gravados. Falhas de gravação do cache em disco emitem um MetadataCacheWarning, mas não descartam uma resposta upstream buscada com sucesso.

Descoberta de URN

As URNs de edição disponíveis podem diferir entre o CTS Perseus e os resultados de busca Scaife, e o inventário ativo pode mudar. Use get_author_resources, get_work_resources ou list_text_groups antes de construir URNs de passagem CTS específicas de edição. Os notebooks selecionam edições CTS anunciadas a partir dos resultados de descoberta em vez de assumir que uma URN de edição Scaife é válida para o CTS Perseus.

A implementação ativa do CTS Perseus pode retornar HTML malformado para GetFirstUrn e GetPrevNextUrn. As ferramentas MCP detectam essa resposta e derivam resultados XML válidos de GetValidReff.

O Perseus também pode retornar 429 Too Many Requests quando um fluxo de trabalho envia muitas requisições CTS em um curto período. Pause antes de tentar novamente, reduza a concorrência e adicione atrasos aos loops de processamento de passagens. O servidor atualmente expõe o erro HTTP upstream em vez de tentar novamente automaticamente.

Configuração

1) Instalar dependências

Usando uv:

uv sync

Ou com pip:

pip install -e .

Quando uma versão for publicada no PyPI, os usuários poderão instalá-la sem clonar o repositório:

pip install perseus-mcp

Para desenvolvimento e testes:

pip install -e ".[dev]"

2) Executar testes

pytest

Com uv, use:

uv run --extra dev pytest

3) Executar localmente

uv run perseus-mcp

O comando de console instalado e o ponto de entrada do módulo são equivalentes:

perseus-mcp
python -m perseus_mcp

4) Inspecionar ferramentas (opcional)

npx @modelcontextprotocol/inspector uv run perseus-mcp

Estratégia de teste e automação

O Perseus MCP usa verificações em camadas em vez de depender de um único teste ponta a ponta. A maior parte do comportamento é coberta por testes pytest determinísticos com fixtures XML/JSON locais e chamadas HTTP assíncronas simuladas. O GitHub Actions verifica separadamente a matriz suportada de Python e sistemas operacionais, artefatos de pacote, segredos, tags de versão e publicação.

Os arquivos de fluxo de trabalho sob .github/workflows/ são a fonte executável da verdade.

Organização do conjunto de testes

O Pytest é configurado em pyproject.toml para importar de src/ e descobrir testes sob tests/.

Módulo de testeResponsabilidade principal
test_author_resources.pyAnálise de autor, obra e recurso CTS; comportamento de autor mesclado
test_disk_cache.pyGravações atômicas de cache, desativação de cache, limpeza e gravadores concorrentes
test_exploration_tools.pyDescoberta, navegação, ferramentas de cache, escopo de autor e respostas estruturadas
test_greek_query_normalization.pyGrego Unicode, Beta Code, parâmetros Scaife e operadores de busca
test_limits_and_language.pyLimites de resultados, limites de paginação e aliases de idioma
test_packaging.pyMetadados, dependências, ativos de documentação, notebooks e expectativas de fluxo de trabalho
test_scaife_urls.pyConstrução segura de URLs e codificação percentual de URN CTS
test_shared_http_client.pyReutilização de conexão, mudanças de event-loop, desligamento e erros HTTP
test_xml_hardening.pyAnálise XML segura e rejeição de ataques XML baseados em entidades

Uma correção de regressão deve incluir um teste focado que falhe para o problema original. Os testes devem afirmar o comportamento observável e cobrir caminhos de falha e valores de limite, bem como chamadas bem-sucedidas.

Isolamento do Perseus e Scaife

Os testes de rotina não dependem de serviços upstream ativos. Os auxiliares HTTP são monkeypatched com duplos de teste assíncronos, enquanto XML CTS representativo e JSON Scaife são armazenados em fixtures de teste. Isso mantém o CI determinístico quando catálogos mudam ou um serviço upstream está indisponível, evita tráfego desnecessário para infraestrutura acadêmica pública e torna os testes de resposta malformada seguros.

Sondas ativas somente leitura podem ser usadas durante revisão manual para compatibilidade de endpoint ou mudanças no ciclo de vida da conexão, mas elas complementam em vez de substituir o conjunto automatizado.

Limpeza de teste assíncrono

Vários testes invocam ferramentas com asyncio.run(), o que cria um novo event loop para cada chamada. O servidor usa um httpx.AsyncClient compartilhado em todo o processo, então a fixture autouse em tests/conftest.py fecha e redefine esse cliente após cada teste. Testes que manipulam o estado compartilhado do cliente também devem deixá-lo redefinido.

Comandos de teste locais

Execute o conjunto completo:

python -m pytest

Execute um módulo ou um teste:

python -m pytest tests/test_disk_cache.py
python -m pytest tests/test_disk_cache.py::test_disk_cache_set_writes_readable_content

Mostre testes ignorados, os testes mais lentos e variáveis locais em caso de falha:

python -m pytest -ra --durations=10 -l

Desative leituras e gravações do cache de metadados durante uma execução de teste:

PERSEUS_MCP_DISABLE_CACHE=1 python -m pytest

Equivalente no PowerShell:

$env:PERSEUS_MCP_DISABLE_CACHE = "1"
python -m pytest

Matriz de teste do GitHub Actions

.github/workflows/tests.yml instala o projeto editável com dependências de desenvolvimento e executa python -m pytest em:

  • Ubuntu e Windows;
  • Python 3.11, 3.12 e 3.13.

A matriz usa fail-fast: false, para que cada trabalho de plataforma/versão termine mesmo quando um falha. Isso torna regressões específicas de versão e específicas do Windows visíveis em uma única execução. Mudanças somente de documentação sob docs/** são excluídas do fluxo de trabalho de teste Python; filtros exatos de evento e branch permanecem definidos no arquivo de fluxo de trabalho.

Validação de pacote

.github/workflows/package.yml verifica se o repositório produz uma distribuição de código-fonte válida e uma wheel universal. Ele instala Python 3.12, executa:

python -m build
python -m twine check dist/*

e envia dist/ como o artefato do fluxo de trabalho python-package. O fluxo de trabalho é filtrado por caminho para arquivos relevantes ao pacote e suporta despacho manual.

tests/test_packaging.py complementa essa compilação verificando expectativas no nível do repositório, como metadados, dependências, arquivos de documentação, JSON de notebook e configuração de fluxo de trabalho. Ambas as camadas importam: testes de metadados podem passar enquanto uma compilação isolada falha, e um pacote pode compilar enquanto ativos obrigatórios do repositório estão ausentes.

Varredura de segredos

.github/workflows/secret-scan.yml rejeita chaves OpenRouter rastreadas que correspondem a:

sk-or-v1-[A-Za-z0-9_-]{20,}

O fluxo de trabalho relata os arquivos afetados sem imprimir o segredo correspondente. Uma chave detectada deve ser removida e rotacionada; a verificação nunca deve ser ignorada. Esta varredura focada não substitui a higiene normal de credenciais: não faça commit de arquivos .env, tokens, configuração MCP privada ou saídas de notebook contendo credenciais.

Segurança de código e dependências

.github/workflows/codeql.yml analisa tanto o código-fonte Python quanto os fluxos de trabalho do GitHub Actions em pushes para main e development, em pull requests, e semanalmente. A análise Python usa o conjunto de consultas security-and-quality do CodeQL, enquanto a análise de fluxos de trabalho usa o conjunto security-extended. O fluxo de trabalho também suporta execução manual para verificações de configuração.

.github/workflows/dependency-review.yml é executado em todo pull request e falha quando uma dependência alterada introduz uma vulnerabilidade conhecida de gravidade moderada ou superior. O Dependabot verifica dependências Python e GitHub Actions semanalmente. Seus rótulos padrão são usados intencionalmente para que pull requests de atualização não dependam de rótulos específicos do repositório pré-criados.

Portões de liberação e publicação

.github/workflows/release.yml é executado para tags v* ou execução manual. Para execuções de tag, ele verifica se a tag é igual a v<project.version>, compila o wheel e o arquivo fonte, valida ambos com Twine, anexa-os a uma release do GitHub gerada e despacha o fluxo de trabalho do PyPI usando a mesma tag.

.github/workflows/publish.yml requer uma referência de tag, repete a verificação de tag/versão, recompila e revalida os artefatos, e publica através da publicação confiável do PyPI. O ambiente GitHub protegido pypi usa OIDC (id-token: write), portanto nenhum token de API PyPI de longa duração é armazenado.

Recompilar durante a publicação evita confiar em um artefato de fluxo de trabalho não relacionado, enquanto a verificação repetida de tag impede a publicação a partir de um branch ou tag de release incompatível.

Implantação de documentação

.github/workflows/pages.yml compila docs/ com Jekyll e implanta o artefato gerado no GitHub Pages após alterações na documentação chegarem a main ou master. Este site Pages é destinado principalmente a usuários finais; documentação de desenvolvimento e estratégia de teste vive no README deste repositório. Pull requests que alteram a documentação ou o fluxo de trabalho Pages também compilam o site para validação, sem implantá-lo. Visualize o site gerado em vez de abrir docs/index.html diretamente: a página inicial agora compartilha o layout Jekyll usado pelas outras páginas.

Interpretando falhas

  • Falhas em todos os jobs da matriz geralmente indicam uma regressão geral.
  • Uma falha em uma única versão Python sugere sintaxe, dependências ou comportamento da biblioteca padrão específicos da versão.
  • Falhas apenas no Windows geralmente envolvem caminhos, permissões, atributos somente leitura ou ciclo de vida do event loop.
  • Uma falha de pacote com jobs pytest verdes geralmente diz respeito a metadados, manifests, renderização do README ou isolamento de build.
  • Uma falha na varredura de segredos requer remoção e rotação de credenciais.
  • Uma falha de release antes da publicação geralmente significa que a tag e project.version não correspondem.

Entenda a falha antes de reexecutar um job e preserve logs de fluxo de trabalho úteis ou tracebacks no pull request quando a causa não for óbvia.

Convenções de nível de mantenedor para estender o conjunto também são mantidas ao lado dos testes em tests/testing.md.

Exemplos de notebooks

O diretório examples/ inclui notebooks Jupyter que demonstram tanto chamadas diretas de endpoint quanto uso de cliente MCP com dados reais em grego e latim:

  • examples/00_install_and_run_perseus_mcp.ipynb — guia de instalação e inicialização cobrindo PyPI, pip, uv, desenvolvimento local do repositório, configuração de cliente MCP, verificação, atualizações e solução de problemas.
  • examples/01_basic_cts_workflow.ipynb — solicitações CTS diretas mínimas.
  • examples/02_search_and_navigation.ipynb — busca JSON Scaife direta e navegação CTS a partir de referências válidas.
  • examples/03_mcp_connection_homer_iliad.ipynb — conexão de cliente FastMCP, descoberta de recursos de Homero e análise de passagens gregas da Ilíada.
  • examples/04_mcp_greek_search_and_navigation.ipynb — busca grega MCP com Unicode/Beta Code, referências válidas e navegação de passagens.
  • examples/05_mcp_all_tools.ipynb — catálogo completo de ferramentas MCP com descrições e esquemas de entrada.
  • examples/06_openrouter_llm_mcp_interaction.ipynb — loop opcional de chamada de ferramentas LLM OpenRouter sobre as ferramentas MCP locais, usando o Free Models Router do OpenRouter por padrão.
  • examples/07_mcp_advanced_search_options.ipynb — busca de forma/lema MCP, consultas de operador Scaife e exemplos de busca com escopo de autor.
  • examples/08_mcp_cache_and_search_tools.ipynb — demonstração avançada de ferramentas de cache, referências paginadas, busca com escopo, busca de leitor, destaques e recuperação de metadados/texto Scaife.
  • examples/09_openrouter_philo_politeia_analysis.ipynb — análise assistida por OpenRouter, primeiro as evidências, de πολιτεία em Fílon de Alexandria usando resultados de busca MCP com escopo e passagens citadas.
  • examples/10_mcp_latin_augustine_workflow.ipynb — descoberta em língua latina, navegação CTS, recuperação de passagens e uma pequena análise de texto usando seleções das Epistulae de Agostinho.

Execute-os após instalar as dependências do projeto. Os notebooks MCP usam o transporte de cliente em processo do FastMCP e chamam as mesmas ferramentas expostas a clientes MCP externos. O notebook OpenRouter opcional também requer uma chave de API OpenRouter; o próprio servidor MCP não. Células de configuração do notebook instalam helpers exclusivos do notebook, como python-dotenv diretamente. Esses helpers não são dependências de runtime principais de perseus-mcp.

Configurar a chave de API OpenRouter

Para examples/06_openrouter_llm_mcp_interaction.ipynb e examples/09_openrouter_philo_politeia_analysis.ipynb, copie .env.example para .env na raiz do projeto e substitua o espaço reservado:

OPENROUTER_API_KEY=sk-or-v1-...

Obtenha sua chave de API em openrouter.ai. Veja a documentação da chave de API do OpenRouter para detalhes de autenticação. O arquivo .env é ignorado pelo Git. Você também pode definir OPENROUTER_API_KEY no seu ambiente ou inseri-la com segurança quando o notebook solicitar.

Ambos os notebooks OpenRouter usam openrouter/free por padrão. Este roteador seleciona entre modelos gratuitos atualmente disponíveis no OpenRouter e filtra por capacidades exigidas pela solicitação, como chamada de ferramentas ou saída estruturada. Ele evita vincular os exemplos a um único modelo gratuito que pode ser removido posteriormente ou ficar temporariamente indisponível. A compensação é reprodutibilidade reduzida: execuções separadas podem usar modelos concretos diferentes, então os notebooks registram o modelo resolvido retornado pelo OpenRouter. Defina OPENROUTER_MODEL para um slug de modelo fixo quando a seleção exata do modelo for importante.

O notebook 06_ pode ser salvo e commitado com suas saídas de LLM e chamadas de ferramentas para que renderizem no GitHub. Variáveis Python e memória do kernel não são armazenadas em um arquivo .ipynb, e o notebook não imprime a chave de API. Antes de commitar uma execução com credenciais, revise as saídas visíveis e verifique se há uma chave OpenRouter completa:

rg "sk-or-v1-[A-Za-z0-9_-]{20,}" examples/06_openrouter_llm_mcp_interaction.ipynb

O comando não deve produzir saída. Ele não corresponde ao espaço reservado sk-or-v1-... documentado.

Usando com qualquer cliente LLM compatível com MCP

Este projeto não requer um LLM específico. Configure seu cliente para iniciar o servidor MCP local com:

uv --directory /full/path/to/Perseus-mcp run perseus-mcp

A maioria dos clientes MCP precisa das mesmas partes: nome do servidor perseus, comando uv, args --directory /full/path/to/Perseus-mcp run perseus-mcp e um ambiente vazio, a menos que você tenha personalizações locais. Veja docs/enduser.md para orientação genérica de clientes e docs/architecture.md para as escolhas de arquitetura, incluindo por que o FastMCP é usado.

Claude Desktop e Claude Code

O servidor roda com Claude via stdio, sem exigir OpenRouter ou chave de API (OpenRouter só é necessário para o cliente de demonstração opcional).

Claude Desktop — adicione a claude_desktop_config.json:

{
  "mcpServers": {
    "perseus": {
      "command": "uv",
      "args": ["--directory", "/full/path/to/Perseus-mcp", "run", "perseus-mcp"]
    }
  }
}

Reinicie o Claude Desktop; as ferramentas Perseus aparecem na lista de ferramentas.

Claude Code — uma linha:

claude mcp add perseus -- uv --directory /full/path/to/Perseus-mcp run perseus-mcp

Verificado contra um handshake MCP stdio: todas as 23 ferramentas registram e chamadas ao vivo retornam (testado com search_perseus e list_text_groups).

Compilar uma distribuição PyPI

Instale as dependências de desenvolvimento, depois compile e valide ambos os formatos de distribuição:

python -m pip install -e ".[dev]"
python -m build
python -m twine check dist/*

A compilação cria um wheel e um arquivo fonte em dist/. Teste o wheel em um ambiente virtual limpo antes de publicar. Envie para o TestPyPI primeiro:

python -m twine upload --repository testpypi dist/*

Após verificar a instalação a partir do TestPyPI, envie os mesmos artefatos para o PyPI:

python -m twine upload dist/*

O PyPI não permite substituir uma release existente. Atualize project.version em pyproject.toml, recompile a partir de um diretório dist/ limpo e publique cada versão apenas uma vez. O fluxo de trabalho de compilação do pacote também compila e verifica artefatos no CI sem publicá-los.

Release automatizada do GitHub e publicação no PyPI

A automação de release segue o mesmo padrão de publicação confiável do MorphKit:

  1. Defina a versão da release em pyproject.toml, por exemplo 1.2.3.
  2. Mescle a alteração de versão no commit que deve ser lançado.
  3. Crie e envie a tag correspondente, por exemplo v1.2.3.
  4. O fluxo de trabalho Build release artifacts verifica a correspondência tag/versão, compila e valida ambas as distribuições e as anexa a uma release gerada no GitHub.
  5. Esse fluxo de trabalho despacha Publish to PyPI, que recompila e valida o pacote antes de publicar através da publicação confiável do PyPI.

Configure o repositório uma vez antes do primeiro upload automatizado:

  • Crie um ambiente GitHub Actions chamado pypi.
  • Nas configurações existentes do projeto PyPI, ou como um publicador pendente antes do primeiro upload, adicione um publicador confiável para o proprietário tonyjurg, repositório Perseus-mcp, fluxo de trabalho publish.yml e ambiente pypi.
  • Não adicione um token de API PyPI; o fluxo de trabalho usa GitHub OIDC com id-token: write.

Os fluxos de trabalho rejeitam uma tag como v1.2.4 quando project.version ainda é 1.2.3. As versões do PyPI são imutáveis, então incremente a versão antes de tentar novamente uma release que já foi enviada.

Contribuindo e relatando problemas

Relatórios de bugs, correções de documentação, solicitações de recursos focadas e pull requests são bem-vindos. Por favor, relate problemas através do rastreador de issues do GitHub e inclua o comando, a versão Python, o cliente MCP, os argumentos da ferramenta, o traceback e qualquer URN CTS relevante ou consulta de busca grega quando possível.

Veja docs/contributing.md para orientação de contribuição.

Divulgação responsável

Este projeto foi criado com assistência do OpenAI Codex. O mantenedor humano permanece responsável por revisar, testar e aceitar todas as alterações de código e documentação.

Licença

Este projeto é lançado sob a Licença MIT. Veja LICENSE para detalhes.