Skip to main content
Glama
d-bui

users-demo

by d-bui

User Management API + MCP Layered Demo

A small demo built with Node.js (JS only). This is a presentation sample for showing, layer by layer, a setup that "provides the same API to both human users and AI agents with separate authentication and separate exposure scopes, and layers an MCP server (API description layer) on the AI side."

The design is based on the production MCP of spx-learning-square (spx-learning-square/mcp/, 65 tools, distributed as .mcpb). This demo distills that approach into a minimal setup.

Overview

 人間ユーザー ──ログイン──▶ セッショントークン ─┐
                                                  │ Authorization: Bearer
 AI (Claude) ──▶ MCP サーバー ──PAT──────────────┤
              (mcp/index.mjs                     ▼
                = API 説明層)          ┌─────────────────────────┐
                                        │ API サーバー (Express)  │
                                        │  認証層(2 系統)       │
                                        │  エージェント公開       │
                                        │  レジストリ             │
                                        │  controller             │
                                        │  service                │
                                        │  repository(メモリ)   │
                                        └─────────────────────────┘

Related MCP server: MCP CRUD Tools

Layer Structure

Layer

File

Role

Auth layer (human)

api/auth/userAuth.mjs

Login → issues session token. userOnly guard

Auth layer (AI)

api/auth/agentAuth.mjs

Validates PAT (pre-issued key). No login required

Public registry

api/agentRegistry.mjs

Registration list of APIs exposed to AI. Unregistered APIs return 403 even with valid auth

Controller layer

api/usersController.mjs

HTTP ⇄ service conversion + guard declaration per route

Service layer

api/usersService.mjs

Business rules (validation, duplicate checks). Knows nothing about HTTP

Repository layer

api/usersRepository.mjs

Data persistence (in-memory in the demo; swap for MySQL etc. in production)

MCP layer (API description layer)

mcp/index.mjs

Explains API usage to AI in Japanese while mediating. Holds no permissions

Permission Matrix (the core of the demo)

API

Human user

AI agent

GET /api/users (list)

✅ registered

GET /api/users/:id (get)

✅ registered

POST /api/users (create)

✅ registered

PUT /api/users/:id (update)

user_only

DELETE /api/users/:id (delete)

user_only

GET /api/agent/apis (public list)

✅ registered

Destructive operations (update/delete) are made human-only by not registering them in the registry. The key point is that "what is allowed for AI" can be seen at a glance in a single file, agentRegistry.mjs.

How to Run

1. API Server

npm install
npm run api          # http://localhost:3000

To run with Docker (only the API is containerized):

npm run docker       # = docker compose up --build → http://localhost:3000

The MCP layer (mcp/index.mjs) is not put in a container. Since Claude Desktop / Claude Code launch it as a stdio process on the user's machine, distribution is done via .mcpb, not Docker. This is also a presentation point: the API is server-side (Docker/ECS), while the MCP is client-side (.mcpb) — the deployment units are separate.

Human user flow (login → CRUD):

# ログイン(デモ: alice / demo)
TOKEN=$(curl -s -X POST localhost:3000/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"login_id":"alice","password":"demo"}' | node -p 'JSON.parse(require("fs").readFileSync(0)).data.token')

curl -s localhost:3000/api/users -H "Authorization: Bearer $TOKEN"          # 一覧
curl -s -X DELETE localhost:3000/api/users/3 -H "Authorization: Bearer $TOKEN"  # 削除も OK

AI agent flow (PAT, default key agent-demo-key):

curl -s localhost:3000/api/users -H "Authorization: Bearer agent-demo-key"       # ✅ 200
curl -s localhost:3000/api/agent/apis -H "Authorization: Bearer agent-demo-key"  # ✅ 公開一覧
curl -s -X DELETE localhost:3000/api/users/2 \
  -H "Authorization: Bearer agent-demo-key"                                       # ❌ 403 user_only

There are two kinds of error codes: user_only = an API with a human-only guard (update/delete), agent_not_allowed = an API whose guard is forAgent but is not registered in the registry.

2. MCP Server (API Description Layer)

Debug UI (MCP Inspector):

npm run inspect

Register with Claude Code:

claude mcp add users-demo -- node /Users/d.bui/Documents/project/mcp-from-scratch/mcp/index.mjs

Conversation examples: "Show me the user list" → list_users, "Register a new member" → create_user, "Delete number 3" → no such tool exists, so guide them to the admin screen (instructed via instructions).

3. E2E Test (calling MCP "in place of Claude")

npm test             # test/mcp-client.test.mjs

Using the MCP SDK client, connect via stdio to mcp/index.mjs (the same path as Claude), then start the API → automatically verify all tools + resources + error cases (non-existent ID / duplicate email / schema violations). This can also be used for a live demo during the presentation.

4. Distributing as .mcpb for Claude Desktop

.mcpb = a Desktop Extension that zips manifest.json + code. It can be installed by double-clicking, and users don't need to install Node or edit configuration files. The API URL and access key are injected into env from user_config (the form shown at install time) (keys with sensitive: true are stored in the OS keychain).

npx @anthropic-ai/mcpb validate manifest.json
npm run pack         # → dist/users-mcp-demo.mcpb(node_modules ごと同梱)

Build artifacts are output to dist/ (not under git management). Thanks to .mcpbignore, API code and Docker-related files are not bundled into the extension — the bundle contains only manifest.json + mcp/ + node_modules.

Presentation Slides

Open slides/index.html in a browser and you can present directly (← → keys to navigate, 14 slides, works offline). Structure: overview → code shots of each layer → permission matrix → distribution → demo procedure → lessons from production.

Presentation Points (from the production spx-learning-square)

  • The MCP layer holds no permissions. It doesn't touch the DB; it only calls the REST API with a PAT. Permission checks and validation all happen in one place on the API side — even if the MCP breaks, no accident that the UI couldn't do will occur.

  • Authentication is split into two systems. Human = login + session, AI = pre-issued PAT. If the token origins differ, revocation, auditing, and rate limiting can also be designed separately.

  • Exposure to AI is an "explicit registration system." If you open up by path prefix, you can accidentally expose neighboring sensitive APIs too (a lesson that nearly happened in practice). The registry also doubles as the "API spec for AI."

  • Tool descriptions are instructions to the model. By writing operational rules like "don't guess IDs — resolve them with list_users" or "guide users to the admin screen for deletion" in description / instructions, you can control AI behavior with text rather than code.

  • Errors are returned as isError + machine-readable code, not thrown. The model can read the code and recover on its own (email_taken → suggest an alternative, etc.).

  • stdout is reserved for JSON-RPC. In a stdio server, console.log breaks the communication. Always use console.error for logging.

References

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Runtime permission, approval, and audit layer for AI agent tool execution.

  • Odoo ERP for AI agents: hosted OAuth endpoint, gated writes, one endpoint for every instance.

  • Permission boundary receipts for ChatGPT agents.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/d-bui/mcp-from-scratch'

If you have feedback or need assistance with the MCP directory API, please join our Discord server