Skip to main content
Glama

search_modal_logs

Read-onlyIdempotent

Search Modal app or container logs for errors, tracebacks, or request IDs and return each match with surrounding context. Filter by time range, source, or regex to isolate the relevant lines.

Instructions

Search an app's or container's logs and return each hit WITH surrounding context —
the fastest way to find a traceback, an error or a request ID. Logs are fetched once
and grepped locally, so you get the lines around each match, not just the match.

Covers the stdout/stderr/system streams ONLY. Crash events shown on the Modal
dashboard (e.g. "... exited with ...") are not log lines, so a search for them
returns 0 matches even though the failure is real — check the dashboard instead.

Args:
    identifier: App name/ID ("my-app", "ap-...") or container ID ("ta-...").
    pattern: Text to find, or a Python regex when regex=True.
    target: "auto" (default — "ta-..." is a container), "app", or "container".
    regex / case_sensitive: Match mode. Both default False.
    context_lines: Lines of context each side of a match. Default 3.
    max_matches: Cap on match blocks returned. Default 50.
    since / until: Time range, ISO 8601 or relative ("2h", "30m", "1d"). PREFER a
        bounded range (both ends) when you know roughly when something happened —
        `since` alone fetches every entry from then until now, which on a busy app
        is megabytes and gets cut off at the timeout. Range must be <= 35 days.
    tail: Search only the last N entries (max 20000) instead of a whole range.
        With no since/until/tail, defaults to the last 1000 entries.
    source: Search only "stdout", "stderr", or "system".
    exclude: Drop lines matching this BEFORE searching, to strip repeated noise.
    prefilter: Push `pattern` down to Modal as a server-side substring filter, so
        non-matching lines are never fetched. The big lever for huge logs, but it
        requires regex=False and leaves `context_lines` showing only other matching
        lines — use it to find *where* something is, then re-query that window.
    timestamps: Prefix lines with their timestamp. Default True.
    timeout_seconds: Max seconds spent fetching logs. Default 30.
    env: Modal environment (apps only).

Returns: {match_count (exact, whole log searched), returned (matches actually shown),
returned_blocks, matches (context blocks, matched lines prefixed ">"), excluded_lines,
output_capped}.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
envNo
tailNo
regexNo
sinceNo
untilNo
sourceNo
targetNoauto
excludeNo
patternYes
prefilterNo
identifierYes
timestampsNo
max_matchesNo
context_linesNo
case_sensitiveNo
timeout_secondsNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changedv0.5.0
    • addedInput schema / properties / prefilter
      Added value: +{
      +  "default": false,
      +  "title": "Prefilter",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / until
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Until"
      +}
  2. Changed4 schema fields changedv0.2.2
    • addedInput schema / properties / exclude
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Exclude"
      +}
    • addedInput schema / properties / source
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Source"
      +}
    • changedInput schema / properties / target / default
      Previous value: -"app"New value: +"auto"
    • addedInput schema / properties / timestamps
      Added value: +{
      +  "default": true,
      +  "title": "Timestamps",
      +  "type": "boolean"
      +}
  3. First observedv0.1.0

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, open-world, and idempotent behavior, but the description adds substantial behavioral context beyond structured data: logs are fetched once and grepped locally, crash events are absent from log streams, a single bounded 'since' range can fetch megabytes and be cut off by timeout, and prefilter changes what context_lines shows. These are meaningful, non-obvious behaviors an agent needs to know.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The structure is purposeful: a front-loaded purpose statement, a critical stream-coverage caveat early, and then parameter documentation that earns its place by adding real semantic and operational value. Despite being long, there is little redundancy, and the return-value summary is compact.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-parameter tool with 0% schema coverage, the description covers every parameter's semantics, gives default behaviors, failure modes, performance trade-offs, and explains the return shape. It is complete enough for an agent to select and invoke the tool correctly with no additional information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, and it succeeds: every parameter is explained with non-schema semantics. identifier gets app/container ID prefixes, target gets an 'auto' rule, since/until gets a format warning and a 35-day cap, tail gets a max and default, prefilter gets a clear server-side behavior, and exclude' is defined as pre-search filtering.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Search an app's or container's logs') and clarifies the unique selling point: returns each hit with surrounding context to find tracebacks, errors, or request IDs. It also distinguishes itself from sibling tools by scoping coverage to stdout/stderr/system streams and explicitly excluding Modal dashboard crash events.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance ('fastest way to find a traceback, an error or a request ID') and a clear when-not-to-use case: crash events are not log lines and should be checked on the dashboard. It also gives operational guidance for large logs, such as preferring bounded ranges, using prefilter for huge logs, and re-querying a window after locating the hit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.