Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
SELVEDGE_DBNoPath to the SQLite database file. Overrides project and global defaults.
SELVEDGE_QUIETNoSet to '1' to suppress warnings about using global database fallback.
SELVEDGE_LOG_LEVELNoLogging level for the Selvedge server. One of DEBUG, INFO, WARNING, ERROR.WARNING

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
log_changeA

Record a change to a codebase entity.

Call this immediately after making any meaningful change. The event is written to the local SQLite store and returned with its assigned id and timestamp. If the reasoning fails the quality validator (empty, too short, or a generic placeholder), or the entity_path doesn't match the usual shape for its entity_type, the result includes a warnings array — the event is still stored.

Renames: pass the new path in entity_path, set change_type="rename", and pass the old path in rename_from. Selvedge then writes two events — a rename on the old path and a create on the new path with metadata.renamed_from set — so the entity's history follows it. Example:

log_change(
    entity_path="src/auth/session.py::login",   # new path
    change_type="rename",
    rename_from="src/auth.py::login",            # old path
    entity_type="function",
    reasoning="Split auth.py into an auth/ package; login moved.",
)

Rejections: when you consider an approach and decide against it WITHOUT writing the change, record the verdict with change_type="reject" — the abandoned path is a first-class event, and the next agent's prior_attempts query finds it as a high-confidence ("exact") row instead of re-deriving the dead end. Name what was rejected AND what was chosen instead, and record the condition that would invalidate the verdict. Example:

log_change(
    entity_path="users.card_pan",
    change_type="reject",
    entity_type="column",
    reasoning="Rejected storing raw card PANs on the user row — "
              "went with provider tokens instead; PANs in our own "
              "DB put us in PCI scope.",
    stale_when="payment provider changed",
    expires_when="entity:deps/stripe:changes",
)

Use change_type="revert" for the sibling case — the change WAS written and then rolled back (clearer than a plain remove).

Superseding a reverted decision: when a reverted change becomes correct again (the constraint that killed it no longer holds), do NOT delete or edit history — log with change_type="supersede" and the reason. The new event links the prior revert (auto-resolved when supersedes is empty) and every read surface then reports the trail tried → reverted → re-opened. Never re-apply a reverted change without superseding it first.

On validation failure (invalid change_type, missing entity_path, rename_from set without change_type='rename', supersedes set without change_type='supersede', a supersede with nothing to re-open, or an expires_when outside the closed grammar) the result is {"status": "error", "error": "..."} with no event written.

diffA

Get change history for a codebase entity, newest first.

Supports prefix matching — e.g. 'users' returns all events for the users table and any users.* column. Each event carries a derived superseded_by id ("" when nothing overrode it), so the tried → reverted → re-opened trail reads straight off the history.

blameA

Most recent change to an entity — what changed, when, who, why.

Like git blame but for semantic entities (DB columns, functions, env vars, dependencies) and AI agents. Also carries the derived decision state: status (active / reverted / reopened) and superseded_by (id of a later supersede overriding this change, or ""). If no history exists for the entity, returns {"error": "..."} with protocol-level isError: false.

historyA

Filtered change history across all entities, newest first.

Combine since, entity_path, project, and changeset_id to scope the result. On unparseable since input the response is [{"error": "..."}] so the caller sees the problem.

changesetA

All events that share a changeset_id, oldest first.

Use to reconstruct the full scope of a feature or task across multiple entities. If the changeset has no events, returns [{"error": "..."}] so the caller can distinguish "unknown changeset" from "empty history."

searchA

Full-text search across entity paths, diffs, reasoning, and agents.

Useful for questions like 'what changes were made for the billing feature?', 'which columns were added by cursor?', or 'show everything related to authentication'.

prior_attemptsA

Prior change attempts on an entity, each with an inferred outcome.

Call this BEFORE editing an entity. If the same change was tried before and reverted, you get the prior reasoning and change_type plus an inferred outcome — so you can change your plan instead of repeating a rejected approach.

Each result is a change event plus the trail fields: outcome ("reverted" — a later removal on the path; "reopened" — closed but a later supersede re-opened it; "rejected" — a standalone reject event that closed no earlier attempt, surfaced as its own row whose reasoning IS the record; "active"), confidence ("exact" — the attempt was closed by an explicit revert/reject, or the row is a standalone rejection; "proximity_high" / "proximity_low" — the add->remove window heuristic for implicit removals), outcome_reasoning (WHY it was rejected), superseded_by + supersede_reasoning (the re-open, when present), and current_status — the entity's standing now. Treat "reverted" and "rejected" as "don't repeat this without a supersede"; "reopened" means the old verdict no longer stands. Together they read: tried → reverted → re-opened. Templated and deterministic — no LLM call; pull-only.

Conservative by design — min_confidence defaults to "proximity_high", so an empty list (nothing clearly tried-and-rejected) is the normal, preferred answer over a speculative false positive; "exact" rows always clear that default floor. Pass min_confidence="proximity_low" to widen recall. Rows carry match_type ("exact" / "substring" / "fuzzy") and similarity.

stale_decisionsA

Decisions due for a revisit — expired, past their date, or with a triggered stale condition.

Three deterministic rules. Expiry-based (flag="expired"): events whose expires_when condition fired, evaluated from local state only — date: against now, entity:PATH:changes against the event log, library:NAME>=VERSION against installed dist metadata; the pattern kind that fired is in expired_pattern. A library: condition whose dependency isn't locally observable surfaces as flag="manual_review" instead of a guess; manual:LABEL never auto-fires. Date-based (flag="revisit_due"): events whose revisit_after has passed AND the entity is still live (queried via blame/diff/prior_attempts after the decision, or its changeset saw later activity) — pure age alone never surfaces. Condition-based (flag="review_suggested"): events whose stale_when text shares keywords with a LATER change event — the named invalidation evidence may have happened. Surfacing only: nothing is un-retired automatically; follow up with a supersede if the condition really was triggered.

Each result is the change event plus flag, revisit_due, days_overdue, active_use_signals, matched_terms, matched_event_id, expires_status, expired_pattern, expires_detail, and a one-line stale_reason. Date-due rows first, most-overdue leading; filter by entity_path, project, or agent. Templated and deterministic; no LLM call, no network.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.2/5.0

Scored across 8 tools

Disambiguation4/5

Most tools have clear, distinct purposes: logging changes, querying history, searching, and finding stale decisions. However, `diff` (entity history) and `history` (filtered history across entities) overlap somewhat—both return change history, differing mainly in scope and filtering. `blame` is distinct (latest change per entity) and `prior_attempts` is distinct (outcome-focused), but the overlap between diff/history could cause occasional misselection.

Naming Consistency3/5

Tool names are mostly two-word lowercase verbs or nouns (log_change, prior_attempts, stale_decisions), but the pattern is inconsistent: some are verb_noun (log_change, stale_decisions), others are single nouns (diff, blame, history, changeset, search). This mix of action-oriented and entity-oriented names breaks a strict pattern, though each name is still readable and intuitive.

Tool Count5/5

With 8 tools, the server is well-scoped for its domain (change logging and history management). Each tool serves a distinct purpose—recording events, querying history at different granularities, searching, proactive checks, and maintenance. No tool feels redundant, and the count is within the ideal range, making the surface manageable without overwhelming an agent.

Completeness5/5

The tool set covers the full lifecycle: logging changes (log_change), retrieving history (diff, history, blame), reconstructing changesets, searching, checking prior attempts before editing, and flagging stale decisions for revisit. It even supports renames, rejects, reverts, and supersedes, showing thorough coverage of decision evolution. No obvious missing operations like deleting events (likely intentionally immutable), and the stale_decisions tool closes the loop on maintenance, so the surface feels complete.

Maintenance

ActivityActive
ResponsivenessResponsive