Skip to main content
Glama
README.md
# aimm-mcp

Local **Model Context Protocol** server for the AI Model Manager.
Captures SQL data-model metadata as **one JSON file per project**
(`<slug>.aimm.json`) and exposes it to Claude Code (or any MCP
client) over stdio.

Fork of the [AIMM VS Code extension](https://github.com/DylanCodyBrown/ODBC_AI_Workbench),
rebuilt in Python with no UI: just tools the agent calls. Both the
VS Code extension and this server read/write the same project-file
format — share a project by committing one `.aimm.json` to your
repo.

## Why this exists

The VS Code extension lives inside an editor. This fork lets you
skip the editor entirely — install once with `claude mcp add`, and
any Claude session on the machine sees the same models.

## Install

One line. Claude Code spawns the server via `uvx` (uv's npx) — no
prior install, no setup.

```bash
claude mcp add aimm --scope user -- uvx aimm-mcp
```

First connection downloads the package (a few seconds). Subsequent
connections are cache-served.

For testing from a local checkout before PyPI, see
[`LOCAL_INSTALL.md`](LOCAL_INSTALL.md).

## Where state lives

Two concepts: **machine-local sidecars** (always at `~/Documents/AIMM/`)
and **project files** (anywhere you point them, default the same folder).

```
~/Documents/AIMM/                    machine-local, never moves
├── state.json                       which folder + which active project
├── discovered_joins.json            scan output (not project state)
└── diagnostics.log                  ODBC query append-log

<projects_folder>/                   defaults to ~/Documents/AIMM/
├── customer_warehouse.aimm.json     one project
├── reporting_model.aimm.json        another project
└── …
```

A team checks `<projects_folder>` into a git repo. The agent runs
`aimm_set_projects_folder` to point at the local clone, then
`aimm_list_projects` + `aimm_set_active_project` to pick one. The
"active project" pointer survives across Claude Code sessions.

No derived snapshots on disk. Renderings (XML / markdown / raw JSON)
happen in-memory when `aimm_read_project_context` is called.

## Engines

Three engines via ODBC: `trino`, `sql_server`, `databricks`.
Connection descriptors carry a DSN name (system DSN registered at
the OS level) plus the catalog / database qualifier.

## Tools

### Session / context

The agent must select an active project before any project-touching
tool runs — these tools handle that bootstrap.

- **`aimm_set_projects_folder`** — point the server at a folder of
  `.aimm.json` files (defaults to `~/Documents/AIMM/`). Use to
  switch to a team repo of shared projects. Clears the active
  pointer.
- **`aimm_list_projects`** — enumerate `.aimm.json` files in the
  current folder with their internal project name + `updated_at`.
- **`aimm_set_active_project`** — pick one as active. Subsequent
  tool calls read and write that file.
- **`aimm_show_active_project`** — report the current pointer state
  (folder + active file + on-disk status).

### Project + context

- **`aimm_init_project`** — create a new `<slug>.aimm.json` (slug
  derived from `name`) in the current folder, set it as active.
- **`aimm_read_project_context`** — return the entire active
  project. Formats: `xml` (default), `markdown`, `json` (raw bytes
  of the active file).

### Connections + live catalog

- **`aimm_upsert_connection`** — create / update a connection
  descriptor. Validates Trino catalog requirement.
- **`aimm_list_system_dsns`** — pyodbc.dataSources() wrapper for
  discovery before upsert.
- **`aimm_browse_connection`** — drill into schemas / tables /
  columns on a live connection. Optional case-insensitive search
  filter.
- **`aimm_refresh_columns`** — re-fetch column shapes from
  information_schema and merge back into the active project
  (preserves user-edited PK / FK / description flags).

### Table mutations

- **`aimm_update_table`** — patch any non-identity field on a
  tracked table. Creates on first patch.
- **`aimm_set_primary_key`** — atomically set primary_keys + flip
  is_primary_key on matching columns.
- **`aimm_add_relationship`** — append an FK edge (idempotent on
  duplicates, composite keys supported).
- **`aimm_add_upstream`** — append a lineage edge.

### Semantic context (the "what it means" layer)

The structural fields above tell the agent what's *there*. These
tell it what those things *mean* — captured once, surfaced on
every subsequent `aimm_read_project_context` call.

- **`aimm_set_table_grain`** — one-line "what is a row?" per table.
- **`aimm_add_pitfall`** — append-with-dedupe to a table's "don't do
  this" list.
- **`aimm_set_column_classification`** — flag a column as
  pii / phi / restricted / internal / public.
- **`aimm_add_glossary_term`** — upsert a domain-vocabulary entry.
- **`aimm_add_measure`** — upsert a KPI / metric with definition +
  formula.
- **`aimm_update_project_config`** — patch the project header
  (description, conventions, dialect, default_connection,
  modeling_paradigm, tags).

### Folder scan for joins

- **`aimm_scan_folder_for_joins`** — walk a local folder of `.sql`
  files, extract JOIN clauses via sqlglot (multi-dialect fallback:
  tsql → spark → none), persist canonical edges to
  `~/Documents/AIMM/discovered_joins.json`. Works without an active
  project.

### Diagnostics

- **`aimm_show_diagnostics_log`** — tail of `diagnostics.log` where
  every ODBC query is recorded.

### Pending changes

- **`aimm_get_pending_changes`** — per-tracked-table diff between
  authored columns and the live `information_schema` shape.

## Why ODBC?

Every warehouse this targets exposes an ODBC driver. We never run
user SQL — only `information_schema` reads for column / table /
schema metadata. Drivers stay read-only at the credential level.

## Development

```bash
uv sync --dev
uv run python -m aimm_mcp        # starts the MCP stdio server
uv run pytest -q                 # tests
```

## License

MIT.

TDQS

A4.2/5.0

Scored across 2 tools

Disambiguation5/5

Each tool has a completely distinct purpose: one initializes the project, the other reads its context. There is no overlap or ambiguity.

Naming Consistency5/5

Both tools follow a consistent 'aimm_verb_noun' pattern (init_project, read_project_context), making naming predictable and clear.

Tool Count2/5

With only 2 tools, the server feels undersized for managing a data model. A more complete set (e.g., adding tables, connections) would be expected.

Completeness2/5

The server provides initialization and read capabilities only, lacking essential mutation tools like adding tables or connections, making it incomplete for full project management.

Maintenance

ActivityInactive
ResponsivenessNo issues