Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
MODAL_PROFILENoOptional. Modal profile name to use.
MODAL_TOKEN_IDYesModal API token ID (create with `modal token new` or from the Modal dashboard). Authenticates the bundled modal CLI.
MODAL_ENVIRONMENTNoOptional. Default Modal environment to target when a tool omits one.
MODAL_TOKEN_SECRETYesModal API token secret paired with MODAL_TOKEN_ID.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
manage_modal_appA
Change a deployed app's state. Both actions affect live traffic.

Args:
    action: "stop" — shut the app down, ending web endpoints (`modal app stop`).
        "rollback" — restore a previous deployment (`modal app rollback`).
    app_identifier: App name ("my-app") or ID ("ap-...").
    version: Rollback target; omit for the immediately preceding version. List valid
        versions with list_modal_resources(resource="app_history", name=...).
    env: Modal environment to target.

Returns: {message, stdout, stderr} or {error}.
manage_modal_containerA
Act on one running container. Find IDs with
list_modal_resources(resource="containers").

Args:
    action: "exec" — run a command inside the container (`modal container exec`).
        This is arbitrary remote code execution: treat it like SSH, not a lookup.
        "stop" — terminate it (`modal container stop`); in-flight inputs are
        cancelled and rescheduled elsewhere.
    container_id: Container ID ("ta-..."). Unique across environments, so no `env`
        argument is needed (the CLI accepts none for these subcommands).
    command: For "exec": argv list, e.g. ["python", "-c", "print('hi')"] or
        ["ls", "-la", "/"].
    timeout_seconds: For "exec": max seconds to wait. Default 60.

Returns: exec → {output, returncode, truncated, output_capped}; stop → {message}.
analyze_modal_costsA
Break down what the workspace is spending (`modal billing`). Costs are fetched once
and aggregated locally, so you get ranked totals and period-over-period changes
rather than hundreds of raw rows.

Answering common questions:
  "what is my costliest app?"     -> view="by_app", period="this month"
  "why was Monday expensive?"     -> view="timeline", period="last week" (the
                                     `explanation` field diffs the peak day against
                                     the day before and ranks which apps grew)
  "what did that day cost hourly?" -> view="timeline", start="2026-08-31",
                                      end="2026-09-01", resolution="h"
  "where does the money go?"      -> view="by_resource" (CPU / GPU / memory / ...)
  "what is the bill this cycle?"  -> view="summary"

Billing is workspace-wide, so this reports across every environment; use
`environment` to narrow it after the fact.

Args:
    view: "by_app" (default), "timeline" (per interval, with an explanation of the
        peak), "by_environment", "by_resource", "summary" (billed vs metered for a
        month cycle), or "rates" (current unit prices).
    period: Convenience range — "today", "yesterday", "this week", "last week",
        "this month", "last month". For "summary" also accepts "YYYY-MM".
    start / end: Explicit range instead of `period` — ISO dates ("2026-08-31") or
        relative ("3 days ago"). Start is inclusive, end exclusive; end defaults to now.
    resolution: "d" (daily, default) or "h" (hourly). Hourly is what you want when
        drilling into a single day.
    timezone: Timezone for interpreting dates — "local", an offset ("+05:30"), or an
        IANA name. Requires resolution="h".
    app: Only include apps whose name or ID contains this string (case-insensitive).
    environment: Only include rows from this Modal environment.
    top_n: How many groups/movers to return. Default 10.
    tag_names: Comma-separated cost-attribution tag names to include.

Returns: {total_cost, groups | intervals, explanation (for timeline), row_count}.
    Costs are strings of US dollars with 4 decimals. `total_cost` always covers every
    row in range, even when `groups` is cut to top_n.
deploy_modal_appA
Deploy a Modal app (`modal deploy`). Deployed endpoints persist after this returns,
so any URLs in the result are live, shareable links.

Args:
    absolute_path_to_app: Absolute path to the app file. Its directory must use `uv`
        and have `modal` installed in its virtualenv.
    env: Modal environment to deploy into.
    name: Deployment name (`--name`).
    tag: Version tag (`--tag`).
    strategy: Rollout strategy — "rolling" or "recreate".
    stream_logs: Stream the app's logs after deploying.

Returns: {message, urls (live endpoints), stdout, stderr}.
run_modal_appA
Run a Modal function or local entrypoint once and collect its output (`modal run`).
Use this to test on Modal compute; use deploy_modal_app to publish.

Args:
    absolute_path_to_app: Absolute path to the app file. Its directory must use `uv`
        and have `modal` installed in its virtualenv.
    function_name: Function/entrypoint name, e.g. "main". Omit if the module has
        exactly one.
    env: Modal environment to target.
    detach: Keep the run alive on Modal past this call (`--detach`) — for long jobs.
    timeout_seconds: Max seconds to collect output. Default 120.

Returns: {output, urls, truncated (still running at the timeout), output_capped}.
get_modal_logsA
Fetch logs for an app or container (`modal app logs` / `modal container logs`).
To find where something went wrong, prefer search_modal_logs — it returns matches
with surrounding context instead of a raw tail.

Covers the stdout/stderr/system streams ONLY. Crash events shown on the Modal
dashboard (e.g. "... exited with ...") are not log lines and never appear here.

Args:
    identifier: App name/ID ("my-app", "ap-...") or container ID ("ta-...").
    target: "auto" (default — "ta-..." is a container), "app", or "container".
    timeout_seconds: Max seconds to collect. Default 30.
    env: Modal environment. Apps only — container logs take no environment.
    since / until: Time range, ISO 8601 or relative ("2h", "30m", "1d"). Max 35 days.
        `since` without `tail` fetches EVERY entry in the range — pass `until` too
        (or a `tail`) to bound the volume on a busy app.
    tail: Only the last N entries (max 20000).
    source: "stdout", "stderr", or "system".
    timestamps: Prefix each line with its wall-clock timestamp.
    follow: Live-stream until the app/container stops or the timeout hits.

Returns: {logs, truncated (still streaming at the timeout), output_capped (text
trimmed to fit context — narrow with tail/since/source)}.
search_modal_logsA
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}.
list_modal_resourcesA
Read-only lookup of everything in the Modal account. Start here to find the app name,
container ID or volume name that the other tools take.

Args:
    resource: One of:
        "apps" — deployed/running/recently-stopped apps.
        "app_history" — one app's deployment versions (`name` = app name/ID); use it
            to pick a version for manage_modal_app(action="rollback").
        "containers" — running containers ("ta-..."); `name` = app ID to filter.
        "volumes" — named volumes.
        "volume_files" — files in a volume (`name` = volume, plus `path`).
        "secrets" — secret names only; values are never returned.
        "environments" — valid values for every `env` argument.
        "profile" — active profile + all profiles (which account am I?).
    name: App name/ID, app ID filter, or volume name — see `resource`.
    path: Path inside the volume for "volume_files". Default "/".
    env: Modal environment. Ignored for "environments"/"profile".

Returns: {<resource key>: [...]} — e.g. "apps", "containers", "contents". Listings
over 200 entries are capped, with `omitted_items` giving the count dropped.
manage_modal_secretA
Create or delete a secret. To list secret names use
list_modal_resources(resource="secrets") — values are never readable.

Values are redacted from every field returned (command, stdout, stderr, error), so
they cannot leak back into the transcript on failure.

Args:
    action: "create" or "delete".
    secret_name: Secret name.
    key_values: For "create": {"API_KEY": "abc", ...}.
    from_dotenv / from_json: For "create": load key/values from a local file instead.
    force: For "create": overwrite an existing secret.
    env: Modal environment to target.

Returns: {message, stdout, stderr} or {error}, with values redacted.
inspect_modal_secretA
List the KEY NAMES inside a Modal secret — never the values.

Modal exposes no API for this: neither the CLI, the SDK, nor the gRPC layer can read
a secret's contents, by design. The only way to see which keys a secret defines is to
mount it in a container and look at the environment variable names. So this tool
starts a short-lived container (`modal shell --secret ...`), prints the variable NAMES
only, and subtracts the ones the image and the Modal runtime would have set anyway.

That means, unlike every other read in this server, a call here **starts remote
compute and costs a few cents** (and takes tens of seconds — longer on the first run
for a given image, which has to be built). It is not a free lookup: use
list_modal_resources(resource="secrets") to see which secrets exist, and reach for
this only when you need to know what is inside one.

Values never leave the container: the probe is `compgen -e`, a bash builtin that
prints exported variable NAMES only, so no value is ever printed or read.

Args:
    secret_name: Name of the secret, from list_modal_resources(resource="secrets").
    env: Modal environment the secret lives in.
    image: Optional container image. Omit it to use Modal's default image, which is
        built to match this server's Python — that is the most reliable choice. Pass one
        (e.g. "python:3.12-slim") if the workspace's image builder rejects that Python.
    timeout_seconds: Max seconds to wait, including image build. Default 300.

Returns: {keys: [...names...], all_env_names: [...], filtered_out: n}. `all_env_names`
    is the unfiltered list, so a key that looks like a runtime variable (e.g. one
    literally named "PATH") is still visible rather than silently dropped.
manage_modal_volumeA
Volume lifecycle. For the files inside a volume use modal_volume_files (writes) or
list_modal_resources(resource="volume_files") (reads).

Args:
    action: "create", "delete" (removes the volume and ALL its data — irreversible),
        or "rename".
    volume_name: Volume name (the current name, for "rename").
    new_name: Required for "rename".
    env: Modal environment. Volumes are environment-scoped, so this must match the
        environment the volume lives in.

Returns: {message, stdout, stderr} or {error}.
modal_volume_filesA
Write operations on a volume's files. To LIST a volume's contents use
list_modal_resources(resource="volume_files").

Args:
    action: "put" (upload local_path → remote_path), "get" (download remote_path →
        local_path; "-" returns the contents instead of writing a file), "cp" (copy
        inside the volume, using `paths`), "rm" (delete remote_path).
    volume_name: Volume name.
    local_path: Local source ("put") or destination ("get", default ".").
    remote_path: In-volume destination ("put", default "/", trailing "/" keeps the
        filename), source ("get"), or target ("rm").
    paths: For "cp": sources followed by the destination, e.g. ["a.txt", "dest/"].
    recursive: Needed to "rm" or "cp" a directory.
    force: Overwrite existing files ("put"/"get").
    env: Modal environment the volume lives in.

Returns: {message, stdout, stderr} or {error}. When MCP_MODAL_ALLOWED_LOCAL_PATHS is
set, "put"/"get" are refused for local paths outside the allowlist.

Prompts

Interactive templates invoked by user choice

NameDescription
debug_modal_appWalk through diagnosing a failing or misbehaving Modal app.
deploy_and_verifyDeploy a Modal app, then confirm it actually came up.
investigate_modal_costsTrace a cost increase back to the app and resource that caused it.
review_modal_accountInventory the Modal account and flag cleanup candidates.

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.4/5.0

Scored across 12 tools

Disambiguation5/5

Every tool targets a distinct resource-action pair: logs are split into raw retrieval and context search with explicit cross-references, app and container management are separated, and secret/volume operations are cleanly divided into listing, inspecting, and mutating. The only close pair (get vs search logs) is clearly disambiguated by pointing out which to prefer.

Naming Consistency4/5

Most tools follow a clear [verb]_modal_[noun] pattern (manage_modal_app, deploy_modal_app, list_modal_resources), with consistent snake_case including the 'modal' brand. The outlier is 'modal_volume_files', which drops the verb prefix and reads as a resource path rather than an action, breaking the otherwise predictable naming convention.

Tool Count5/5

Twelve tools cover the full Modal surface — apps, containers, logs, volumes, secrets, billing, and resource discovery — without redundancy or bloat. Each tool addresses a significant workflow, so the count feels naturally scoped for the domain.

Completeness5/5

The toolset provides full lifecycle coverage: deploy/run apps, manage their state (stop/rollback), execute/stop containers, read and write volume files, create/delete secrets plus read key names, cost analytics, and broad resource discovery. Useful missing operations (like editing a secret) are handled via supported actions such as create-with-force, so there are no obvious dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues