MCP Hub
Back to servers

Crescender MCP Server

Read-only MCP server that connects AI clients to Crescender's school asset, loan, member, and asset-comms API.

glama
Updated
May 8, 2026

Crescender MCP Server

Model Context Protocol server for Crescender's public read API. Connects AI clients (Claude Desktop, Cursor, custom agents) to a school's assets, loans, members, and asset-comms threads — all read-only, scope-token-authenticated, and bound to a single school per token.

Status: 0.0.x — pre-publish. This package has not yet been published to npm or pushed to GHCR. The publish pipelines exist but are gated to manual triggers; the first release ships when the source has been pressure-tested locally. For now, run from a clone or a pnpm link (see Local development below).

What it gives an AI

Six read-only tools, each backed by an /api/v1/* endpoint:

MCP toolReturns
list_schoolsThe single school the token is bound to (single-item array)
get_assetFull asset detail by id — model, serial, location, role, current loan
search_assetsUp to 50 assets matching q / item_class / category / status
get_loans_for_assetLoan history for one asset (current + past)
list_membersMember directory — id, role, status, external_id (no PII)
list_asset_threadsAsset-comms threads with status filter (read-only — vendor-token issuance is NOT exposed via MCP)

Reads only. No update_* / create_* tools in v1.

Configuration

Two environment variables, one of them required:

VarDefaultNotes
CRESCENDER_API_TOKENRequired. Issue from https://app.crescender.com.au/school/<id>/settings/integrations (the "Integrations" tile under your school's Settings). Format crsc_<random>.
CRESCENDER_API_URLhttps://app.crescender.com.auOverride only if you're pointing at a non-production deployment.
CRESCENDER_MCP_LOG_LEVELinfoOne of debug / info / warn / error. Logs go to stderr (stdout is reserved for the MCP protocol).
CRESCENDER_MCP_HEALTH0Set to 1 in container deployments to enable the GET /health HTTP endpoint on PORT (default 3030).
CRESCENDER_API_TIMEOUT_MS15000Per-request upstream timeout.

Connecting Claude Desktop (once published)

Once the first version is on npm:

// ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
// %APPDATA%\Claude\claude_desktop_config.json (Windows)
{
  "mcpServers": {
    "crescender": {
      "command": "npx",
      "args": ["-y", "@crescender/mcp-server"],
      "env": {
        "CRESCENDER_API_TOKEN": "crsc_..."
      }
    }
  }
}

Then restart Claude Desktop. The six tools should appear in the MCP picker.

Connecting Cursor (once published)

Cursor reads MCP config from .cursor/mcp.json in your workspace, or globally from settings. The shape is the same as Claude Desktop's mcpServers block.

Local development

# Install
git clone https://github.com/lincalinca/crescender-mcp-server.git
cd crescender-mcp-server
pnpm install

# Build
pnpm build

# Smoke test (talks to stdin/stdout — Claude Desktop / Cursor will spawn it
# the same way)
CRESCENDER_API_TOKEN=crsc_... node dist/index.js

To wire your local clone into Claude Desktop without publishing:

{
  "mcpServers": {
    "crescender-local": {
      "command": "node",
      "args": ["/absolute/path/to/crescender-mcp-server/dist/index.js"],
      "env": {
        "CRESCENDER_API_TOKEN": "crsc_..."
      }
    }
  }
}

Container

# Build (the published image is built by .github/workflows/publish-image.yml)
docker build -t crescender-mcp-server:dev .

# Run with the in-container /health endpoint enabled
docker run --rm -i \
  -e CRESCENDER_API_TOKEN=crsc_... \
  -e CRESCENDER_MCP_HEALTH=1 \
  -p 3030:3030 \
  crescender-mcp-server:dev

Once published, the image will be available at ghcr.io/lincalinca/crescender-mcp-server.

Statelessness contract

  • No in-memory token cache: validation hits the upstream API on every call (revocation is immediate).
  • No filesystem state: stdout/stderr only.
  • Config is env-driven, parsed once at boot, frozen.
  • /health (when enabled) returns { ok, api_reachable, version } and probes the upstream /api/v1/health to verify reachability — not just "this process is alive."
  • Graceful shutdown: SIGTERM / SIGINT trigger a 30-second drain, then force-exit.

This is what makes the container k8s-ready without any k8s-specific code. When the orchestration decision is eventually made (ASK / AKS / GKE / Fly / Railway / etc.), nothing changes here.

License

MIT — see LICENSE.

Related

  • @crescender/crescender-core — the platform itself, which serves the /api/v1 endpoints this MCP wraps.
  • OpenAPI spec: https://app.crescender.com.au/api/v1/openapi.json

Reviews

No reviews yet

Sign in to write a review