Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
NER_DB_CARNoDefault car name to use when the `car` argument is omitted. If unset, uses LATEST_CAR from config.py.
NER_DB_USERNoDatabase user.readonly
NER_DB_SERVERNoDatabase server host and port.server.finishlinebyner.com:59021
PENELOPE_HOSTNoHost address for the hosted mode server.0.0.0.0
PENELOPE_PORTNoPort for the hosted mode server.8000
NER_DB_PASSWORDNoDatabase password. Defaults to a baked-in read-only password.
PENELOPE_TOKENSYesComma-separated list of name:token pairs, e.g. "chris:token1,jack:token2". Required for hosted mode.
PENELOPE_EXPORT_DIRNoDirectory to store export files. Defaults to a temp directory.
PENELOPE_EXPORT_TTLNoTime-to-live in seconds for export files.3600
PENELOPE_PUBLIC_URLNoPublic base URL clients use to reach the server. If unset, derived per request from the Host header (usually correct).
PENELOPE_SIGNING_KEYNoHMAC signing key for export URLs. If unset, a random key is generated per start, invalidating outstanding export links on restart.
PENELOPE_EXPORT_MAX_ROWSNoMaximum rows allowed in an export; errors rather than truncating.5000000
PENELOPE_EXPORT_MAX_BYTESNoMaximum total bytes for the export directory before sweeping.5000000000
PENELOPE_EXPORT_TIMEOUT_MSNoTimeout for export queries in milliseconds.120000

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
car_infoD

Which car's database these tools read, and its table names.

search_topicsA

Find telemetry topics by name. Start here for any data question.

Substring match, case-insensitive, order-independent: "volt" finds every topic containing "volt", and "pack temp" finds "BMS/Pack Temp". Each hit reports how many samples exist over the topic's whole lifetime (0 means declared but never logged) and its unit when known.

Read three fields before trusting the list:

  • total_matches vs returned -- broad words match hundreds of topics. When truncated is true you are seeing a page, not the answer. Pass offset (or the next_offset from the last response) to page through the rest; ordering is stable, so pages never repeat or skip a topic.

  • namespaces -- where the matches live, e.g. most "volt" hits are per-cell topics under BMS/PerCell. Search a longer prefix to narrow.

  • mode -- all-terms is a real hit. any-term and fuzzy mean nothing matched properly and these are near misses to offer the user.

If more than one hit could plausibly answer the user's question, ask the user to choose rather than picking one yourself.

browse_topicsA

List the immediate children of a topic namespace, like ls.

Use this to explore, and search_topics to find. Topic names are deeply nested -- most are six segments -- so a namespace can hold hundreds of topics while having only a handful of children. BMS/PerCell holds 970 of 25A's 1502 topics but has exactly two children, Alpha and Beta. Searching that prefix returns an unreadable page of leaf names; browsing it returns two lines.

Call with no prefix for the top-level namespaces, then walk down. Each child reports topics (how many exist at or below it), so you can see where the mass is before descending, and is_topic (whether the path is itself a logged topic rather than only a folder).

Once you reach a specific topic, confirm it with describe_topic.

describe_topicA

Profile one topic: sample count, time span, array arity, value range.

Use this to confirm a topic is the right one -- and to learn whether its values array holds more than one element -- before querying it in bulk. Pass the exact name from search_topics.

list_runsA

List recent logging sessions (runs), newest first.

A run is one recording session. Use run.id (the UUID) to filter data via data."runId"; the integer "runId" column is not the join key. Use this to resolve vague time references like "the last test" into a concrete run id, which export_series accepts directly.

describe_tableC

Columns, types, and nullability for one table in public.

export_seriesA

Export one or more topics to a file and return a link plus a profile.

Use this for anything you plan to plot or analyze in code. It returns no rows: read the returned URL (or path) from your code execution environment, e.g. pd.read_csv(URL, parse_dates=["bucket"]). Do not fetch it into context.

Give a time range either as start/end (ISO-8601) or as a run_id from list_runs, which expands to that run's full span.

With a bucket (a Postgres interval like '100 milliseconds' or '1 second') the file is wide: one row per bucket, with <topic>__avg, __min, and __max columns per topic, plus a samples count. Pass bucket=null for long raw output (time, dataTypeName, value) -- raw samples from different topics do not share timestamps, so they cannot be aligned into columns.

index picks the element of the values array (1-based). format is 'csv' or 'parquet'. Report the topic names you exported in your answer.

export_queryA

Run arbitrary read-only SQL straight to a file; return a link, not rows.

The export escape hatch, for shapes export_series does not cover (joins against run, multi-index array columns, custom aggregates). Same contract as export_series: read the returned URL from your code execution environment rather than into context.

Runs in a READ ONLY transaction. Prefer run_query when you only need to look at a handful of rows yourself.

get_seriesA

Downsampled time series returned INLINE: avg, min, max, count per bucket.

Capped at 1000 rows and charged to your context. Use it when you need to read the numbers to answer a question. For plotting or any bulk analysis, use export_series instead.

start and end are ISO-8601; bucket is a Postgres interval such as '100 milliseconds', '1 second', or '5 minutes'. Choose a bucket that keeps the result under a few hundred rows. index picks the element of the values array (1-based).

Report the topic name you passed in your answer to the user.

run_queryA

Run arbitrary read-only SQL and return rows INLINE, capped at 1000.

The escape hatch for questions the other tools do not cover. Runs in a Postgres READ ONLY transaction with a 30 s statement timeout. TimescaleDB functions like time_bucket are available. Remember the camelCase columns need double quotes.

If you are collecting data to plot, use export_query instead -- this tool spends context on every row it returns.

Name any topic you filtered on in your answer to the user.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.5/5.0

Scored across 10 tools

Disambiguation5/5

Each tool targets a distinct operation: search, browse, and describe cover topic discovery at different levels; run_query/export_query and get_series/export_series are clearly separated by inline-vs-file delivery. The descriptions explicitly reinforce these boundaries, so an agent should rarely confuse one tool for another.

Naming Consistency4/5

Nine of ten tools follow a consistent verb_noun pattern like export_query, browse_topics, describe_topic, and list_runs. The noun-only 'car_info' is a minor outlier, preventing a perfect score, but the overall convention is predictable.

Tool Count5/5

Ten tools is well-scoped for a telemetry exploration server: discovery, profiling, inline querying, bulk export, and schema/run metadata each have a dedicated tool. There are no redundant or filler tools.

Completeness5/5

The surface covers the full read-only workflow: find topics, confirm them, query small results inline, export bulk data, and resolve runs or table schemas. The arbitrary read-only SQL escape hatches cover any remaining analytical shapes, leaving no dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues