Log Tools
The operations tools of the platform’s pod logs: list_log_sources, search_logs and summarize_log_errors.
They read smarter.apps.infrastructure.services.infrastructure .logs: the last 72 hours
of the app (smarter), the Celery workers (smarter-worker, smarter-worker-infrastructure),
beat (smarter-beat) and MariaDB (mariadb). Each query is structured, not LogQL, so the LLM
cannot inject a query of its own.
They are tools of the staff-only Smarter Operations MCP server, built on
SmarterOperationsTool, which records every
call in the audit trail. A result that quotes log lines starts with
UNTRUSTED_DATA_NOTICE, because a log line
can carry text that a user wrote.
Side effects: each call makes one or two HTTP GETs to Loki (in the tests, to the in-memory log service), and the audit trail’s database write. Nothing is cached.
Note
Experimental. The MCPServer was designed and coded by Claude Code (Anthropic’s Claude Opus 5.5), with Lawrence McDaniel as co-author. It is experimental, and will be documented.
- smarter.apps.mcpserver.logs.tools.COMPONENTS = ('smarter', 'smarter-worker', 'smarter-worker-infrastructure', 'smarter-beat', 'mariadb')
the
app.kubernetes.io/nameof their pods.( 'smarter', 'smarter-worker', 'smarter-worker-infrastructure', 'smarter-beat', 'mariadb', )
- Type:
The components whose logs are kept
- class smarter.apps.mcpserver.logs.tools.ListLogSourcesTool(user)[source]
Bases:
SmarterOperationsToolThe
list_log_sourcestool: the components and pods that logged recently.A component that is missing from the list wrote nothing in the period, which usually means that its pods are down. The pods’ names are what
search_logs’podargument takes.- arguments_model
alias of
ListLogSourcesArguments
- description: ClassVar[str] = "List the components and pods that wrote to the logs in the last minutes, from the log store, which keeps 72 hours. A component that is missing has written nothing, e.g. because its pods are down. Pod names change on every deploy and restart: use them with search_logs' pod argument."
What the tool does, and when to call it.
The LLM reads it to decide which tool to call.
- name: ClassVar[str] = 'list_log_sources'
The tool’s name, which the LLM calls it by, e.g.
search_logs.
- run(arguments)[source]
List the components and pods that wrote to the logs in the period.
Side effects: two HTTP GETs to Loki, for the values of the
componentandpodlabels.- Parameters:
arguments (
ListLogSourcesArguments) – The validated arguments.- Return type:
- Returns:
Markdown: the components, those of
COMPONENTSthat wrote nothing, and the pods.- Raises:
LogServiceError – If Loki could not be reached.
InfrastructureNotReadyError – If there is no log store.
- class smarter.apps.mcpserver.logs.tools.SearchLogsTool(user)[source]
Bases:
SmarterOperationsToolThe
search_logstool: the lines of the pod logs that match a set of filters.The filters become a
LogQuery, which the log service turns into escaped LogQL, so the LLM’s text is never run as a query.- arguments_model
alias of
SearchLogsArguments
- description: ClassVar[str] = "Search the logs of the platform's pods, from the log store, which keeps 72 hours. Filter by component, pod, text, a regular expression and the least severe level. Returns the newest matching lines first, each with its time (UTC), component and pod. With no filters, it returns the latest lines, like tail. To find what went wrong, start with summarize_log_errors, then search for a signature it returns."
What the tool does, and when to call it.
The LLM reads it to decide which tool to call.
- run(arguments)[source]
Search the pod logs.
Side effects: one HTTP GET to Loki’s
query_range.- Parameters:
arguments (
SearchLogsArguments) – The validated arguments.- Return type:
- Returns:
Markdown: a heading with the number of lines, then the lines in a code block, after
UNTRUSTED_DATA_NOTICE, or a hint to widen the search if no line matches.- Raises:
SmarterMCPServerToolError – If the query is not valid, e.g. its pattern does not compile.
LogServiceError – If Loki could not be reached, or rejected the query.
InfrastructureNotReadyError – If there is no log store.
- class smarter.apps.mcpserver.logs.tools.SummarizeLogErrorsTool(user)[source]
Bases:
SmarterOperationsToolThe
summarize_log_errorstool: the errors of the pod logs, grouped by their signature.It reads up to
SUMMARY_LINESwarning and error lines, and groups them witherror_groups(), so that the LLM sees each problem once, with how often it happened, rather than thousands of lines.- arguments_model
alias of
SummarizeLogErrorsArguments
- description: ClassVar[str] = "Summarize the errors, and optionally the warnings, in the platform's pod logs over the last minutes: the lines are grouped by component, level and signature (the message without its numbers, ids and quoted values), and each group has its count, its pods, when it was first and last seen, and its latest line. Call it first when a user reports errors, slowness or an outage, then use search_logs for the lines around a group."
What the tool does, and when to call it.
The LLM reads it to decide which tool to call.
- name: ClassVar[str] = 'summarize_log_errors'
The tool’s name, which the LLM calls it by, e.g.
search_logs.
- run(arguments)[source]
Group the errors, and optionally the warnings, of the period.
Side effects: one HTTP GET to Loki’s
query_range.- Parameters:
arguments (
SummarizeLogErrorsArguments) – The validated arguments.- Return type:
- Returns:
Markdown: a heading with the number of lines, then one section for each group, the most frequent first, after
UNTRUSTED_DATA_NOTICE, or a heading that says there were none.- Raises:
SmarterMCPServerToolError – If the query is not valid.
LogServiceError – If Loki could not be reached, or rejected the query.
InfrastructureNotReadyError – If there is no log store.