npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@teachinglabstudio/scm-mcp

v0.3.0

Published

MCP server exposing the SCM REST API to Claude Desktop and other MCP clients.

Readme

@teachinglabstudio/scm-mcp

MCP server that exposes the SCM REST API to Claude Desktop (and other MCP clients) as tools. Lives next to the SCM web/api packages so it ships in lockstep with their DTOs and routes.

                Your Mac                                     Cloud
                                                              |
  Claude Desktop ── stdio JSON-RPC ── scm-mcp ── HTTPS ──────▶ SCM API
   (Anthropic app)                    (Node)   Bearer scma_…   (your Railway/wherever)

What you get

70 tools total (v0.3.0). Every call goes through SCM's existing scope + role guards — Claude sees exactly what the human admin sees, nothing more.

Reads (31):

  • me, list_my_capabilities, list_my_integrations, list_oauth_clients
  • list_districts, get_district, list_schools, get_school, list_classrooms, get_classroom
  • list_staff, get_staff, list_students, get_student
  • list_materials, get_material, list_lessons, get_lesson, list_kcs, get_kc
  • list_assignments, get_assignment, list_student_groups, get_student_group, list_goals, get_goal
  • list_lesson_progress, get_lesson_progress, get_lesson_progress_dashboard, list_kc_progress, get_kc_progress

Goal + Group lifecycle (7): create_goal, update_goal, approve_goal, create_student_group, add_group_member, approve_student_group, generate_group_recommendations.

Admin / curriculum / progress writes (19): create+update for districts, schools, classrooms, students, materials, lessons, KCs; update_staff; create_assignment; update_student_group; update_lesson_progress; update_kc_progress. ADMIN-only at SCM (group/progress mutations TEACHER+).

Destructive ops (13): delete_district, delete_school, delete_classroom, delete_student, delete_staff, delete_material, delete_lesson, delete_kc, delete_goal, delete_student_group (all soft — set deletedAt); delete_assignment, remove_group_member (hard — recoverable by re-creating); disconnect_integration (revoke an agent token). Every description starts with DESTRUCTIVE — only call when explicitly told for LLM steering. ADMIN-only (group member removal TEACHER+; integration revoke owner-only). Every call audit-logged with actorKind=agent. See DEC-035.

Deliberately not exposed: create_staff (requires upstream Supabase Auth user) and connect_integration (would let an agent provision its own bearer). The full RFC OAuth flow endpoints (/oauth/authorize, /oauth/token, etc.) aren't tools either — they're for external client wallets, not for an agent acting as a user.

Install

Once published to npm

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "scm": {
      "command": "npx",
      "args": ["-y", "@teachinglabstudio/scm-mcp"],
      "env": {
        "SCM_API_URL": "https://scm.example.com",
        "SCM_TOKEN": "scma_replace-me"
      }
    }
  }
}

Restart Claude Desktop. The scm server should appear in Claude's tool drawer.

Before npm publish (local-only smoke)

git clone [email protected]:TeachingLabHQ/SCM-SCHEMA.git
cd SCM-SCHEMA
pnpm install
pnpm --filter @teachinglabstudio/scm-mcp build

Then point Claude Desktop at the built file:

{
  "mcpServers": {
    "scm": {
      "command": "node",
      "args": ["/absolute/path/to/SCM-SCHEMA/mcp/dist/scm-mcp.mjs"],
      "env": {
        "SCM_API_URL": "http://localhost:3001",
        "SCM_TOKEN": "scma_replace-me"
      }
    }
  }
}

Get a token

  1. Sign in to the SCM web app as yourself.
  2. Go to /integrations.
  3. Click Connect Claude.
  4. Optionally label it (e.g. "MacBook Claude Desktop").
  5. Click Connect — a one-time bearer token (scma_…) appears.
  6. Copy it into the SCM_TOKEN field above. It is shown only once.
  7. Restart Claude Desktop so it picks up the new env var.

Tokens default to a 90-day lifetime. When yours expires you'll see a friendly message in Claude. Mint a new one at /integrations and update your config.

Troubleshooting

"missing required env vars" You forgot SCM_API_URL or SCM_TOKEN in your config. Edit, save, fully quit Claude Desktop (not just close the window), and relaunch.

"SCM_TOKEN must be a SCM agent token (starts with scma_)" You probably pasted a Supabase JWT instead of an integration token. Tokens that work here come from /integrations, not from the browser session.

"Your SCM token is invalid, expired, or has been revoked" Two paths: (a) it's been more than 90 days since you minted, or (b) someone (you?) hit Disconnect on /integrations. Mint a new one and update your config.

"Out of scope for your role" You hit a row outside your district/school scope. SCM enforces scope server-side; this is working as designed. Pivot to a row you have access to.

Nothing shows up in Claude Desktop Three things to check:

  1. Is the process actually running? Tail Claude Desktop's MCP logs (~/Library/Logs/Claude/mcp-server-scm.log or similar).
  2. Did you fully restart Claude Desktop after editing the config? File watchers don't pick up MCP server changes.
  3. Run the binary by hand: SCM_API_URL=http://localhost:3001 SCM_TOKEN=scma_xxx node /path/to/scm-mcp.mjs. If it doesn't print a JSON line on stderr and wait for stdin, the install is broken.

Development

cd mcp
pnpm install
pnpm test            # 46 tests across factory + client + config + tool integration
pnpm typecheck
pnpm build           # esbuild → dist/scm-mcp.mjs (single file, deps inlined)
pnpm dev             # tsx-driven watch mode for hacking on tools

Adding a new tool

src/tools/reads.ts (or writes.ts) — add a ToolSpec:

export const list_widgets: ToolSpec<typeof shape> = {
  name: 'list_widgets',
  description: 'What this does + when to call it.',
  inputSchema: { schoolId: z.string().uuid().optional(), cursor, limit },
  method: 'GET',
  pathTemplate: '/widgets',
  queryArgs: ['schoolId', 'cursor', 'limit'],
};

Then add it to the READ_TOOLS (or WRITE_TOOLS) array. That's it — defineTool handles fetching, error mapping, and result framing.

Architecture in 60 seconds

src/index.ts — boot, env validation, server setup, register every tool spec. src/define-tool.ts — factory that turns a declarative spec into an McpServer.registerTool call. src/scm-client.tsfetch wrapper that attaches the bearer, masks the token in logs, maps HTTP status codes to user-facing messages. src/config.ts — env reader; fails loudly if SCM_API_URL or SCM_TOKEN is missing or malformed. src/logger.ts — structured stderr logger. Stdout is the protocol channel — never write user-facing output there. src/tools/reads.ts — 30 read-only tool specs.