Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
PERF_ENVNo`NAME=VALUE` pairs, separated by spaces, set for the recorded program.
KEEP_RUNSNoKeeps only the newest N recordings.
KEEP_TRACENo`1` keeps each recording's `.trace`, for `trace_tables`, `trace_query` or Instruments.
WINEPREFIXNoThe Wine prefix used when the call names none; `~/.wine` otherwise.
METAL_TRACE_LOGNo`off` silences the one-line stderr log per call.
METAL_TRACE_OUTNoWhere recordings go. Give an absolute path: the default, `./perf-runs`, depends on the client's working directory.
METAL_TRACE_READNoMore directories the tools may read, separated by `:`.
METAL_TRACE_WINENoThe Wine directory (holding `bin/wine`) that `perf_record` uses when the call names none.

Instructions

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

Records GPU use on Apple silicon with Metal System Trace. One recording runs at a time; keep other GPU work off the Mac while it records. Under Wine record 30 s or more: Wine's start-up takes part of the recording. A recording needs about 0.8 GB of free disk per second for Instruments' temporary files (26 GB for 30 s, 50 GB for 60 s); perf_record refuses to start without it. Reading a recording back takes 1 to 14 s per recorded second. Compare only recordings with 100 frames or more, and repeat a run before calling a change real. perf_baseline (or perf_baseline_record, which records them) saves several equal runs as a named reference and perf_check says whether a new run regressed against their range. perf_diagnose says whether a run splits its GPU work into too many short encoders, as translation layers do; perf_compare says how much two runs differ; skip_s on perf_compare, perf_gate and perf_panel leaves out the first seconds (start-up) of each run; perf_history follows FPS, hitches and memory across runs with one name prefix, oldest first; perf_gate says whether a run meets budgets you set (FPS floor, hitch or memory ceiling); perf_panel writes an HTML page to look at one or two runs in a browser.trace_tables and trace_query need the .trace, kept only with KEEP_TRACE=1. When perf_record ends it stops every program of its Wine prefix, or every process named like a native program. To compare native Metal with a translation layer without a game of one's own: workload_list, workload_fetch, then perf_record with workload and api (and example, for a workload that lists examples), or the compare-layer prompt. perf_sweep records one run per value of dim, example, api or an environment variable and fits GPU ms per frame on the value. memory_free_pct holds the whole Mac short of memory while recording (keep other work off it) and background throttles the program: repeat a run that uses either.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{}
prompts
{}
resources
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
perf_recordA

Records program (an .exe under Wine, or a macOS binary with wine="native"), or a test program fetched with workload_fetch (workload, api, dim), for seconds with Metal System Trace and returns its summary: GPU ms per frame, frame intervals, FPS, Metal and resident memory (memory=false skips the Metal memory table, the slowest to read). When it ends it stops every program of that Wine prefix (wineserver -k), or every process named like the program with native. counters=true also records Metal GPU Counters (gpu_counters in the summary: the units the GPU waited on, its utilization, occupancy and memory bandwidth); it adds about 40 s of read-back per recorded second.

perf_baseline_recordA

Records the same program count times in a row with perf_record's arguments and saves the runs as the reference name for perf_check, returning the range each number spans across them. Runs are named name-1, name-2, ... Each recording takes its seconds plus about a minute to read back. skip_s as in perf_baseline: the reference leaves out each run's start-up.

perf_sweepA

Records the same program once per value of one variable (dim, example, api, size, or env:NAME for an environment variable) and returns, per value, the median of FPS, 1 % low, GPU ms per frame and stutter, and with 3 or more numeric values the straight line GPU ms per frame follows (fixed ms plus ms per draw for dim, per unit otherwise) with its r2. With rounds above 1 the values run in opposite order every other round, so drift hits all alike. Runs are named name--r; each takes its seconds plus about a minute to read back.

perf_abA

Records the same program with two environments in the order A B B A (repeated rounds times, so drift hits both sides equally) and says per metric whether B is better, worse or the same as A, with every value behind it. env_a and env_b are NAME=VALUE pairs separated by spaces; empty means none. Runs are named name-a1, name-b1, ... Each recording takes its seconds plus about a minute to read back. skip_s leaves out the first seconds of every recording (the start-up) when the verdicts are drawn, as perf_compare does; the recordings are whole.

perf_attachA

Records a program that is already running, by pid or by a name in its command line (Game.exe under Wine), for seconds and returns the same summary as perf_record; the program keeps running. For games started by Steam, CrossOver, NotProton or any launcher: start the game or its benchmark there first.

perf_runsA

Lists the saved recordings, newest first, with frames, FPS, GPU ms per frame, memory peaks and the translation layer each ran on (fingerprint and Wine, or native).

perf_compareA

Compares two saved recordings (names from perf_runs), a the reference and b the run after a change: the headline numbers (FPS, GPU ms, frame pacing, memory), then what changed in the GPU work and where: encoders and command buffers per frame, the share of encoders under short_us, the GPU's idle time, and each encoder label's count and GPU ms per frame, largest change first. layer says whether both ran on the same translation layer: with different layers it compares layers, not one change. A Windows run against a Metal run has measure: the GPU ms and Metal memory differ in kind and the encoders exist only in Metal, so use FPS, its lows, stutter and jitter. Recordings with under 100 frames are flagged: too short to compare. With markdown true the result also has markdown: the same numbers as tables for a PR comment. skip_s leaves out the first seconds of each recording, where shaders compile and resources load: the GPU numbers, hitches and Metal memory are recomputed from the per-frame files without them, and skipped_s says it; thermal state, process memory and encoders stay whole-run. screen appears when one run was recorded with the screen locked and the other not: FPS is then not comparable.

perf_baselineA

Names a reference for perf_check, or lists them. With name and runs (names from perf_runs, several runs of the same program recorded with no change between them), it saves copies of their summaries as the reference name, replacing a previous one, and returns the range each number spans across them: that range, not one run, is what perf_check judges against, since repeated runs differ by a few percent, and spread_pct, each range's width in % of its midpoint: the noise of this program on this machine, which a change must exceed. With name alone it shows that reference; with nothing it lists them. With skip_s the reference keeps each run without its first skip_s seconds (the start-up, as perf_compare's skip_s) and perf_check applies the same cut to the run it judges, so both are steady-state; the runs need their per-frame files for that.

perf_checkA

Judges a recording against a reference saved with perf_baseline: regressed when FPS falls under the reference's lowest FPS by more than margin_pct, GPU ms per frame rises over its highest by more than margin_pct, or encoders or command buffers per frame exceed its highest; improved when a number leaves the range the other way and none regressed; same otherwise. Frame pacing, short encoders and GPU idle time are reported by the comparison but do not decide: they vary too much between equal runs. A run from Windows against a Metal reference (or the reverse) is judged on FPS alone. A reference saved with skip_s judges the run without its first skip_s seconds too (skipped_s says so). Returns the reasons and perf_compare's full comparison against the reference's first run.

perf_export_traceA

Writes a recording's GPU frames as a Chrome trace file, <run>.chrome-trace in the runs directory, that ui.perfetto.dev and chrome://tracing open: one slice per GPU frame, from its start for its GPU time (the sum of its encoders' time, so a frame with parallel encoders can show shorter than it took), with the compute, fragment and vertex split as arguments. Returns the file name and the number of frames.

perf_gateA

Checks a recording against budgets and says pass or fail: a floor for FPS and the 1% low, a ceiling for the stutter rate, the p95 GPU ms per frame, the hitch count and the peak Metal MiB. Give at least one. A number the recording lacks fails its budget (value null): a gate must not pass on missing data. Returns each budget with its limit, the value and whether it held. Use it as a bar a change must clear, where perf_check judges against equal runs. skip_s leaves out the first seconds of the recording (the start-up), as perf_compare does.

perf_historyA

Lists the recordings whose name starts with prefix, oldest first, with their FPS, 1% low, GPU ms, stutter, hitches and peak Metal MiB, and the change from the first to the last: how a number moved over a series of runs, such as one recording per version of a translation layer. Read a trend as real only when it exceeds the spread_pct that perf_baseline reports for equal runs. Runs from Windows and Metal in one series are flagged: their GPU ms and memory do not compare. skip_s leaves out the first seconds of each recording (the start-up), as perf_compare does.

perf_panelA

Writes one HTML file, <name>.panel.html in the runs directory, that shows one or two recordings in a browser without a server: GPU time per frame with the hitches marked, the numbers (FPS and its lows, frame time, jitter, stutter, memory, thermal state), Metal memory over time and, for two runs, A against B. The file holds the data itself, no path, and loads nothing from the network; the viewer can hide and reorder the widgets and export the layout as JSON. preset fps is the timeline, numbers and memory; compare (two runs) puts A against B first. skip_s leaves out the first seconds of each recording (the start-up), as perf_compare does. layout (tab ids in the order to show) is saved as panel.json in the runs directory and becomes the default tab order of every panel, the live one too, until the viewer changes it in the browser; ids left out are hidden but can be switched back on; tabs are summary, ab, frames, encoders, counters, memory and data, and a panel.json you wrote yourself, or copied from the panel's Layout JSON, works the same. Returns the file name, the runs, the frames shown and the file's bytes.

perf_diagnoseA

Says whether a saved recording splits its GPU work into too many short encoders, the pattern of translation layers such as DXMT, Mullion or MoltenVK, with the numbers behind it: encoders and command buffers per frame, the share of short encoders, the labels with the most GPU time and the GPU's idle time. Read the idle time together with the FPS: a program waiting for vsync idles too. Defaults come from bgfx 17-drawstress on an M1 Pro: 7 encoders per frame and 50% under 25 us under Mullion, 2 and 2% in native Metal.

trace_tablesA

Lists the data tables (schemas) a .trace recording holds; recordings keep their .trace only with KEEP_TRACE=1.

trace_countA

Counts the rows of several tables of a kept .trace, in all and per process, so a recording's useful tables show before reading them: a table with 0 rows needs another instrument or Xcode, not a bigger page.

trace_queryA

Returns one page of rows of one table of a .trace as {column: value}, optionally only one process's rows.

capture_summaryB

Reads a Metal .gputrace capture without Xcode: command buffers, encoders, draws, debug groups, and the 100 most frequent call ids out of calls_total.

capture_recordsA

Returns one page of the records of a .gputrace command stream, with their Metal call names when known.

gpu_familyA

Apple's published facts for one GPU family, by family ("Apple7") or chip ("M1 Pro"): its chips, what it adds, its limits, plus the limits shared by all families and the footnotes. Source URLs are in the result.

workload_listA

Lists the test programs workload_fetch can download, such as bgfx's drawstress: what each measures, its size, license and APIs, and whether it is already downloaded.

workload_fetchA

Downloads a test program from this project's GitHub releases once, checks its SHA-256 against the one this package pins, and keeps it in ~/Library/Caches/metal-gpu-trace; later calls reuse it. The programs are built from source by the project's workloads workflow.

presentmon_installA

Windows only: downloads Intel's PresentMon console application (MIT) from its GitHub release, checks its SHA-256 against the one this package pins, and keeps it in %LOCALAPPDATA%\metal-gpu-trace, where perf_record and perf_attach find it; later calls reuse it. It needs administrator rights or the Performance Log Users group to run.

Prompts

Interactive templates invoked by user choice

NameDescription
compare-layerRecords a test program in native Metal and under a translation layer, then diagnoses and compares both runs

Resources

Contextual data attached and managed by the client

NameDescription
Apple GPU familiesApple silicon GPU families Apple7 to Apple10: chips, first family with each feature, and limits that differ. Facts restated from Apple's public documents, not Apple's text. Check a device with MTLDevice.supportsFamily; families nest, so an Apple9 GPU also supports Apple7 and Apple8.
Apple7 GPU familyApple's published facts for Apple7
Apple8 GPU familyApple's published facts for Apple8
Apple9 GPU familyApple's published facts for Apple9
Apple10 GPU familyApple's published facts for Apple10

TDQS

A3.9/5.0

Scored across 23 tools

Disambiguation5/5

Despite many perf_* tools, each has a clearly distinct role: record, attach, sweep, A/B compare, baseline, check, gate, history, diagnose, panel, export, and run listing. Similar-sounding pairs like perf_baseline versus perf_baseline_record are differentiated by whether they consume existing runs or record new ones. The trace and capture tools are also cleanly separated by operation and artifact type.

Naming Consistency4/5

The set follows a consistent snake_case convention with useful domain prefixes such as perf_, trace_, capture_, workload_, and gpu_. Names are not strictly verb_noun throughout—there are noun-style names like perf_runs, perf_history, and perf_panel—but the grouping is readable and predictable. Minor deviations do not impede tool selection.

Tool Count4/5

At 23 tools the surface is large, but this is a broad GPU profiling suite covering recording, comparison, baselines, gates, traces, captures, workload setup, and environment inspection. Each tool appears to earn its place, though the count is slightly heavy and could be streamlined. It is not an extreme mismatch for the stated scope.

Completeness4/5

The tool set covers the main lifecycle: fetching workloads, recording or attaching, saving baselines, comparing, checking, gating, diagnosing, visualizing, exporting traces, and inspecting raw trace/capture data. The main noticeable gap is management of saved artifacts, such as deleting or renaming recordings and baselines. That is a minor omission rather than a blocker for core profiling workflows.

Maintenance

ActivityMaintained
ResponsivenessSyncing