Last9 MCP Server
oficialTraga perfeitamente o contexto de produção em tempo real—logs, métricas e traces—para o seu ambiente local, corrigindo código automaticamente com mais rapidez.
Documentação
Servidor MCP Last9

Seu agente de IA não sabe o que está quebrado em produção. Isso resolve.
O Servidor MCP Last9 conecta Claude, Cursor, Windsurf e qualquer outro assistente de IA compatível com MCP diretamente aos seus dados de observabilidade de produção — logs, métricas, traces, exceções, consultas de banco de dados, alertas e implantações. O agente para de adivinhar e começa a ler o sinal real.
Comece em 30 segundos (Hospedado)
Nenhum binário para instalar. Nenhum token para gerenciar. Uma URL, OAuth no seu navegador, pronto.
Encontre o slug da sua organização na sua URL do Last9: app.last9.io/<org_slug>/...
Claude Code
claude mcp add --transport http last9 https://app.last9.io/api/v4/organizations/<org_slug>/mcp
Digite /mcp, selecione last9, autentique. É isso.
Cursor
Configurações > MCP > Adicionar Novo Servidor MCP:
{
"mcpServers": {
"last9": {
"type": "http",
"url": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp"
}
}
}
Clique em Conectar, complete o OAuth.
VS Code
Requer v1.99+. Abra a Paleta de Comandos → MCP: Adicionar Servidor, cole a URL, autentique.
Ou diretamente em settings.json:
{
"mcp": {
"servers": {
"last9": {
"type": "http",
"url": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp"
}
}
}
}
Windsurf
Configurações > Cascade > Abrir Mercado MCP > ícone de engrenagem (mcp_config.json):
{
"mcpServers": {
"last9": {
"serverUrl": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp"
}
}
}
Claude Web/Desktop
Configurações > Conectores > Adicionar conector personalizado. Nomeie como last9, cole a URL, autentique.
Requer acesso de administrador à sua organização Claude.
Auto-Hospedado (STDIO)
Use quando seu cliente MCP não suportar transporte HTTP ou quando precisar do servidor rodando localmente.
Instalar
Homebrew:
brew install last9/tap/last9-mcp
NPM:
npm install -g @last9/mcp-server@latest
# or directly:
npx -y @last9/mcp-server@latest
Lançamentos binários (Windows / manual):
Baixe de Lançamentos do GitHub:
| Plataforma | Arquivo |
|---|---|
| Windows (x64) | last9-mcp-server_Windows_x86_64.zip |
| Windows (ARM64) | last9-mcp-server_Windows_arm64.zip |
| Linux (x64) | last9-mcp-server_Linux_x86_64.tar.gz |
| Linux (ARM64) | last9-mcp-server_Linux_arm64.tar.gz |
| macOS (x64) | last9-mcp-server_Darwin_x86_64.tar.gz |
| macOS (ARM64) | last9-mcp-server_Darwin_arm64.tar.gz |
Obter um Token de Atualização
Apenas administradores podem criar tokens.
- Vá para Acesso à API
- Clique em Gerar Token com permissões de Escrita
- Copie-o
Configuração do Cliente
Homebrew:
{
"mcpServers": {
"last9": {
"command": "/opt/homebrew/bin/last9-mcp",
"env": {
"LAST9_REFRESH_TOKEN": "<your_refresh_token>"
}
}
}
}
NPM:
{
"mcpServers": {
"last9": {
"command": "npx",
"args": ["-y", "@last9/mcp-server@latest"],
"env": {
"LAST9_REFRESH_TOKEN": "<your_refresh_token>"
}
}
}
}
Onde colar isso:
| Cliente | Localização |
|---|---|
| Claude Web/Desktop | Configurações > Desenvolvedor > Editar Config (claude_desktop_config.json) |
| Cursor | Configurações > Configurações do Cursor > MCP > Adicionar Novo Servidor MCP Global |
| Windsurf | Configurações > Cascade > Mercado MCP > ícone de engrenagem (mcp_config.json) |
| VS Code | Envolva em { "mcp": { "servers": { ... } } } em settings.json — detalhes |
Configuração STDIO do VS Code
{
"mcp": {
"servers": {
"last9": {
"type": "stdio",
"command": "/opt/homebrew/bin/last9-mcp",
"env": {
"LAST9_REFRESH_TOKEN": "<your_refresh_token>"
}
}
}
}
}
Para NPM: use "command": "npx" e adicione "args": ["-y", "@last9/mcp-server@latest"].
Windows
Após baixar de Lançamentos do GitHub, extraia e aponte para o caminho completo:
{
"mcpServers": {
"last9": {
"command": "C:\\Users\\<user>\\AppData\\Local\\Programs\\last9-mcp-server.exe",
"env": {
"LAST9_REFRESH_TOKEN": "<your_refresh_token>"
}
}
}
}
A rota NPM é mais fácil no Windows — sem gerenciamento de caminho.
Variáveis de Ambiente
| Variável | Padrão | Descrição |
|---|---|---|
LAST9_REFRESH_TOKEN | (obrigatório) | Token de atualização de Acesso à API |
LAST9_DATASOURCE | padrão da org | Nome da fonte de dados/cluster — útil quando você tem múltiplos clusters Levitate |
LAST9_API_HOST | app.last9.io | Substitui o host da API |
LAST9_MAX_GET_LOGS_ENTRIES | 5000 | Máximo de entradas para requisições get_logs em bloco |
LAST9_DEBUG_CHUNKING | false | Defina true para registrar detalhes do planejamento de bloco para get_logs, get_service_logs, get_traces |
LAST9_DISABLE_TELEMETRY | true | Defina false para habilitar rastreamento OTel interno |
OTEL_SDK_DISABLED | — | Variável de ambiente OTel padrão. Substitui LAST9_DISABLE_TELEMETRY |
OTEL_EXPORTER_OTLP_ENDPOINT | — | Endpoint do coletor OTLP (somente quando a telemetria está habilitada) |
OTEL_EXPORTER_OTLP_HEADERS | — | Cabeçalhos de autenticação OTLP (somente quando a telemetria está habilitada) |
O Que Ele Pode Fazer
Saúde do Serviço
get_service_summary— Throughput, taxa de erro, tempo de resposta p95 em todos os serviçosget_service_environments— Ambientes disponíveis para seus serviços. Execute isso primeiro — outras ferramentas APM precisam deenvdaquiget_service_performance_details— Detalhamento completo: throughput, taxa de erro, p50/p90/p95/média/máx, apdex, disponibilidadeget_service_operations_summary— Operações agrupadas por endpoints HTTP, chamadas de BD, mensageria, clientes HTTPget_service_dependency_graph— Mapa de dependências com throughput, latência e taxas de erro para upstream/downstream/infraget_exceptions— Exceções do lado do servidor com filtros de serviço e span
Observabilidade de Banco de Dados
Quatro ferramentas que vão diretamente ao desempenho do seu banco de dados, derivadas de spans de trace do OpenTelemetry. Nenhuma instrumentação extra necessária se você já estiver usando OTel.
get_databases— Descubra todos os bancos de dados em sua infraestrutura: tipo de BD, host, throughput (consultas/min), latência p95, taxa de erro, número de serviços dependentesget_database_slow_queries— As execuções de consulta mais lentas reais, ordenadas por duração, com IDs de trace para detalhar traces completosget_database_queries— Padrões de consulta e agregados: com que frequência uma consulta é executada, duração média/p95, taxa de erroget_database_server_metrics— Métricas do lado do servidor do próprio host do BD (CPU, conexões, taxas de acerto de buffer — depende do seu sistema de BD)
Suporta PostgreSQL, MySQL, MongoDB, Redis, Aerospike e qualquer outro com traces OTel com um atributo db_system.
Prometheus / PromQL
prometheus_range_query— Consultas de intervalo PromQL sobre qualquer métricaprometheus_instant_query— Consultas instantâneas; use funções de rollup comoavg_over_time,sum_over_timeprometheus_label_values— Valores de label para uma determinada sérieprometheus_labels— Todos os labels disponíveis para uma série
Aponte-os para uma fonte de dados/cluster diferente do padrão definindo LAST9_DATASOURCE.
Logs
get_logs— Consultas de log de pipeline JSON completas (agregações, filtros, extração de campos)get_service_logs— Linhas de log brutas para um serviço, filtráveis por severidade e conteúdo do corpoget_log_attributes— Catálogo global de atributos no esquema de log para uma janela de tempoget_log_attributes_for_pipeline— Campos de log realmente presentes para um pipeline em andamento (descoberta com escopo), cada um com seufilter_fieldexatoget_drop_rules— Regras de descarte de log do Painel de Controle Last9add_drop_rule— Crie uma nova regra de descarte para reduzir o volume de log na origem
Traces
get_traces— Consultas de trace de pipeline JSON para buscas amplas e agregaçõesget_service_traces— Traces por ID de trace exato ou nome do serviço. Use quando tiver um ID de trace — é mais rápidoget_trace_attributes— Catálogo global de atributos no esquema de traceget_trace_attributes_for_pipeline— Atributos realmente presentes para um pipeline em andamento (descoberta com escopo), cada um com seufilter_fieldexatoget_trace_attribute_values— Valores distintos para um atributo de trace, opcionalmente com escopo para um pipeline
Eventos de Mudança e Alertas
get_change_events— Implantações, mudanças de configuração, rollbacks. Correlacione incidentes com o que mudouget_alert_config— Configurações de regras de alerta — pesquisáveis por nome, severidade, tipo, tagsget_alerts— Alertas atualmente disparados dentro de uma janela de tempoget_alert_rule_state— Estado histórico de disparo (1/0) por regra de alerta em um intervalo de tempo, agrupado porrule_id. Filtrável por grupo de alerta, nome da regra, filtros de label e estado.get_notification_channels— Canais de notificação configurados (Slack, PagerDuty, e-mail, etc.)
Painéis Personalizados
list_dashboards— Todos os painéis personalizados na sua organização: IDs, nomes e metadadosget_dashboard— Definição completa do painel por ID, incluindo painéis e consultascreate_dashboard— Crie um novo painel personalizado com painéis, consultas e metadadosupdate_dashboard— Atualize um painel existente por ID (painéis de sistema somente leitura retornam um erro)delete_dashboard— Exclua um painel personalizado por ID
Resolução Difusa de Nomes
did_you_mean— Quando o agente não tem certeza sobre o nome de uma entidade, isso retorna as correspondências mais próximas do seu catálogo (serviços, ambientes, hosts, bancos de dados, implantações/namespaces K8s, jobs). Até 3 sugestões com pontuações de similaridade. O servidor chama isso automaticamente antes da maioria das ferramentas quando uma consulta de nome retorna vazia.
Como Funciona
Links diretos em cada resposta. Cada ferramenta retorna um campo deep_link — uma URL direta para o painel Last9 para aquela consulta e intervalo de tempo exatos. O agente pode lhe entregar o link; você clica; você está lá.
Cache de atributos ao vivo. Na inicialização, o servidor busca os nomes reais dos atributos de log e trace dos seus dados e os incorpora nas descrições das ferramentas. Isso significa que o assistente de IA sabe quais campos existem no seu esquema, não apenas uma lista genérica. O cache é atualizado a cada 2 horas.
Resultados grandes em bloco. get_logs e get_traces lidam com grandes conjuntos de resultados por meio de divisão em blocos em vez de truncamento. O limite padrão é de 5000 entradas para logs; configurável via LAST9_MAX_GET_LOGS_ENTRIES.
Desenvolvimento
Modo HTTP, teste com curl, compilação a partir do código fonte
Executar em Modo HTTP
export LAST9_REFRESH_TOKEN="your_refresh_token"
export LAST9_HTTP=true
export LAST9_PORT=8080
./last9-mcp-server
O servidor inicia em http://localhost:8080/mcp.
Testar com curl
MCP Streamable HTTP requer um handshake de inicialização primeiro. Não defina Mcp-Session-Id na primeira requisição.
# Step 1: Initialize
SESSION_ID=$(curl -si -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "curl-test", "version": "1.0"}
}
}' | grep -i "^Mcp-Session-Id:" | awk '{print $2}' | tr -d '\r')
echo "Session: $SESSION_ID"
# Step 2: Send initialized notification
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}}'
# Step 3: List tools
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}'
# Step 4: Call a tool
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_service_logs",
"arguments": {
"service": "your-service-name",
"lookback_minutes": 30,
"limit": 10
}
}
}'
Compilar a Partir do Código Fonte
git clone https://github.com/last9/last9-mcp-server.git
cd last9-mcp-server
go build -o last9-mcp-server
LAST9_HTTP=true ./last9-mcp-server
LAST9_HTTP=true é para desenvolvimento local. Para uso real, o endpoint HTTP hospedado é mais fácil.
Referência de Ferramentas
Todos os parâmetros, padrões de entrada de tempo e detalhes
Entrada de Tempo
- Tempos absolutos (
start_time_iso/end_time_iso, outime_iso) têm precedência sobrelookback_minutes. - Para janelas relativas: use
lookback_minutes. - Para janelas absolutas: use RFC3339/ISO8601 —
2026-02-09T15:04:05Z. - O legado
YYYY-MM-DD HH:MM:SSé aceito apenas para compatibilidade.
get_exceptions
limit(inteiro, opcional): Máximo de exceções. Padrão: 20.lookback_minutes(inteiro, opcional): Padrão: 60.start_time_iso/end_time_iso(string, opcional): Intervalo de tempo absoluto.service_name(string, opcional): Filtrar por serviço.span_name(string, opcional): Filtrar por nome do span.deployment_environment(string, opcional): Filtrar por ambiente.
get_service_summary
start_time_iso/end_time_iso(string, opcional)env(string, opcional): Padrãoprod.
get_service_environments
start_time_iso/end_time_iso(string, opcional)
Todas as outras ferramentas APM requerem um valor
env. Use""se isso retornar vazio.
get_service_performance_details
service_name(string, obrigatório)lookback_minutes(inteiro, opcional): Padrão: 60.start_time_iso/end_time_iso(string, opcional)env(string, opcional): Padrãoprod.
get_service_operations_summary
service_name(string, obrigatório)lookback_minutes(integer, opcional): Padrão: 60.start_time_iso/end_time_iso(string, opcional)env(string, opcional): Padrão:prod.
get_service_dependency_graph
service_name(string, opcional)lookback_minutes(integer, opcional): Padrão: 60.start_time_iso/end_time_iso(string, opcional)env(string, opcional): Padrão:prod.
get_databases
env(string, opcional): Filtrar por ambiente. Padrão: todos.lookback_minutes(integer, opcional): Padrão: 60.start_time_iso/end_time_iso(string, opcional)
get_database_slow_queries
db_system(string, opcional): ex.:postgresql,mysql,mongodb,redis.host(string, opcional): Host do banco de dados (net_peer_name).service_name(string, opcional): Nome do serviço chamador.env(string, opcional)min_duration_ms(float, opcional): Duração mínima da consulta em ms.lookback_minutes(integer, opcional): Padrão: 60.start_time_iso/end_time_iso(string, opcional)limit(integer, opcional): Padrão: 20.
get_database_queries
db_system(string, opcional)host(string, opcional)service_name(string, opcional)env(string, opcional)lookback_minutes(integer, opcional): Padrão: 60.start_time_iso/end_time_iso(string, opcional)limit(integer, opcional): Padrão: 20.
get_database_server_metrics
db_system(string, obrigatório): ex.:postgresql,mysql,mongodb,redis,aerospike.host(string, opcional)lookback_minutes(integer, opcional): Padrão: 60.start_time_iso/end_time_iso(string, opcional)
prometheus_range_query
query(string, obrigatório): A consulta PromQL.start_time_iso/end_time_iso(string, opcional): Padrão: últimos 60 min.lookback_minutes(float, opcional): Padrão: 60.
prometheus_instant_query
query(string, obrigatório)time_iso(string, opcional): Padrão: agora.lookback_minutes(float, opcional)
prometheus_label_values
match_query(string, opcional): Filtro PromQL.label(string, obrigatório): Nome do rótulo.start_time_iso/end_time_iso(string, opcional)
prometheus_labels
match_query(string, opcional): Filtro PromQL.start_time_iso/end_time_iso(string, opcional)
get_logs
logjson_query(array, obrigatório): Consulta de pipeline JSON.lookback_minutes(integer, opcional): Padrão: 5.start_time_iso/end_time_iso(string, opcional)limit(integer, opcional): Padrão do servidor: 5000.index(string, opcional):physical_index:<name>ourehydration_index:<block_name>.
Para inventário de serviços baseado em logs, consulte physical_index_service_count primeiro:
sum by (name, service_name, env) (physical_index_service_count{destination="logs"})
Use service_name como ServiceName, env como o ambiente quando presente e name como o nome do índice físico. Se name="default", omita index; para um índice físico não padrão selecionado pelo usuário, passe index: "physical_index:<name>". Se o backend rejeitar a filtragem explícita por índice físico, tente novamente sem index e informe que a filtragem explícita por índice físico não está disponível para esse backend.
get_service_logs
service(string, obrigatório)lookback_minutes(integer, opcional): Padrão: 60.limit(integer, opcional): Padrão: 20.env(string, opcional)severity_filters(array, opcional): ex.:["error", "warn"]. Lógica OU.body_filters(array, opcional): ex.:["timeout", "failed"]. Lógica OU.start_time_iso/end_time_iso(string, opcional)index(string, opcional)
Múltiplos tipos de filtro são combinados com E. Cada array usa OU internamente.
Use get_logs para contagens agregadas amplas primeiro; use get_service_logs somente após restringir a um serviço/ambiente/índice e um pequeno conjunto de amostras.
get_log_attributes
lookback_minutes(integer, opcional): Padrão: 15.start_time_iso/end_time_iso(string, opcional)region(string, opcional)index(string, opcional)
get_log_attributes_for_pipeline
pipeline(array, obrigatório): Estágios de filtro anteriores para escopo da descoberta, ex.:[{"type":"filter","query":{"$eq":["ServiceName","<service>"]}}].lookback_minutes(integer, opcional): Padrão: 15.start_time_iso/end_time_iso(string, opcional)region(string, opcional)index(string, opcional)
get_drop_rules
Sem parâmetros.
add_drop_rule
name(string, obrigatório)filters(array, obrigatório): Cada filtro:key,value,operator(equals/not_equals),conjunction(and).
get_traces
Use para buscas amplas e agregações. Para busca exata por ID de trace, use get_service_traces.
tracejson_query(array, obrigatório)start_time_iso/end_time_iso(string, opcional)lookback_minutes(integer, opcional): Padrão: 60.limit(integer, opcional): Padrão: 5000.
get_service_traces
Exatamente um de trace_id ou service_name é obrigatório.
trace_id(string, opcional): Janela de busca padrão: 72 horas.service_name(string, opcional): Janela de busca padrão: 60 min.lookback_minutes(integer, opcional)start_time_iso/end_time_iso(string, opcional)limit(integer, opcional): Padrão: 10.env(string, opcional)
get_trace_attributes
lookback_minutes(integer, opcional): Padrão: 15.start_time_iso/end_time_iso(string, opcional)region(string, opcional)
get_trace_attributes_for_pipeline
pipeline(array, obrigatório): Estágios de filtro anteriores para escopo da descoberta, ex.:[{"type":"filter","query":{"$eq":["ServiceName","<service>"]}}].lookback_minutes(integer, opcional): Padrão: 15.start_time_iso/end_time_iso(string, opcional)region(string, opcional)
get_trace_attribute_values
tag_name(string, obrigatório): Nome do atributo deget_trace_attributes(ex.:resource_departmentouattributes['http.method']).pipeline(array, opcional): Estágios de filtro anteriores para escopo dos valores; omita para valores globais.region(string, opcional)
get_change_events
start_time_iso/end_time_iso(string, opcional)lookback_minutes(integer, opcional): Padrão: 60.service(string, opcional)environment(string, opcional)event_name(string, opcional): Chame sem isso primeiro para obteravailable_event_names.
get_alert_config
search_term(string, opcional): Busca por texto livre em nome, grupo, fonte de dados, tags.rule_name(string, opcional)severity(string, opcional)rule_type(string, opcional):staticouanomaly.alert_group_name/alert_group_type/data_source_name(string, opcional)tags(array, opcional): Todos devem corresponder (lógica E).
get_alerts
time_iso(string, opcional): Horário de avaliação em RFC3339.window(integer, opcional): Janela de busca em segundos. Padrão: 900. Intervalo: 60–86400.lookback_minutes(integer, opcional): Intervalo: 1–1440.
get_alert_rule_state
start_time(integer, obrigatório): Início do intervalo em epoch Unix (inclusivo).end_time(integer, obrigatório): Fim do intervalo em epoch Unix (inclusivo).step(integer, obrigatório): Resolução em segundos entre amostras. O número de amostras((end_time - start_time) / step + 1)é limitado a 100.alert_group_id(string, opcional): Filtrar por ID do grupo de alertas.rule_name(string, opcional): Filtro regex no nome da regra.alert_group_name(string, opcional): Filtro regex no nome do grupo de alertas.label_filters(string, opcional): Filtros de rótulokey=valueseparados por vírgula.state(string, opcional): Filtrar por estado (ex.:firing).
Retorna um mapa JSON de rule_id -> [{timestamp, is_firing}]. Um timestamp em que uma regra está ausente da resposta upstream é reportado como is_firing=0 — isso significa "não observado como em disparo", não um estado normal confirmado.
get_notification_channels
Sem parâmetros. Retorna todos os canais de notificação configurados (Slack, PagerDuty, email, webhooks, etc.).
did_you_mean
query(string, obrigatório): O nome a ser pesquisado — parcial, com erro de ortografia ou abreviado.type(string, opcional): Restringir ao tipo de entidade:service,environment,host,database,k8s_deployment,k8s_namespace,job.
Retorna até 3 correspondências mais próximas com pontuações de similaridade. Use isso antes de qualquer chamada de ferramenta onde o nome da entidade seja incerto. Se uma chamada anterior retornou resultados vazios, tente isso antes de tentar novamente.
list_dashboards
Sem parâmetros. Retorna todos os dashboards personalizados na organização como um array JSON com id, name e metadados.
get_dashboard
id(string, obrigatório): UUID do dashboard.region(string, opcional): Região para população de consultas do painel. Padrão: região da fonte de dados configurada.
create_dashboard
dashboard(object, obrigatório): Definição do dashboard comnameepanels[]. Cada painel requername,version,layout(x,y,w,h),visualization.typeequeries[].metadata(object, opcional): Metadados do dashboard — campos_categorye_type(ex.:{"_category":"custom","_type":"metrics"}).
update_dashboard
id(string, obrigatório): UUID do dashboard a ser atualizado.dashboard(object, obrigatório): Corpo completo de substituição do dashboard (mesmo formato da criação).metadata(object, opcional): Metadados de substituição. Dashboards de sistema somente leitura retornam um erro 403.
delete_dashboard
id(string, obrigatório): UUID do dashboard a ser excluído. Dashboards de sistema somente leitura não podem ser excluídos.
Testes
Consulte TESTING.md para configuração e instruções de testes de integração.
