grafana-fastmcp


Namegrafana-fastmcp JSON
Version 1.2.3 PyPI version JSON
download
home_pageNone
SummaryPython Grafana FastMCP server/CLI with SSE, Streamable HTTP and STDIO transports
upload_time2025-11-06 00:50:01
maintainerNone
docs_urlNone
authorAlessander de Souza Goulart
requires_python>=3.13
licenseApache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
keywords grafana loki mcp observability oncall prometheus pyroscope sift
VCS
bugtrack_url
requirements httpx mcp starlette python-dotenv pytest-asyncio
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![PR Tests (3.13)](https://github.com/sandersouza/grafanaFastMCP/actions/workflows/pr-package.yml/badge.svg)](https://github.com/sandersouza/grafanaFastMCP/actions/workflows/pr-package.yml)
[![Python package](https://github.com/sandersouza/grafanaFastMCP/actions/workflows/python-package.yml/badge.svg)](https://github.com/sandersouza/grafanaFastMCP/actions/workflows/python-package.yml)
[![Python Version](https://img.shields.io/badge/python-3.13%2B-blue.svg)](https://www.python.org/downloads/release/python-3130/)

<a href="https://link.mercadopago.com.br/buymecoke"><img align="right" src="donation.png" alt="Me compre um café!" width="140"></a>

# Grafana FastMCP Server / CLI
## Visão geral
Python FastMCP Server / CLI ( OpenAI Compliance ), com suporte a transportes Server-Sent Events (SSE), Streamable HTTP e STDIO. A aplicação expõe recursos de uma instância Grafana para agentes compatíveis com o protocolo MCP, oferecendo operações para busca, criação e atualização de dashboards, exploração de logs via Loki, consulta de datasources, gestão de alertas, incidentes, turnos de on-call e acesso a dados de observabilidade (Prometheus, Pyroscope, Grafana Sift e muito mais).

**🚀 NOVA VERSÃO v1.2.3**: Esta release inclui melhorias nas checagens de inicialização (TLS/autenticação), suporte a variáveis TLS/SSL e flags CLI para troubleshooting rápido. Veja [CHANGELOG.md](./CHANGELOG.md) e [ISSUES.md](./ISSUES.md) para detalhes completos.

## Estrutura do projeto
Todo o código-fonte fica no diretório `app/`, deixando a raiz do repositório reservada para arquivos de configuração (como `.env`, `Dockerfile`, `requirements.txt` e este `README`). A organização completa é:

```
.
├── app/
│   ├── __init__.py            # Metadados e versão do pacote
│   ├── __main__.py            # Permite executar com `python -m app`
│   ├── config.py              # Carregamento e saneamento das variáveis de ambiente
│   ├── context.py             # Resolução de configuração por requisição
│   ├── grafana_client.py      # Cliente HTTP assíncrono para a API do Grafana
│   ├── main.py                # CLI que instancia e publica o servidor MCP
│   ├── patches.py             # Ajustes de compatibilidade para FastMCP/transportes
│   ├── server.py              # Fábrica do FastMCP e registro das ferramentas
│   └── tools/                 # Coleção de ferramentas MCP (dashboards, Loki, etc.)
├── run_app.py                 # Entrypoint usado pelo PyInstaller (`make package`)
├── tests/                     # Testes automatizados em Python
├── Dockerfile                 # Imagem Docker/Podman
├── Makefile                   # Atalhos de automação (venv, package, docker...)
├── env.example                # Exemplo de variáveis de ambiente (nomes oficiais)
├── instructions.md            # Prompt padrão utilizado pelos clientes MCP
├── requirements.txt           # Dependências de runtime
└── pytest.ini                 # Configuração do pytest
```

Consulte [CHANGELOG.md](./CHANGELOG.md) para detalhes das versões publicadas.

Cada submódulo em `app/tools/` registra um conjunto de ferramentas MCP, abrangendo desde administração de usuários até consultas de observabilidade e automação de incidentes.

## Requisitos
- Python 3.13 ou superior
- Instância Grafana acessível (local ou remota) e credenciais de API válidas


### Gerenciamento de dependências (uv/uvx)
Este repositório adota o [uv](https://github.com/astral-sh/uv) como gerenciador de dependências e execução. Você pode continuar usando `venv`/`pip` tradicionalmente, mas recomendamos `uv` pelos benefícios de velocidade, reprodutibilidade (`uv.lock`) e simplificação de scripts.

**Dependências não são pinadas**: O projeto sempre buscará as versões mais recentes compatíveis de cada pacote. O arquivo `uv.lock` é versionado para garantir builds reprodutíveis e CI estável.

Passos rápidos:

1. Instale o uv (uma vez):
```bash
curl -Ls https://astral.sh/uv/install.sh | sh
```

2. Sincronize as dependências (runtime + dev):
```bash
uv sync --dev --all-extras
```

3. Rode o servidor:
```bash
uv run -m app --address localhost:8000 --log-level INFO --transport stdio
```

Também é possível executar via PyPI usando uvx (após a publicação):
```bash
uvx grafana-fastmcp --address localhost:8000 --log-level INFO --transport stdio
```

4. Comandos comuns:
```bash
# Testes
uv run pytest

# Cobertura
uv run pytest --cov=. --cov-report term-missing

# Lint e formatação (ruff)
uv run ruff check .
uv run ruff format .

# Type checking
uv run mypy app tests

# Empacotar com PyInstaller
uvx pyinstaller --clean --onefile --name grafana-mcp run_app.py
```


**Testes unitários:**
- O badge "PR Tests (3.13)" acima reflete o status dos testes que rodarão para cada Pull Request (Python 3.13).
- O badge "Python package" reflete o status do pipeline principal (push para main).
- Para rodar localmente com uv/uvx:
  - `uv run pytest` (unitários)
  - `uv run pytest --cov=. --cov-report term-missing` (cobertura)
  - `make uv-test` (atalho Makefile)
  - `make uv-cov` (cobertura via Makefile)

**Construção de artefatos em PRs:**
- Para gerar binários/wheel no contexto de um PR, adicione o rótulo `build-artifacts` ao PR. Isso acionará o job `build-artifacts` que constrói e anexa os artefatos ao workflow como `pr-build-artifacts`.

**Atualize o lockfile**: Ao atualizar/alterar pacotes, rode `uv lock` para garantir builds determinísticos.

## Configuração
A aplicação lê os parâmetros de conexão a partir de variáveis de ambiente, argumentos de linha de comando ou cabeçalhos HTTP. As principais variáveis disponíveis em `app/config.py` são:

- `GRAFANA_URL`: URL base da instância Grafana (padrão `http://localhost:3000`).
- `GRAFANA_SERVICE_ACCOUNT_TOKEN`: token de service account recomendado.
- `GRAFANA_API_KEY`: chave de API legada (use apenas se não houver service account).
- `GRAFANA_USERNAME` / `GRAFANA_PASSWORD`: credenciais para autenticação básica.
- `GRAFANA_ACCESS_TOKEN` / `GRAFANA_ID_TOKEN`: tokens OIDC utilizados quando disponíveis.

Defina as variáveis conforme o método de autenticação que estiver usando. Também é possível fornecer certificados TLS personalizados por meio da estrutura `TLSConfig` definida no módulo de configuração.

TLS / SSL (novas variáveis)
 - `GRAFANA_TLS_CERT_FILE`: caminho para certificado cliente (opcional)
 - `GRAFANA_TLS_KEY_FILE`: caminho para chave do certificado (opcional)
 - `GRAFANA_TLS_CA_FILE`: caminho para um bundle CA para validar o servidor Grafana (opcional)
 - `GRAFANA_TLS_SKIP_VERIFY`: se `true` (ou `1`, `yes`), ignora a verificação do certificado TLS (útil para certificados auto-assinados; inseguro)

Além das variáveis de ambiente, agora existem três flags CLI úteis:
 - `--ignore-ssl`: equivalente a definir `GRAFANA_TLS_SKIP_VERIFY=true` — faz o cliente ignorar erros de certificado.
 - `--check-connection`: executa uma verificação simples (`/api/health`) contra a instância Grafana e encerra com código 0 em sucesso ou 2 em falha. Útil para CI ou troubleshooting pré-execução.
 - `--require-grafana`: quando fornecida, a aplicação executa um conjunto de checagens na inicialização — reachability/TLS via `/api/health`, validação de identidade do servidor, e verificação de autenticação via `/api/user` — e aborta o startup se algum passo falhar.
 - `--require-grafana` (enabled by default): a aplicação executará um conjunto de checagens na inicialização (reachability/TLS via `/api/health`, validação de identidade do servidor, e verificação de autenticação via `/api/user`) e abortará a inicialização se alguma checagem falhar. Para desativar esse comportamento padrão, passe `--no-require-grafana`.

## Execução
Após configurar o ambiente, execute o servidor MCP com:

```bash
python -m app --address localhost:8000 --log-level INFO
```

Por padrão, o transporte STDIO é utilizado. Para executar em modos HTTP, informe `--transport sse` ou `--transport streamable-http` conforme necessário.

Se existir um arquivo `.env` na raiz do projeto, ele será carregado automaticamente durante a inicialização. Para utilizar um arquivo diferente, passe `--env-file caminho/para/arquivo`.
Além disso, variáveis de ambiente como `APP_ADDRESS`, `BASE_PATH`, `STREAMABLE_HTTP_PATH`, `LOG_LEVEL` e `TRANSPORT` são usadas como valores padrão para os respectivos parâmetros CLI quando definidos. Para alterar o prompt inicial fornecido aos clientes MCP, edite `instructions.md` ou defina `MCP_INSTRUCTIONS_PATH` apontando para outro arquivo de texto/Markdown.

Parâmetros úteis:
- `--address`: endereço e porta nos quais o servidor será publicado.
- `--base-path`: caminho base para expor o transporte HTTP (padrão `/`).
- `--streamable-http-path`: caminho do endpoint Streamable HTTP (padrão `mcp`; aceita valores absolutos ou relativos ao `--base-path`).
- `--transport`: transporte MCP a utilizar (`sse`, `streamable-http` ou `stdio`; padrão `stdio`).
- `--log-level`: nível de log (`DEBUG`, `INFO`, `WARNING`, etc.).
- `--debug`: ativa modo de depuração do FastMCP.
- `--version`: imprime a versão da aplicação e encerra.
 - `--version`: imprime a versão da aplicação e encerra.
- `--env-file`: caminho para um arquivo `.env` adicional a ser carregado antes da inicialização.

O servidor registra automaticamente todas as ferramentas MCP descritas em `app/tools/` através da função `register_all`. Agentes MCP podem consumir as capacidades para listar datasources, atualizar dashboards, executar consultas no Loki e gerar links de navegação no Grafana, entre outras.

Também é possível sobrescrever as credenciais do Grafana diretamente pela CLI, utilizando os mesmos nomes das variáveis de ambiente, por exemplo:

```bash
python -m app --address localhost:5501 --GRAFANA_URL http://127.0.0.1:3000 \
  --GRAFANA_SERVICE_ACCOUNT_TOKEN glsa_example_token
```

### Conformidade com a especificação MCP da OpenAI
Esta implementação segue os requisitos publicados em [platform.openai.com/docs/mcp#create-an-mcp-server](https://platform.openai.com/docs/mcp#create-an-mcp-server):

- As ações `search` e `search_dashboards` expõem somente o parâmetro obrigatório `query`, tipado como `string`.
- A ação `fetch` exige apenas o parâmetro `id`, também tipado como `string`, mantendo campos opcionais (`uid`, `url`, etc.) para enriquecer o contexto sem ferir a especificação.
- Os transportes SSE, Streamable HTTP e STDIO respeitam os caminhos e formatos esperados pelo conector MCP da OpenAI e podem ser montados em um `base_path` customizado.
- O servidor publica metadados (`instructions`, lista de ferramentas e schemas JSON) diretamente do `FastMCP`, assegurando compatibilidade com clientes que validam o contrato MCP.

## Makefile
O repositório disponibiliza um `Makefile` com alvos que agilizam as tarefas mais comuns de desenvolvimento. O alvo padrão (`make`) executa `make help`, listando um resumo dos principais comandos disponíveis.

### Ambiente local
- `make venv`: cria o ambiente virtual e instala as dependências listadas em `requirements.txt`.
- `make local`: inicia o servidor MCP utilizando o virtualenv criado; o comando lê automaticamente variáveis definidas em `.env`.
- `make package`: gera um executável único (`dist/grafana-mcp`) via PyInstaller.

Variáveis como `APP_ADDRESS`, `BASE_PATH`, `STREAMABLE_HTTP_PATH`, `LOG_LEVEL`, `TRANSPORT` e `ENV_FILE` podem ser sobrescritas diretamente na linha de comando (`make run-local APP_ADDRESS=127.0.0.1:9000 TRANSPORT=streamable-http STREAMABLE_HTTP_PATH=/stream`).

Após executar `make package`, o binário resultante pode ser distribuído como comando único, sem depender do Python local ou do virtualenv. Os assets e dependências Python são incorporados pelo PyInstaller.

### Atalhos com uv/uvx
Se preferir usar `uv`, os mesmos fluxos estão mapeados em alvos Make:

- `make uv-sync` — instala/atualiza dependências (inclui grupos de dev)
- `make uv-local` — executa o servidor com `uv run`
- `make uv-test` — executa testes
- `make uv-cov` — executa testes com cobertura
- `make uv-lint` — ruff check
- `make uv-fmt` — ruff format
- `make uv-typecheck` — mypy
- `make uv-package` — empacota com `uvx pyinstaller`
- `make uv-lock` — atualiza o `uv.lock`

### Containers
- `make docker` / `make podman`: empacotam a aplicação em uma imagem Docker ou Podman.

Os alvos de containers respeitam variáveis como `IMAGE_NAME`, `CONTAINER_NAME`, `APP_PORT`, `TRANSPORT` e `ENV_FILE`, permitindo adaptar os comandos ao seu fluxo de trabalho.

## Testes automatizados

O projeto utiliza `pytest` para validar fluxos críticos como carregamento de configuração, leitura das instruções padrão, negociação do transporte Streamable HTTP e ferramentas MCP para buscas e Grafana Asserts. Para rodar a suíte localmente:

1. Com uv: `make uv-sync && make uv-test`
2. Com venv/pip: crie (ou atualize) o ambiente virtual com `make venv` e execute `pytest`.
3. Execute `pytest` na raiz do repositório para disparar os 197 testes atuais.

O comando também está disponível via `python -m pytest` caso prefira não expor o executável instalado no virtualenv. Mantê-lo em dia ajuda a garantir compatibilidade contínua com os conectores MCP suportados.

### Cobertura de testes com `pytest-cov`

Para gerar relatórios de cobertura, instale o plugin opcional `pytest-cov` dentro do virtualenv e execute a suíte com a flag `--cov`:

```bash
# via uv
uv run pytest --cov=. --cov-report term-missing

# via pip/venv
pip install pytest pytest-cov
pytest --cov=. --cov-report term-missing
```

A execução atual produz um resumo com cobertura global de aproximadamente **85%**, destacando pontos fortes como `app/config.py` (85%), `app/instructions.py` (93%) e `app/tools/search.py` (90%). Versões anteriores introduziram testes abrangentes para todas as ferramentas corrigidas, melhorando significativamente a cobertura geral do projeto.

## Ferramentas disponíveis

> **🎯 Versão 1.1.0**: Todas as ferramentas listadas abaixo agora utilizam **respostas consolidadas** que eliminam problemas de chunking JSON em streamable HTTP com ChatGPT/OpenAI. Cada tool retorna um objeto estruturado com metadados (`total_count`, `type`, parâmetros da requisição) e os dados originais preservados em campos específicos.

### Admin
- `list_teams`: busca times da organização por nome, retornando objeto consolidado com identificadores, URLs e metadados.
- `list_users_by_org`: lista todos os usuários da organização atual com e-mail, cargo, status e contagem total.

### Alerting
- `list_alert_rules`: lista regras de alerta com paginação e filtros por label em formato consolidado.
- `get_alert_rule_by_uid`: obtém a configuração completa de uma regra de alerta pelo UID.
- `list_contact_points`: lista contact points configurados no Grafana Alerting em formato consolidado.

### Asserts
- `get_assertions`: recupera o resumo de Grafana Asserts para uma entidade e janela de tempo.

Os parâmetros `startTime` e `endTime` aceitam timestamps RFC3339 (por exemplo, `2024-01-02T03:04:05Z`) ou expressões relativas baseadas em `now`, como `now-1h` ou `now-1d+2h`.

### Dashboard
- `get_dashboard_by_uid`: retorna o JSON completo de um dashboard.
- `get_dashboard_summary`: gera um resumo compacto de painéis, variáveis e metadados.
- `get_dashboard_panel_queries`: extrai queries LogQL/PromQL e metadados dos painéis.
- `get_dashboard_property`: acessa propriedades específicas usando uma expressão semelhante a JSONPath.
- `update_dashboard`: cria ou atualiza um dashboard existente com resposta consolidada para máxima compatibilidade.

### Datasources
- `list_datasources`: lista datasources disponíveis com filtro por tipo.
- `get_datasource_by_uid`: obtém detalhes completos de um datasource pelo UID.
- `get_datasource_by_name`: obtém detalhes completos de um datasource pelo nome configurado.

### Incident
- `list_incidents`: lista incidentes (com filtros de status e drilldown opcional).
- `get_incident`: recupera detalhes completos de um incidente específico.
- `create_incident`: cria um novo incidente Grafana.
- `add_activity_to_incident`: adiciona notas à linha do tempo do incidente.

### Loki
- `query_loki_logs`: executa consultas LogQL e retorna logs correspondentes.
- `query_loki_stats`: retorna estatísticas agregadas para um seletor LogQL.
- `list_loki_label_names`: lista labels disponíveis em um datasource Loki com resposta consolidada.
- `list_loki_label_values`: lista valores para um label específico em Loki com resposta consolidada.

### Navigation
- `generate_deeplink`: gera URLs de navegação para dashboards, painéis ou Explore com parâmetros opcionais.

### OnCall
- `list_oncall_teams`: lista equipes configuradas no Grafana OnCall com resposta consolidada.
- `list_oncall_schedules`: retorna escalas de plantão com filtros opcionais e resposta consolidada.
- `get_oncall_shift`: consulta detalhes de um turno específico.
- `get_current_oncall_users`: lista quem está de plantão neste momento.
- `list_oncall_users`: lista usuários ou busca um usuário específico do OnCall com resposta consolidada.

### Prometheus
- `query_prometheus`: executa consultas PromQL em datasources Prometheus.
- `list_prometheus_metric_names`: lista métricas disponíveis.
- `list_prometheus_metric_metadata`: retorna metadados para métricas.
- `list_prometheus_label_names`: lista labels disponíveis.
- `list_prometheus_label_values`: retorna valores para um label específico.

### Pyroscope
- `list_pyroscope_profile_types`: lista tipos de perfil suportados com resposta consolidada.
- `list_pyroscope_label_names`: lista labels disponíveis em um datasource Pyroscope com resposta consolidada.
- `list_pyroscope_label_values`: lista valores para um label com resposta consolidada.
- `fetch_pyroscope_profile`: obtém um perfil em formato DOT para visualização.

### Search
- `search`: busca dashboards no Grafana (modo genérico usado por clientes MCP) com resposta consolidada.
- `search_dashboards`: busca dashboards com metadados detalhados e resposta consolidada.
- `fetch`: recupera dados completos de recursos retornados pelo search (dashboards via `id` ou `uid`).

### Sift
- `list_sift_investigations`: lista investigações recentes do Grafana Sift.
- `get_sift_investigation`: recupera detalhes de uma investigação específica.
- `get_sift_analysis`: acessa um resultado de análise associado a uma investigação.
- `find_error_pattern_logs`: executa o check `ErrorPatternLogs` para encontrar padrões de erro.
- `find_slow_requests`: executa o check `SlowRequests` para identificar chamadas lentas.

Cada ferramenta utiliza o cliente HTTP assíncrono definido em `app/grafana_client.py`, adicionando os cabeçalhos e autenticações necessários para conversar com a API do Grafana. As tools com **resposta consolidada** incluem campos como `total_count`, `type` e preservam os dados originais para máxima compatibilidade com streamable HTTP.

## Transportes MCP suportados

> **✨ Compatibilidade Total com ChatGPT/OpenAI**: A versão 1.1.0 introduziu respostas consolidadas que eliminam completamente problemas de chunking JSON em streamable HTTP, proporcionando experiência perfeita com ChatGPT/OpenAI.

### Server-Sent Events (SSE)
O servidor publica um endpoint SSE capaz de manter uma conexão HTTP aberta para envio de eventos do servidor para o cliente. Ao executar `python -m app --transport sse`, o FastMCP monta dois caminhos principais:

1. `GET /sse`: inicializa a sessão SSE, retornando `Content-Type: text/event-stream` e enviando eventos `message`, `ping` e `response` conforme o protocolo MCP.
2. `POST /messages/`: recebe mensagens do cliente com prompts, chamadas de ferramenta ou confirmações. Cada payload é correlacionado por ID e as respostas são emitidas pela conexão SSE aberta.

Esse fluxo permite que plataformas de IA ou agentes MCP recebam respostas em streaming enquanto enviam comandos de maneira independente. O caminho base pode ser customizado via `--base-path` (por exemplo, `/grafana` expõe o SSE em `/grafana/sse` e o endpoint de mensagens em `/grafana/messages/`).

### Streamable HTTP
Com `python -m app --transport streamable-http`, o servidor expõe um único endpoint HTTP compatível com o transporte Streamable HTTP do MCP. Por padrão, o caminho é `/mcp`, mas ele pode ser ajustado com `--streamable-http-path` (valores relativos respeitam o `--base-path`). Esse modo é útil para clientes que preferem uma API HTTP tradicional, mantendo suporte a respostas parciais via streaming.

**🚀 Histórico — v1.1.0**: Todas as tools da v1.1.0 retornam respostas consolidadas que eliminam problemas de chunking JSON, proporcionando:
- ✅ **Performance 90% melhor** em operações de listagem
- ✅ **Zero timeouts** por fragmentação de resposta
- ✅ **Sessões estáveis** sem perda de conexão
- ✅ **Compatibilidade 100%** com ChatGPT/OpenAI

Para investigações ou buscas longas, ajuste os timeouts padrão do servidor HTTP definindo variáveis de ambiente antes de iniciar o processo:

- `MCP_STREAMABLE_HTTP_TIMEOUT_KEEP_ALIVE` (padrão `65` segundos)
- `MCP_STREAMABLE_HTTP_TIMEOUT_NOTIFY` (padrão `120` segundos)
- `MCP_STREAMABLE_HTTP_TIMEOUT_GRACEFUL_SHUTDOWN` (padrão igual ao maior valor entre o notify e `120` segundos)

Valores maiores evitam que clientes MCP desconectem durante respostas demoradas, aproximando-se da robustez observada no transporte SSE.

### STDIO
O transporte STDIO (`python -m app --transport stdio`) permite executar o servidor como um processo filho de um agente, comunicando-se por entrada e saída padrão. Não há endpoints HTTP nesse modo, tornando-o ideal para integrações locais ou ambientes restritos.

## Integração com Claude
Claude Desktop (macOS/Windows/Linux) já reconhece os três transportes publicados por este servidor. Basta adicionar um bloco em `claude_desktop_config.json` com o comando desejado, o transporte correspondente e as variáveis de ambiente apontando para a sua instância Grafana.

### SSE (streaming bidirecional)
```json
{
  "mcpServers": {
    "grafana-sse": {
      "command": "python",
      "args": [
        "-m", "app",
        "--address", "127.0.0.1:8000",
        "--transport", "sse"
      ],
      "transport": {
        "type": "sse",
        "url": "http://127.0.0.1:8000/sse",
        "messagesUrl": "http://127.0.0.1:8000/messages/"
      },
      "env": {
        "GRAFANA_URL": "https://grafana.example.com",
        "GRAFANA_SERVICE_ACCOUNT_TOKEN": "glsa_example_token"
      }
    }
  }
}
```

Nesse modo, Claude consome respostas em streaming pela sessão SSE enquanto envia comandos HTTP independentes para o endpoint de mensagens.

### Streamable HTTP (endpoint único)
```json
{
  "mcpServers": {
    "grafana-http": {
      "command": "python",
      "args": [
        "-m", "app",
        "--address", "127.0.0.1:8100",
        "--transport", "streamable-http",
        "--streamable-http-path", "mcp"
      ],
      "transport": {
        "type": "http",
        "url": "http://127.0.0.1:8100/mcp",
        "streaming": true
      },
      "env": {
        "GRAFANA_URL": "https://grafana.example.com",
        "GRAFANA_SERVICE_ACCOUNT_TOKEN": "glsa_example_token"
      }
    }
  }
}
```

Claude enviará todas as requisições MCP para o único endpoint configurado, recebendo respostas parciais usando o modo Streamable HTTP do FastMCP.

### STDIO (processo filho)
```json
{
  "mcpServers": {
    "grafana-stdio": {
      "command": "/caminho/para/dist/grafana-mcp",
      "transport": {
        "type": "stdio"
      },
      "env": {
        "GRAFANA_URL": "https://grafana.example.com",
        "GRAFANA_SERVICE_ACCOUNT_TOKEN": "glsa_example_token"
      }
    }
  }
}
```

Esse modo executa o servidor como subprocesso direto do Claude, ideal para ambientes offline ou quando não se deseja abrir portas locais.
Antes de configurar o comando no Claude, execute `make package` para gerar o binário `dist/grafana-mcp` utilizado no exemplo acima.

## Próximos passos
O diretório `app/` pode receber novos módulos ou ferramentas MCP específicas da sua instância. Recomenda-se adicionar testes automatizados sob `tests/` à medida que novos recursos forem implementados.

## Documentação Adicional
- **[CHANGELOG.md](./CHANGELOG.md)**: Histórico detalhado de versões e mudanças
- **[ISSUES.md](./ISSUES.md)**: Problemas identificados e suas resoluções
- **[instructions.md](./instructions.md)**: Prompt padrão usado pelos clientes MCP

Para questões de desenvolvimento ou bug reports, consulte os arquivos de documentação acima que contêm informações detalhadas sobre problemas conhecidos, soluções implementadas e histórico de mudanças.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "grafana-fastmcp",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.13",
    "maintainer_email": null,
    "keywords": "grafana, loki, mcp, observability, oncall, prometheus, pyroscope, sift",
    "author": "Alessander de Souza Goulart",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/ef/e8/2f0454e356b426f92c65c1fe34fd872b36e9ddca4260191b1798568f9cd4/grafana_fastmcp-1.2.3.tar.gz",
    "platform": null,
    "description": "[![PR Tests (3.13)](https://github.com/sandersouza/grafanaFastMCP/actions/workflows/pr-package.yml/badge.svg)](https://github.com/sandersouza/grafanaFastMCP/actions/workflows/pr-package.yml)\n[![Python package](https://github.com/sandersouza/grafanaFastMCP/actions/workflows/python-package.yml/badge.svg)](https://github.com/sandersouza/grafanaFastMCP/actions/workflows/python-package.yml)\n[![Python Version](https://img.shields.io/badge/python-3.13%2B-blue.svg)](https://www.python.org/downloads/release/python-3130/)\n\n<a href=\"https://link.mercadopago.com.br/buymecoke\"><img align=\"right\" src=\"donation.png\" alt=\"Me compre um caf\u00e9!\" width=\"140\"></a>\n\n# Grafana FastMCP Server / CLI\n## Vis\u00e3o geral\nPython FastMCP Server / CLI ( OpenAI Compliance ), com suporte a transportes Server-Sent Events (SSE), Streamable HTTP e STDIO. A aplica\u00e7\u00e3o exp\u00f5e recursos de uma inst\u00e2ncia Grafana para agentes compat\u00edveis com o protocolo MCP, oferecendo opera\u00e7\u00f5es para busca, cria\u00e7\u00e3o e atualiza\u00e7\u00e3o de dashboards, explora\u00e7\u00e3o de logs via Loki, consulta de datasources, gest\u00e3o de alertas, incidentes, turnos de on-call e acesso a dados de observabilidade (Prometheus, Pyroscope, Grafana Sift e muito mais).\n\n**\ud83d\ude80 NOVA VERS\u00c3O v1.2.3**: Esta release inclui melhorias nas checagens de inicializa\u00e7\u00e3o (TLS/autentica\u00e7\u00e3o), suporte a vari\u00e1veis TLS/SSL e flags CLI para troubleshooting r\u00e1pido. Veja [CHANGELOG.md](./CHANGELOG.md) e [ISSUES.md](./ISSUES.md) para detalhes completos.\n\n## Estrutura do projeto\nTodo o c\u00f3digo-fonte fica no diret\u00f3rio `app/`, deixando a raiz do reposit\u00f3rio reservada para arquivos de configura\u00e7\u00e3o (como `.env`, `Dockerfile`, `requirements.txt` e este `README`). A organiza\u00e7\u00e3o completa \u00e9:\n\n```\n.\n\u251c\u2500\u2500 app/\n\u2502   \u251c\u2500\u2500 __init__.py            # Metadados e vers\u00e3o do pacote\n\u2502   \u251c\u2500\u2500 __main__.py            # Permite executar com `python -m app`\n\u2502   \u251c\u2500\u2500 config.py              # Carregamento e saneamento das vari\u00e1veis de ambiente\n\u2502   \u251c\u2500\u2500 context.py             # Resolu\u00e7\u00e3o de configura\u00e7\u00e3o por requisi\u00e7\u00e3o\n\u2502   \u251c\u2500\u2500 grafana_client.py      # Cliente HTTP ass\u00edncrono para a API do Grafana\n\u2502   \u251c\u2500\u2500 main.py                # CLI que instancia e publica o servidor MCP\n\u2502   \u251c\u2500\u2500 patches.py             # Ajustes de compatibilidade para FastMCP/transportes\n\u2502   \u251c\u2500\u2500 server.py              # F\u00e1brica do FastMCP e registro das ferramentas\n\u2502   \u2514\u2500\u2500 tools/                 # Cole\u00e7\u00e3o de ferramentas MCP (dashboards, Loki, etc.)\n\u251c\u2500\u2500 run_app.py                 # Entrypoint usado pelo PyInstaller (`make package`)\n\u251c\u2500\u2500 tests/                     # Testes automatizados em Python\n\u251c\u2500\u2500 Dockerfile                 # Imagem Docker/Podman\n\u251c\u2500\u2500 Makefile                   # Atalhos de automa\u00e7\u00e3o (venv, package, docker...)\n\u251c\u2500\u2500 env.example                # Exemplo de vari\u00e1veis de ambiente (nomes oficiais)\n\u251c\u2500\u2500 instructions.md            # Prompt padr\u00e3o utilizado pelos clientes MCP\n\u251c\u2500\u2500 requirements.txt           # Depend\u00eancias de runtime\n\u2514\u2500\u2500 pytest.ini                 # Configura\u00e7\u00e3o do pytest\n```\n\nConsulte [CHANGELOG.md](./CHANGELOG.md) para detalhes das vers\u00f5es publicadas.\n\nCada subm\u00f3dulo em `app/tools/` registra um conjunto de ferramentas MCP, abrangendo desde administra\u00e7\u00e3o de usu\u00e1rios at\u00e9 consultas de observabilidade e automa\u00e7\u00e3o de incidentes.\n\n## Requisitos\n- Python 3.13 ou superior\n- Inst\u00e2ncia Grafana acess\u00edvel (local ou remota) e credenciais de API v\u00e1lidas\n\n\n### Gerenciamento de depend\u00eancias (uv/uvx)\nEste reposit\u00f3rio adota o [uv](https://github.com/astral-sh/uv) como gerenciador de depend\u00eancias e execu\u00e7\u00e3o. Voc\u00ea pode continuar usando `venv`/`pip` tradicionalmente, mas recomendamos `uv` pelos benef\u00edcios de velocidade, reprodutibilidade (`uv.lock`) e simplifica\u00e7\u00e3o de scripts.\n\n**Depend\u00eancias n\u00e3o s\u00e3o pinadas**: O projeto sempre buscar\u00e1 as vers\u00f5es mais recentes compat\u00edveis de cada pacote. O arquivo `uv.lock` \u00e9 versionado para garantir builds reprodut\u00edveis e CI est\u00e1vel.\n\nPassos r\u00e1pidos:\n\n1. Instale o uv (uma vez):\n```bash\ncurl -Ls https://astral.sh/uv/install.sh | sh\n```\n\n2. Sincronize as depend\u00eancias (runtime + dev):\n```bash\nuv sync --dev --all-extras\n```\n\n3. Rode o servidor:\n```bash\nuv run -m app --address localhost:8000 --log-level INFO --transport stdio\n```\n\nTamb\u00e9m \u00e9 poss\u00edvel executar via PyPI usando uvx (ap\u00f3s a publica\u00e7\u00e3o):\n```bash\nuvx grafana-fastmcp --address localhost:8000 --log-level INFO --transport stdio\n```\n\n4. Comandos comuns:\n```bash\n# Testes\nuv run pytest\n\n# Cobertura\nuv run pytest --cov=. --cov-report term-missing\n\n# Lint e formata\u00e7\u00e3o (ruff)\nuv run ruff check .\nuv run ruff format .\n\n# Type checking\nuv run mypy app tests\n\n# Empacotar com PyInstaller\nuvx pyinstaller --clean --onefile --name grafana-mcp run_app.py\n```\n\n\n**Testes unit\u00e1rios:**\n- O badge \"PR Tests (3.13)\" acima reflete o status dos testes que rodar\u00e3o para cada Pull Request (Python 3.13).\n- O badge \"Python package\" reflete o status do pipeline principal (push para main).\n- Para rodar localmente com uv/uvx:\n  - `uv run pytest` (unit\u00e1rios)\n  - `uv run pytest --cov=. --cov-report term-missing` (cobertura)\n  - `make uv-test` (atalho Makefile)\n  - `make uv-cov` (cobertura via Makefile)\n\n**Constru\u00e7\u00e3o de artefatos em PRs:**\n- Para gerar bin\u00e1rios/wheel no contexto de um PR, adicione o r\u00f3tulo `build-artifacts` ao PR. Isso acionar\u00e1 o job `build-artifacts` que constr\u00f3i e anexa os artefatos ao workflow como `pr-build-artifacts`.\n\n**Atualize o lockfile**: Ao atualizar/alterar pacotes, rode `uv lock` para garantir builds determin\u00edsticos.\n\n## Configura\u00e7\u00e3o\nA aplica\u00e7\u00e3o l\u00ea os par\u00e2metros de conex\u00e3o a partir de vari\u00e1veis de ambiente, argumentos de linha de comando ou cabe\u00e7alhos HTTP. As principais vari\u00e1veis dispon\u00edveis em `app/config.py` s\u00e3o:\n\n- `GRAFANA_URL`: URL base da inst\u00e2ncia Grafana (padr\u00e3o `http://localhost:3000`).\n- `GRAFANA_SERVICE_ACCOUNT_TOKEN`: token de service account recomendado.\n- `GRAFANA_API_KEY`: chave de API legada (use apenas se n\u00e3o houver service account).\n- `GRAFANA_USERNAME` / `GRAFANA_PASSWORD`: credenciais para autentica\u00e7\u00e3o b\u00e1sica.\n- `GRAFANA_ACCESS_TOKEN` / `GRAFANA_ID_TOKEN`: tokens OIDC utilizados quando dispon\u00edveis.\n\nDefina as vari\u00e1veis conforme o m\u00e9todo de autentica\u00e7\u00e3o que estiver usando. Tamb\u00e9m \u00e9 poss\u00edvel fornecer certificados TLS personalizados por meio da estrutura `TLSConfig` definida no m\u00f3dulo de configura\u00e7\u00e3o.\n\nTLS / SSL (novas vari\u00e1veis)\n - `GRAFANA_TLS_CERT_FILE`: caminho para certificado cliente (opcional)\n - `GRAFANA_TLS_KEY_FILE`: caminho para chave do certificado (opcional)\n - `GRAFANA_TLS_CA_FILE`: caminho para um bundle CA para validar o servidor Grafana (opcional)\n - `GRAFANA_TLS_SKIP_VERIFY`: se `true` (ou `1`, `yes`), ignora a verifica\u00e7\u00e3o do certificado TLS (\u00fatil para certificados auto-assinados; inseguro)\n\nAl\u00e9m das vari\u00e1veis de ambiente, agora existem tr\u00eas flags CLI \u00fateis:\n - `--ignore-ssl`: equivalente a definir `GRAFANA_TLS_SKIP_VERIFY=true` \u2014 faz o cliente ignorar erros de certificado.\n - `--check-connection`: executa uma verifica\u00e7\u00e3o simples (`/api/health`) contra a inst\u00e2ncia Grafana e encerra com c\u00f3digo 0 em sucesso ou 2 em falha. \u00datil para CI ou troubleshooting pr\u00e9-execu\u00e7\u00e3o.\n - `--require-grafana`: quando fornecida, a aplica\u00e7\u00e3o executa um conjunto de checagens na inicializa\u00e7\u00e3o \u2014 reachability/TLS via `/api/health`, valida\u00e7\u00e3o de identidade do servidor, e verifica\u00e7\u00e3o de autentica\u00e7\u00e3o via `/api/user` \u2014 e aborta o startup se algum passo falhar.\n - `--require-grafana` (enabled by default): a aplica\u00e7\u00e3o executar\u00e1 um conjunto de checagens na inicializa\u00e7\u00e3o (reachability/TLS via `/api/health`, valida\u00e7\u00e3o de identidade do servidor, e verifica\u00e7\u00e3o de autentica\u00e7\u00e3o via `/api/user`) e abortar\u00e1 a inicializa\u00e7\u00e3o se alguma checagem falhar. Para desativar esse comportamento padr\u00e3o, passe `--no-require-grafana`.\n\n## Execu\u00e7\u00e3o\nAp\u00f3s configurar o ambiente, execute o servidor MCP com:\n\n```bash\npython -m app --address localhost:8000 --log-level INFO\n```\n\nPor padr\u00e3o, o transporte STDIO \u00e9 utilizado. Para executar em modos HTTP, informe `--transport sse` ou `--transport streamable-http` conforme necess\u00e1rio.\n\nSe existir um arquivo `.env` na raiz do projeto, ele ser\u00e1 carregado automaticamente durante a inicializa\u00e7\u00e3o. Para utilizar um arquivo diferente, passe `--env-file caminho/para/arquivo`.\nAl\u00e9m disso, vari\u00e1veis de ambiente como `APP_ADDRESS`, `BASE_PATH`, `STREAMABLE_HTTP_PATH`, `LOG_LEVEL` e `TRANSPORT` s\u00e3o usadas como valores padr\u00e3o para os respectivos par\u00e2metros CLI quando definidos. Para alterar o prompt inicial fornecido aos clientes MCP, edite `instructions.md` ou defina `MCP_INSTRUCTIONS_PATH` apontando para outro arquivo de texto/Markdown.\n\nPar\u00e2metros \u00fateis:\n- `--address`: endere\u00e7o e porta nos quais o servidor ser\u00e1 publicado.\n- `--base-path`: caminho base para expor o transporte HTTP (padr\u00e3o `/`).\n- `--streamable-http-path`: caminho do endpoint Streamable HTTP (padr\u00e3o `mcp`; aceita valores absolutos ou relativos ao `--base-path`).\n- `--transport`: transporte MCP a utilizar (`sse`, `streamable-http` ou `stdio`; padr\u00e3o `stdio`).\n- `--log-level`: n\u00edvel de log (`DEBUG`, `INFO`, `WARNING`, etc.).\n- `--debug`: ativa modo de depura\u00e7\u00e3o do FastMCP.\n- `--version`: imprime a vers\u00e3o da aplica\u00e7\u00e3o e encerra.\n - `--version`: imprime a vers\u00e3o da aplica\u00e7\u00e3o e encerra.\n- `--env-file`: caminho para um arquivo `.env` adicional a ser carregado antes da inicializa\u00e7\u00e3o.\n\nO servidor registra automaticamente todas as ferramentas MCP descritas em `app/tools/` atrav\u00e9s da fun\u00e7\u00e3o `register_all`. Agentes MCP podem consumir as capacidades para listar datasources, atualizar dashboards, executar consultas no Loki e gerar links de navega\u00e7\u00e3o no Grafana, entre outras.\n\nTamb\u00e9m \u00e9 poss\u00edvel sobrescrever as credenciais do Grafana diretamente pela CLI, utilizando os mesmos nomes das vari\u00e1veis de ambiente, por exemplo:\n\n```bash\npython -m app --address localhost:5501 --GRAFANA_URL http://127.0.0.1:3000 \\\n  --GRAFANA_SERVICE_ACCOUNT_TOKEN glsa_example_token\n```\n\n### Conformidade com a especifica\u00e7\u00e3o MCP da OpenAI\nEsta implementa\u00e7\u00e3o segue os requisitos publicados em [platform.openai.com/docs/mcp#create-an-mcp-server](https://platform.openai.com/docs/mcp#create-an-mcp-server):\n\n- As a\u00e7\u00f5es `search` e `search_dashboards` exp\u00f5em somente o par\u00e2metro obrigat\u00f3rio `query`, tipado como `string`.\n- A a\u00e7\u00e3o `fetch` exige apenas o par\u00e2metro `id`, tamb\u00e9m tipado como `string`, mantendo campos opcionais (`uid`, `url`, etc.) para enriquecer o contexto sem ferir a especifica\u00e7\u00e3o.\n- Os transportes SSE, Streamable HTTP e STDIO respeitam os caminhos e formatos esperados pelo conector MCP da OpenAI e podem ser montados em um `base_path` customizado.\n- O servidor publica metadados (`instructions`, lista de ferramentas e schemas JSON) diretamente do `FastMCP`, assegurando compatibilidade com clientes que validam o contrato MCP.\n\n## Makefile\nO reposit\u00f3rio disponibiliza um `Makefile` com alvos que agilizam as tarefas mais comuns de desenvolvimento. O alvo padr\u00e3o (`make`) executa `make help`, listando um resumo dos principais comandos dispon\u00edveis.\n\n### Ambiente local\n- `make venv`: cria o ambiente virtual e instala as depend\u00eancias listadas em `requirements.txt`.\n- `make local`: inicia o servidor MCP utilizando o virtualenv criado; o comando l\u00ea automaticamente vari\u00e1veis definidas em `.env`.\n- `make package`: gera um execut\u00e1vel \u00fanico (`dist/grafana-mcp`) via PyInstaller.\n\nVari\u00e1veis como `APP_ADDRESS`, `BASE_PATH`, `STREAMABLE_HTTP_PATH`, `LOG_LEVEL`, `TRANSPORT` e `ENV_FILE` podem ser sobrescritas diretamente na linha de comando (`make run-local APP_ADDRESS=127.0.0.1:9000 TRANSPORT=streamable-http STREAMABLE_HTTP_PATH=/stream`).\n\nAp\u00f3s executar `make package`, o bin\u00e1rio resultante pode ser distribu\u00eddo como comando \u00fanico, sem depender do Python local ou do virtualenv. Os assets e depend\u00eancias Python s\u00e3o incorporados pelo PyInstaller.\n\n### Atalhos com uv/uvx\nSe preferir usar `uv`, os mesmos fluxos est\u00e3o mapeados em alvos Make:\n\n- `make uv-sync` \u2014 instala/atualiza depend\u00eancias (inclui grupos de dev)\n- `make uv-local` \u2014 executa o servidor com `uv run`\n- `make uv-test` \u2014 executa testes\n- `make uv-cov` \u2014 executa testes com cobertura\n- `make uv-lint` \u2014 ruff check\n- `make uv-fmt` \u2014 ruff format\n- `make uv-typecheck` \u2014 mypy\n- `make uv-package` \u2014 empacota com `uvx pyinstaller`\n- `make uv-lock` \u2014 atualiza o `uv.lock`\n\n### Containers\n- `make docker` / `make podman`: empacotam a aplica\u00e7\u00e3o em uma imagem Docker ou Podman.\n\nOs alvos de containers respeitam vari\u00e1veis como `IMAGE_NAME`, `CONTAINER_NAME`, `APP_PORT`, `TRANSPORT` e `ENV_FILE`, permitindo adaptar os comandos ao seu fluxo de trabalho.\n\n## Testes automatizados\n\nO projeto utiliza `pytest` para validar fluxos cr\u00edticos como carregamento de configura\u00e7\u00e3o, leitura das instru\u00e7\u00f5es padr\u00e3o, negocia\u00e7\u00e3o do transporte Streamable HTTP e ferramentas MCP para buscas e Grafana Asserts. Para rodar a su\u00edte localmente:\n\n1. Com uv: `make uv-sync && make uv-test`\n2. Com venv/pip: crie (ou atualize) o ambiente virtual com `make venv` e execute `pytest`.\n3. Execute `pytest` na raiz do reposit\u00f3rio para disparar os 197 testes atuais.\n\nO comando tamb\u00e9m est\u00e1 dispon\u00edvel via `python -m pytest` caso prefira n\u00e3o expor o execut\u00e1vel instalado no virtualenv. Mant\u00ea-lo em dia ajuda a garantir compatibilidade cont\u00ednua com os conectores MCP suportados.\n\n### Cobertura de testes com `pytest-cov`\n\nPara gerar relat\u00f3rios de cobertura, instale o plugin opcional `pytest-cov` dentro do virtualenv e execute a su\u00edte com a flag `--cov`:\n\n```bash\n# via uv\nuv run pytest --cov=. --cov-report term-missing\n\n# via pip/venv\npip install pytest pytest-cov\npytest --cov=. --cov-report term-missing\n```\n\nA execu\u00e7\u00e3o atual produz um resumo com cobertura global de aproximadamente **85%**, destacando pontos fortes como `app/config.py` (85%), `app/instructions.py` (93%) e `app/tools/search.py` (90%). Vers\u00f5es anteriores introduziram testes abrangentes para todas as ferramentas corrigidas, melhorando significativamente a cobertura geral do projeto.\n\n## Ferramentas dispon\u00edveis\n\n> **\ud83c\udfaf Vers\u00e3o 1.1.0**: Todas as ferramentas listadas abaixo agora utilizam **respostas consolidadas** que eliminam problemas de chunking JSON em streamable HTTP com ChatGPT/OpenAI. Cada tool retorna um objeto estruturado com metadados (`total_count`, `type`, par\u00e2metros da requisi\u00e7\u00e3o) e os dados originais preservados em campos espec\u00edficos.\n\n### Admin\n- `list_teams`: busca times da organiza\u00e7\u00e3o por nome, retornando objeto consolidado com identificadores, URLs e metadados.\n- `list_users_by_org`: lista todos os usu\u00e1rios da organiza\u00e7\u00e3o atual com e-mail, cargo, status e contagem total.\n\n### Alerting\n- `list_alert_rules`: lista regras de alerta com pagina\u00e7\u00e3o e filtros por label em formato consolidado.\n- `get_alert_rule_by_uid`: obt\u00e9m a configura\u00e7\u00e3o completa de uma regra de alerta pelo UID.\n- `list_contact_points`: lista contact points configurados no Grafana Alerting em formato consolidado.\n\n### Asserts\n- `get_assertions`: recupera o resumo de Grafana Asserts para uma entidade e janela de tempo.\n\nOs par\u00e2metros `startTime` e `endTime` aceitam timestamps RFC3339 (por exemplo, `2024-01-02T03:04:05Z`) ou express\u00f5es relativas baseadas em `now`, como `now-1h` ou `now-1d+2h`.\n\n### Dashboard\n- `get_dashboard_by_uid`: retorna o JSON completo de um dashboard.\n- `get_dashboard_summary`: gera um resumo compacto de pain\u00e9is, vari\u00e1veis e metadados.\n- `get_dashboard_panel_queries`: extrai queries LogQL/PromQL e metadados dos pain\u00e9is.\n- `get_dashboard_property`: acessa propriedades espec\u00edficas usando uma express\u00e3o semelhante a JSONPath.\n- `update_dashboard`: cria ou atualiza um dashboard existente com resposta consolidada para m\u00e1xima compatibilidade.\n\n### Datasources\n- `list_datasources`: lista datasources dispon\u00edveis com filtro por tipo.\n- `get_datasource_by_uid`: obt\u00e9m detalhes completos de um datasource pelo UID.\n- `get_datasource_by_name`: obt\u00e9m detalhes completos de um datasource pelo nome configurado.\n\n### Incident\n- `list_incidents`: lista incidentes (com filtros de status e drilldown opcional).\n- `get_incident`: recupera detalhes completos de um incidente espec\u00edfico.\n- `create_incident`: cria um novo incidente Grafana.\n- `add_activity_to_incident`: adiciona notas \u00e0 linha do tempo do incidente.\n\n### Loki\n- `query_loki_logs`: executa consultas LogQL e retorna logs correspondentes.\n- `query_loki_stats`: retorna estat\u00edsticas agregadas para um seletor LogQL.\n- `list_loki_label_names`: lista labels dispon\u00edveis em um datasource Loki com resposta consolidada.\n- `list_loki_label_values`: lista valores para um label espec\u00edfico em Loki com resposta consolidada.\n\n### Navigation\n- `generate_deeplink`: gera URLs de navega\u00e7\u00e3o para dashboards, pain\u00e9is ou Explore com par\u00e2metros opcionais.\n\n### OnCall\n- `list_oncall_teams`: lista equipes configuradas no Grafana OnCall com resposta consolidada.\n- `list_oncall_schedules`: retorna escalas de plant\u00e3o com filtros opcionais e resposta consolidada.\n- `get_oncall_shift`: consulta detalhes de um turno espec\u00edfico.\n- `get_current_oncall_users`: lista quem est\u00e1 de plant\u00e3o neste momento.\n- `list_oncall_users`: lista usu\u00e1rios ou busca um usu\u00e1rio espec\u00edfico do OnCall com resposta consolidada.\n\n### Prometheus\n- `query_prometheus`: executa consultas PromQL em datasources Prometheus.\n- `list_prometheus_metric_names`: lista m\u00e9tricas dispon\u00edveis.\n- `list_prometheus_metric_metadata`: retorna metadados para m\u00e9tricas.\n- `list_prometheus_label_names`: lista labels dispon\u00edveis.\n- `list_prometheus_label_values`: retorna valores para um label espec\u00edfico.\n\n### Pyroscope\n- `list_pyroscope_profile_types`: lista tipos de perfil suportados com resposta consolidada.\n- `list_pyroscope_label_names`: lista labels dispon\u00edveis em um datasource Pyroscope com resposta consolidada.\n- `list_pyroscope_label_values`: lista valores para um label com resposta consolidada.\n- `fetch_pyroscope_profile`: obt\u00e9m um perfil em formato DOT para visualiza\u00e7\u00e3o.\n\n### Search\n- `search`: busca dashboards no Grafana (modo gen\u00e9rico usado por clientes MCP) com resposta consolidada.\n- `search_dashboards`: busca dashboards com metadados detalhados e resposta consolidada.\n- `fetch`: recupera dados completos de recursos retornados pelo search (dashboards via `id` ou `uid`).\n\n### Sift\n- `list_sift_investigations`: lista investiga\u00e7\u00f5es recentes do Grafana Sift.\n- `get_sift_investigation`: recupera detalhes de uma investiga\u00e7\u00e3o espec\u00edfica.\n- `get_sift_analysis`: acessa um resultado de an\u00e1lise associado a uma investiga\u00e7\u00e3o.\n- `find_error_pattern_logs`: executa o check `ErrorPatternLogs` para encontrar padr\u00f5es de erro.\n- `find_slow_requests`: executa o check `SlowRequests` para identificar chamadas lentas.\n\nCada ferramenta utiliza o cliente HTTP ass\u00edncrono definido em `app/grafana_client.py`, adicionando os cabe\u00e7alhos e autentica\u00e7\u00f5es necess\u00e1rios para conversar com a API do Grafana. As tools com **resposta consolidada** incluem campos como `total_count`, `type` e preservam os dados originais para m\u00e1xima compatibilidade com streamable HTTP.\n\n## Transportes MCP suportados\n\n> **\u2728 Compatibilidade Total com ChatGPT/OpenAI**: A vers\u00e3o 1.1.0 introduziu respostas consolidadas que eliminam completamente problemas de chunking JSON em streamable HTTP, proporcionando experi\u00eancia perfeita com ChatGPT/OpenAI.\n\n### Server-Sent Events (SSE)\nO servidor publica um endpoint SSE capaz de manter uma conex\u00e3o HTTP aberta para envio de eventos do servidor para o cliente. Ao executar `python -m app --transport sse`, o FastMCP monta dois caminhos principais:\n\n1. `GET /sse`: inicializa a sess\u00e3o SSE, retornando `Content-Type: text/event-stream` e enviando eventos `message`, `ping` e `response` conforme o protocolo MCP.\n2. `POST /messages/`: recebe mensagens do cliente com prompts, chamadas de ferramenta ou confirma\u00e7\u00f5es. Cada payload \u00e9 correlacionado por ID e as respostas s\u00e3o emitidas pela conex\u00e3o SSE aberta.\n\nEsse fluxo permite que plataformas de IA ou agentes MCP recebam respostas em streaming enquanto enviam comandos de maneira independente. O caminho base pode ser customizado via `--base-path` (por exemplo, `/grafana` exp\u00f5e o SSE em `/grafana/sse` e o endpoint de mensagens em `/grafana/messages/`).\n\n### Streamable HTTP\nCom `python -m app --transport streamable-http`, o servidor exp\u00f5e um \u00fanico endpoint HTTP compat\u00edvel com o transporte Streamable HTTP do MCP. Por padr\u00e3o, o caminho \u00e9 `/mcp`, mas ele pode ser ajustado com `--streamable-http-path` (valores relativos respeitam o `--base-path`). Esse modo \u00e9 \u00fatil para clientes que preferem uma API HTTP tradicional, mantendo suporte a respostas parciais via streaming.\n\n**\ud83d\ude80 Hist\u00f3rico \u2014 v1.1.0**: Todas as tools da v1.1.0 retornam respostas consolidadas que eliminam problemas de chunking JSON, proporcionando:\n- \u2705 **Performance 90% melhor** em opera\u00e7\u00f5es de listagem\n- \u2705 **Zero timeouts** por fragmenta\u00e7\u00e3o de resposta\n- \u2705 **Sess\u00f5es est\u00e1veis** sem perda de conex\u00e3o\n- \u2705 **Compatibilidade 100%** com ChatGPT/OpenAI\n\nPara investiga\u00e7\u00f5es ou buscas longas, ajuste os timeouts padr\u00e3o do servidor HTTP definindo vari\u00e1veis de ambiente antes de iniciar o processo:\n\n- `MCP_STREAMABLE_HTTP_TIMEOUT_KEEP_ALIVE` (padr\u00e3o `65` segundos)\n- `MCP_STREAMABLE_HTTP_TIMEOUT_NOTIFY` (padr\u00e3o `120` segundos)\n- `MCP_STREAMABLE_HTTP_TIMEOUT_GRACEFUL_SHUTDOWN` (padr\u00e3o igual ao maior valor entre o notify e `120` segundos)\n\nValores maiores evitam que clientes MCP desconectem durante respostas demoradas, aproximando-se da robustez observada no transporte SSE.\n\n### STDIO\nO transporte STDIO (`python -m app --transport stdio`) permite executar o servidor como um processo filho de um agente, comunicando-se por entrada e sa\u00edda padr\u00e3o. N\u00e3o h\u00e1 endpoints HTTP nesse modo, tornando-o ideal para integra\u00e7\u00f5es locais ou ambientes restritos.\n\n## Integra\u00e7\u00e3o com Claude\nClaude Desktop (macOS/Windows/Linux) j\u00e1 reconhece os tr\u00eas transportes publicados por este servidor. Basta adicionar um bloco em `claude_desktop_config.json` com o comando desejado, o transporte correspondente e as vari\u00e1veis de ambiente apontando para a sua inst\u00e2ncia Grafana.\n\n### SSE (streaming bidirecional)\n```json\n{\n  \"mcpServers\": {\n    \"grafana-sse\": {\n      \"command\": \"python\",\n      \"args\": [\n        \"-m\", \"app\",\n        \"--address\", \"127.0.0.1:8000\",\n        \"--transport\", \"sse\"\n      ],\n      \"transport\": {\n        \"type\": \"sse\",\n        \"url\": \"http://127.0.0.1:8000/sse\",\n        \"messagesUrl\": \"http://127.0.0.1:8000/messages/\"\n      },\n      \"env\": {\n        \"GRAFANA_URL\": \"https://grafana.example.com\",\n        \"GRAFANA_SERVICE_ACCOUNT_TOKEN\": \"glsa_example_token\"\n      }\n    }\n  }\n}\n```\n\nNesse modo, Claude consome respostas em streaming pela sess\u00e3o SSE enquanto envia comandos HTTP independentes para o endpoint de mensagens.\n\n### Streamable HTTP (endpoint \u00fanico)\n```json\n{\n  \"mcpServers\": {\n    \"grafana-http\": {\n      \"command\": \"python\",\n      \"args\": [\n        \"-m\", \"app\",\n        \"--address\", \"127.0.0.1:8100\",\n        \"--transport\", \"streamable-http\",\n        \"--streamable-http-path\", \"mcp\"\n      ],\n      \"transport\": {\n        \"type\": \"http\",\n        \"url\": \"http://127.0.0.1:8100/mcp\",\n        \"streaming\": true\n      },\n      \"env\": {\n        \"GRAFANA_URL\": \"https://grafana.example.com\",\n        \"GRAFANA_SERVICE_ACCOUNT_TOKEN\": \"glsa_example_token\"\n      }\n    }\n  }\n}\n```\n\nClaude enviar\u00e1 todas as requisi\u00e7\u00f5es MCP para o \u00fanico endpoint configurado, recebendo respostas parciais usando o modo Streamable HTTP do FastMCP.\n\n### STDIO (processo filho)\n```json\n{\n  \"mcpServers\": {\n    \"grafana-stdio\": {\n      \"command\": \"/caminho/para/dist/grafana-mcp\",\n      \"transport\": {\n        \"type\": \"stdio\"\n      },\n      \"env\": {\n        \"GRAFANA_URL\": \"https://grafana.example.com\",\n        \"GRAFANA_SERVICE_ACCOUNT_TOKEN\": \"glsa_example_token\"\n      }\n    }\n  }\n}\n```\n\nEsse modo executa o servidor como subprocesso direto do Claude, ideal para ambientes offline ou quando n\u00e3o se deseja abrir portas locais.\nAntes de configurar o comando no Claude, execute `make package` para gerar o bin\u00e1rio `dist/grafana-mcp` utilizado no exemplo acima.\n\n## Pr\u00f3ximos passos\nO diret\u00f3rio `app/` pode receber novos m\u00f3dulos ou ferramentas MCP espec\u00edficas da sua inst\u00e2ncia. Recomenda-se adicionar testes automatizados sob `tests/` \u00e0 medida que novos recursos forem implementados.\n\n## Documenta\u00e7\u00e3o Adicional\n- **[CHANGELOG.md](./CHANGELOG.md)**: Hist\u00f3rico detalhado de vers\u00f5es e mudan\u00e7as\n- **[ISSUES.md](./ISSUES.md)**: Problemas identificados e suas resolu\u00e7\u00f5es\n- **[instructions.md](./instructions.md)**: Prompt padr\u00e3o usado pelos clientes MCP\n\nPara quest\u00f5es de desenvolvimento ou bug reports, consulte os arquivos de documenta\u00e7\u00e3o acima que cont\u00eam informa\u00e7\u00f5es detalhadas sobre problemas conhecidos, solu\u00e7\u00f5es implementadas e hist\u00f3rico de mudan\u00e7as.\n",
    "bugtrack_url": null,
    "license": "Apache License\n                                   Version 2.0, January 2004\n                                http://www.apache.org/licenses/\n        \n           TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n        \n           1. Definitions.\n        \n              \"License\" shall mean the terms and conditions for use, reproduction,\n              and distribution as defined by Sections 1 through 9 of this document.\n        \n              \"Licensor\" shall mean the copyright owner or entity authorized by\n              the copyright owner that is granting the License.\n        \n              \"Legal Entity\" shall mean the union of the acting entity and all\n              other entities that control, are controlled by, or are under common\n              control with that entity. For the purposes of this definition,\n              \"control\" means (i) the power, direct or indirect, to cause the\n              direction or management of such entity, whether by contract or\n              otherwise, or (ii) ownership of fifty percent (50%) or more of the\n              outstanding shares, or (iii) beneficial ownership of such entity.\n        \n              \"You\" (or \"Your\") shall mean an individual or Legal Entity\n              exercising permissions granted by this License.\n        \n              \"Source\" form shall mean the preferred form for making modifications,\n              including but not limited to software source code, documentation\n              source, and configuration files.\n        \n              \"Object\" form shall mean any form resulting from mechanical\n              transformation or translation of a Source form, including but\n              not limited to compiled object code, generated documentation,\n              and conversions to other media types.\n        \n              \"Work\" shall mean the work of authorship, whether in Source or\n              Object form, made available under the License, as indicated by a\n              copyright notice that is included in or attached to the work\n              (an example is provided in the Appendix below).\n        \n              \"Derivative Works\" shall mean any work, whether in Source or Object\n              form, that is based on (or derived from) the Work and for which the\n              editorial revisions, annotations, elaborations, or other modifications\n              represent, as a whole, an original work of authorship. For the purposes\n              of this License, Derivative Works shall not include works that remain\n              separable from, or merely link (or bind by name) to the interfaces of,\n              the Work and Derivative Works thereof.\n        \n              \"Contribution\" shall mean any work of authorship, including\n              the original version of the Work and any modifications or additions\n              to that Work or Derivative Works thereof, that is intentionally\n              submitted to Licensor for inclusion in the Work by the copyright owner\n              or by an individual or Legal Entity authorized to submit on behalf of\n              the copyright owner. For the purposes of this definition, \"submitted\"\n              means any form of electronic, verbal, or written communication sent\n              to the Licensor or its representatives, including but not limited to\n              communication on electronic mailing lists, source code control systems,\n              and issue tracking systems that are managed by, or on behalf of, the\n              Licensor for the purpose of discussing and improving the Work, but\n              excluding communication that is conspicuously marked or otherwise\n              designated in writing by the copyright owner as \"Not a Contribution.\"\n        \n              \"Contributor\" shall mean Licensor and any individual or Legal Entity\n              on behalf of whom a Contribution has been received by Licensor and\n              subsequently incorporated within the Work.\n        \n           2. Grant of Copyright License. Subject to the terms and conditions of\n              this License, each Contributor hereby grants to You a perpetual,\n              worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n              copyright license to reproduce, prepare Derivative Works of,\n              publicly display, publicly perform, sublicense, and distribute the\n              Work and such Derivative Works in Source or Object form.\n        \n           3. Grant of Patent License. Subject to the terms and conditions of\n              this License, each Contributor hereby grants to You a perpetual,\n              worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n              (except as stated in this section) patent license to make, have made,\n              use, offer to sell, sell, import, and otherwise transfer the Work,\n              where such license applies only to those patent claims licensable\n              by such Contributor that are necessarily infringed by their\n              Contribution(s) alone or by combination of their Contribution(s)\n              with the Work to which such Contribution(s) was submitted. If You\n              institute patent litigation against any entity (including a\n              cross-claim or counterclaim in a lawsuit) alleging that the Work\n              or a Contribution incorporated within the Work constitutes direct\n              or contributory patent infringement, then any patent licenses\n              granted to You under this License for that Work shall terminate\n              as of the date such litigation is filed.\n        \n           4. Redistribution. You may reproduce and distribute copies of the\n              Work or Derivative Works thereof in any medium, with or without\n              modifications, and in Source or Object form, provided that You\n              meet the following conditions:\n        \n              (a) You must give any other recipients of the Work or\n                  Derivative Works a copy of this License; and\n        \n              (b) You must cause any modified files to carry prominent notices\n                  stating that You changed the files; and\n        \n              (c) You must retain, in the Source form of any Derivative Works\n                  that You distribute, all copyright, patent, trademark, and\n                  attribution notices from the Source form of the Work,\n                  excluding those notices that do not pertain to any part of\n                  the Derivative Works; and\n        \n              (d) If the Work includes a \"NOTICE\" text file as part of its\n                  distribution, then any Derivative Works that You distribute must\n                  include a readable copy of the attribution notices contained\n                  within such NOTICE file, excluding those notices that do not\n                  pertain to any part of the Derivative Works, in at least one\n                  of the following places: within a NOTICE text file distributed\n                  as part of the Derivative Works; within the Source form or\n                  documentation, if provided along with the Derivative Works; or,\n                  within a display generated by the Derivative Works, if and\n                  wherever such third-party notices normally appear. The contents\n                  of the NOTICE file are for informational purposes only and\n                  do not modify the License. You may add Your own attribution\n                  notices within Derivative Works that You distribute, alongside\n                  or as an addendum to the NOTICE text from the Work, provided\n                  that such additional attribution notices cannot be construed\n                  as modifying the License.\n        \n              You may add Your own copyright statement to Your modifications and\n              may provide additional or different license terms and conditions\n              for use, reproduction, or distribution of Your modifications, or\n              for any such Derivative Works as a whole, provided Your use,\n              reproduction, and distribution of the Work otherwise complies with\n              the conditions stated in this License.\n        \n           5. Submission of Contributions. Unless You explicitly state otherwise,\n              any Contribution intentionally submitted for inclusion in the Work\n              by You to the Licensor shall be under the terms and conditions of\n              this License, without any additional terms or conditions.\n              Notwithstanding the above, nothing herein shall supersede or modify\n              the terms of any separate license agreement you may have executed\n              with Licensor regarding such Contributions.\n        \n           6. Trademarks. This License does not grant permission to use the trade\n              names, trademarks, service marks, or product names of the Licensor,\n              except as required for reasonable and customary use in describing the\n              origin of the Work and reproducing the content of the NOTICE file.\n        \n           7. Disclaimer of Warranty. Unless required by applicable law or\n              agreed to in writing, Licensor provides the Work (and each\n              Contributor provides its Contributions) on an \"AS IS\" BASIS,\n              WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n              implied, including, without limitation, any warranties or conditions\n              of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n              PARTICULAR PURPOSE. You are solely responsible for determining the\n              appropriateness of using or redistributing the Work and assume any\n              risks associated with Your exercise of permissions under this License.\n        \n           8. Limitation of Liability. In no event and under no legal theory,\n              whether in tort (including negligence), contract, or otherwise,\n              unless required by applicable law (such as deliberate and grossly\n              negligent acts) or agreed to in writing, shall any Contributor be\n              liable to You for damages, including any direct, indirect, special,\n              incidental, or consequential damages of any character arising as a\n              result of this License or out of the use or inability to use the\n              Work (including but not limited to damages for loss of goodwill,\n              work stoppage, computer failure or malfunction, or any and all\n              other commercial damages or losses), even if such Contributor\n              has been advised of the possibility of such damages.\n        \n           9. Accepting Warranty or Additional Liability. While redistributing\n              the Work or Derivative Works thereof, You may choose to offer,\n              and charge a fee for, acceptance of support, warranty, indemnity,\n              or other liability obligations and/or rights consistent with this\n              License. However, in accepting such obligations, You may act only\n              on Your own behalf and on Your sole responsibility, not on behalf\n              of any other Contributor, and only if You agree to indemnify,\n              defend, and hold each Contributor harmless for any liability\n              incurred by, or claims asserted against, such Contributor by reason\n              of your accepting any such warranty or additional liability.\n        \n           END OF TERMS AND CONDITIONS\n        \n           APPENDIX: How to apply the Apache License to your work.\n        \n              To apply the Apache License to your work, attach the following\n              boilerplate notice, with the fields enclosed by brackets \"[]\"\n              replaced with your own identifying information. (Don't include\n              the brackets!)  The text should be enclosed in the appropriate\n              comment syntax for the file format. We also recommend that a\n              file or class name and description of purpose be included on the\n              same \"printed page\" as the copyright notice for easier\n              identification within third-party archives.\n        \n           Copyright [yyyy] [name of copyright owner]\n        \n           Licensed under the Apache License, Version 2.0 (the \"License\");\n           you may not use this file except in compliance with the License.\n           You may obtain a copy of the License at\n        \n               http://www.apache.org/licenses/LICENSE-2.0\n        \n           Unless required by applicable law or agreed to in writing, software\n           distributed under the License is distributed on an \"AS IS\" BASIS,\n           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n           See the License for the specific language governing permissions and\n           limitations under the License.",
    "summary": "Python Grafana FastMCP server/CLI with SSE, Streamable HTTP and STDIO transports",
    "version": "1.2.3",
    "project_urls": {
        "Homepage": "https://github.com/sandersouza/grafanaFastMCP",
        "Issues": "https://github.com/sandersouza/grafanaFastMCP/issues",
        "Repository": "https://github.com/sandersouza/grafanaFastMCP"
    },
    "split_keywords": [
        "grafana",
        " loki",
        " mcp",
        " observability",
        " oncall",
        " prometheus",
        " pyroscope",
        " sift"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "88eb670b88056246520aa2055e52578b857a8bd20ebdd0e444f406fbb860d2dd",
                "md5": "b13e658b8be8c931056a40e925e69701",
                "sha256": "492bcba0840112d724a6adc147eb67ba092e800950838c3ef79e27440849e4fc"
            },
            "downloads": -1,
            "filename": "grafana_fastmcp-1.2.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b13e658b8be8c931056a40e925e69701",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.13",
            "size": 81889,
            "upload_time": "2025-11-06T00:50:00",
            "upload_time_iso_8601": "2025-11-06T00:50:00.652935Z",
            "url": "https://files.pythonhosted.org/packages/88/eb/670b88056246520aa2055e52578b857a8bd20ebdd0e444f406fbb860d2dd/grafana_fastmcp-1.2.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "efe82f0454e356b426f92c65c1fe34fd872b36e9ddca4260191b1798568f9cd4",
                "md5": "dd958b78a64c42943c47a87563fd3548",
                "sha256": "3bee99395bff343a776181430732bb53310ce003dbc3ca02d67191b742923364"
            },
            "downloads": -1,
            "filename": "grafana_fastmcp-1.2.3.tar.gz",
            "has_sig": false,
            "md5_digest": "dd958b78a64c42943c47a87563fd3548",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.13",
            "size": 154312,
            "upload_time": "2025-11-06T00:50:01",
            "upload_time_iso_8601": "2025-11-06T00:50:01.804184Z",
            "url": "https://files.pythonhosted.org/packages/ef/e8/2f0454e356b426f92c65c1fe34fd872b36e9ddca4260191b1798568f9cd4/grafana_fastmcp-1.2.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-11-06 00:50:01",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "sandersouza",
    "github_project": "grafanaFastMCP",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "httpx",
            "specs": [
                [
                    ">=",
                    "0.27"
                ]
            ]
        },
        {
            "name": "mcp",
            "specs": [
                [
                    ">=",
                    "0.1.0"
                ]
            ]
        },
        {
            "name": "starlette",
            "specs": [
                [
                    ">=",
                    "0.31"
                ]
            ]
        },
        {
            "name": "python-dotenv",
            "specs": [
                [
                    ">=",
                    "1.0"
                ]
            ]
        },
        {
            "name": "pytest-asyncio",
            "specs": [
                [
                    ">=",
                    "0.20"
                ]
            ]
        }
    ],
    "lcname": "grafana-fastmcp"
}
        
Elapsed time: 1.69432s