pqc-memory-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +47 -0
- package/AGENTS.md +13 -0
- package/README.md +403 -0
- package/dist/auth/tenant-verifier.d.ts +18 -0
- package/dist/auth/tenant-verifier.d.ts.map +1 -0
- package/dist/auth/tenant-verifier.js +255 -0
- package/dist/auth/tenant-verifier.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +34 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +244 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +543 -0
- package/dist/client.js.map +1 -0
- package/dist/debug.d.ts +6 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +21 -0
- package/dist/debug.js.map +1 -0
- package/dist/http.d.ts +21 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +189 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/init-wizard.d.ts +3 -0
- package/dist/init-wizard.d.ts.map +1 -0
- package/dist/init-wizard.js +138 -0
- package/dist/init-wizard.js.map +1 -0
- package/dist/mcp-exchange.d.ts +38 -0
- package/dist/mcp-exchange.d.ts.map +1 -0
- package/dist/mcp-exchange.js +126 -0
- package/dist/mcp-exchange.js.map +1 -0
- package/dist/server-factory.d.ts +8 -0
- package/dist/server-factory.d.ts.map +1 -0
- package/dist/server-factory.js +29 -0
- package/dist/server-factory.js.map +1 -0
- package/dist/session.d.ts +27 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +121 -0
- package/dist/session.js.map +1 -0
- package/dist/tenant-cache.d.ts +20 -0
- package/dist/tenant-cache.d.ts.map +1 -0
- package/dist/tenant-cache.js +61 -0
- package/dist/tenant-cache.js.map +1 -0
- package/dist/tenant-fetch.d.ts +20 -0
- package/dist/tenant-fetch.d.ts.map +1 -0
- package/dist/tenant-fetch.js +91 -0
- package/dist/tenant-fetch.js.map +1 -0
- package/dist/tenant-runtime.d.ts +16 -0
- package/dist/tenant-runtime.d.ts.map +1 -0
- package/dist/tenant-runtime.js +31 -0
- package/dist/tenant-runtime.js.map +1 -0
- package/dist/tenant.d.ts +20 -0
- package/dist/tenant.d.ts.map +1 -0
- package/dist/tenant.js +26 -0
- package/dist/tenant.js.map +1 -0
- package/dist/tool-definitions.d.ts +9 -0
- package/dist/tool-definitions.d.ts.map +1 -0
- package/dist/tool-definitions.js +81 -0
- package/dist/tool-definitions.js.map +1 -0
- package/dist/tool-dispatch.d.ts +9 -0
- package/dist/tool-dispatch.d.ts.map +1 -0
- package/dist/tool-dispatch.js +194 -0
- package/dist/tool-dispatch.js.map +1 -0
- package/dist/tools/codegraph.d.ts +73 -0
- package/dist/tools/codegraph.d.ts.map +1 -0
- package/dist/tools/codegraph.js +203 -0
- package/dist/tools/codegraph.js.map +1 -0
- package/dist/tools/delete.d.ts +18 -0
- package/dist/tools/delete.d.ts.map +1 -0
- package/dist/tools/delete.js +23 -0
- package/dist/tools/delete.js.map +1 -0
- package/dist/tools/evolution.d.ts +90 -0
- package/dist/tools/evolution.d.ts.map +1 -0
- package/dist/tools/evolution.js +255 -0
- package/dist/tools/evolution.js.map +1 -0
- package/dist/tools/graph.d.ts +43 -0
- package/dist/tools/graph.d.ts.map +1 -0
- package/dist/tools/graph.js +94 -0
- package/dist/tools/graph.js.map +1 -0
- package/dist/tools/models.d.ts +57 -0
- package/dist/tools/models.d.ts.map +1 -0
- package/dist/tools/models.js +105 -0
- package/dist/tools/models.js.map +1 -0
- package/dist/tools/narratives.d.ts +82 -0
- package/dist/tools/narratives.d.ts.map +1 -0
- package/dist/tools/narratives.js +218 -0
- package/dist/tools/narratives.js.map +1 -0
- package/dist/tools/objects.d.ts +65 -0
- package/dist/tools/objects.d.ts.map +1 -0
- package/dist/tools/objects.js +157 -0
- package/dist/tools/objects.js.map +1 -0
- package/dist/tools/obsidian.d.ts +31 -0
- package/dist/tools/obsidian.d.ts.map +1 -0
- package/dist/tools/obsidian.js +167 -0
- package/dist/tools/obsidian.js.map +1 -0
- package/dist/tools/outcome.d.ts +21 -0
- package/dist/tools/outcome.d.ts.map +1 -0
- package/dist/tools/outcome.js +35 -0
- package/dist/tools/outcome.js.map +1 -0
- package/dist/tools/promote.d.ts +21 -0
- package/dist/tools/promote.d.ts.map +1 -0
- package/dist/tools/promote.js +31 -0
- package/dist/tools/promote.js.map +1 -0
- package/dist/tools/reflect.d.ts +27 -0
- package/dist/tools/reflect.d.ts.map +1 -0
- package/dist/tools/reflect.js +85 -0
- package/dist/tools/reflect.js.map +1 -0
- package/dist/tools/search.d.ts +27 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +42 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/strategies.d.ts +43 -0
- package/dist/tools/strategies.d.ts.map +1 -0
- package/dist/tools/strategies.js +126 -0
- package/dist/tools/strategies.js.map +1 -0
- package/dist/tools/summary.d.ts +61 -0
- package/dist/tools/summary.d.ts.map +1 -0
- package/dist/tools/summary.js +124 -0
- package/dist/tools/summary.js.map +1 -0
- package/dist/tools/swarm.d.ts +71 -0
- package/dist/tools/swarm.d.ts.map +1 -0
- package/dist/tools/swarm.js +145 -0
- package/dist/tools/swarm.js.map +1 -0
- package/dist/tools/v4.d.ts +152 -0
- package/dist/tools/v4.d.ts.map +1 -0
- package/dist/tools/v4.js +348 -0
- package/dist/tools/v4.js.map +1 -0
- package/dist/tools/write.d.ts +30 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +52 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/types.d.ts +359 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/zod-json-schema.d.ts +3 -0
- package/dist/zod-json-schema.d.ts.map +1 -0
- package/dist/zod-json-schema.js +52 -0
- package/dist/zod-json-schema.js.map +1 -0
- package/docs/claude-remote-oauth.md +26 -0
- package/docs/crypticpqc-auth-architecture.md +107 -0
- package/docs/crypticpqc-cross-domain-auth.md +194 -0
- package/docs/mcp-auth0-exchange-contract.md +75 -0
- package/docs/mcp-authorization-spec-alignment.md +29 -0
- package/docs/mcp-org-object-storage.md +55 -0
- package/docs/pqc-api-tenant-context-go.md +238 -0
- package/docs/pqc-db-mcp-tenant-context.md +15 -0
- package/docs/pqc-db-tenant-context-implementation.md +32 -0
- package/docs/standalone-distribution.md +92 -0
- package/package.json +52 -0
- package/scripts/start.mjs +13 -0
package/.env.example
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# --- Stdio MCP (Cursor, Claude Code, Claude Desktop) ---
|
|
2
|
+
PQC_API_URL=http://localhost:8081
|
|
3
|
+
PQC_API_KEY=your-api-key-here
|
|
4
|
+
PQC_BUCKET_ID=your-bucket-uuid-here
|
|
5
|
+
|
|
6
|
+
# Optional: memory session TTL (minutes); also used as HTTP fallback if tenant-context omits session_ttl_minutes
|
|
7
|
+
# PQC_SESSION_TTL=1440
|
|
8
|
+
|
|
9
|
+
# --- HTTP MCP (remote connectors) — npm run start:http ---
|
|
10
|
+
# Public pqc-api ORIGIN only (scheme + host + port). No path. e.g. https://crypticpqc.com or http://localhost:8081
|
|
11
|
+
# MCP calls GET {origin}/api/v1/mcp/tenant-context
|
|
12
|
+
# PQC_TENANT_RESOLUTION_URL=https://crypticpqc.com
|
|
13
|
+
|
|
14
|
+
# Optional: must match pqc-api MCP_TENANT_SERVICE_API_KEY when that is set; sent as X-API-Key on tenant-context and POST /auth/mcp-exchange.
|
|
15
|
+
# If pqc-api does not use MCP_TENANT_SERVICE_API_KEY, leave this unset.
|
|
16
|
+
# PQC_MCP_SERVICE_API_KEY=
|
|
17
|
+
|
|
18
|
+
# Auth0 → pqc-db JWT exchange (requires pqc-db POST /api/v1/auth/mcp-exchange). Omit = Bearer goes straight to tenant-context (pqc-db JWT only).
|
|
19
|
+
# retry | 1 | true = same mode: tenant-context first, then mcp-exchange only if that returns 401. always = exchange first (best for Claude + Auth0 only).
|
|
20
|
+
# PQC_MCP_AUTH0_EXCHANGE=always
|
|
21
|
+
# PQC_MCP_AUTH0_EXCHANGE=true
|
|
22
|
+
|
|
23
|
+
# Optional: listen port. On Zeabur/Railway/Render, PORT is set for you; otherwise default 8787.
|
|
24
|
+
# PQC_MCP_HTTP_PORT=8787
|
|
25
|
+
|
|
26
|
+
# Optional: Host header allowlist (comma-separated) when binding publicly
|
|
27
|
+
# PQC_MCP_ALLOWED_HOSTS=mcp.example.com
|
|
28
|
+
|
|
29
|
+
# OAuth protected-resource metadata (RFC 9728) — required for Claude connector discovery (well-known must not 404 in prod).
|
|
30
|
+
# PQC_MCP_PUBLIC_URL = public origin of THIS MCP host only (no path), e.g. https://mcp.crypticpqc.com
|
|
31
|
+
# PQC_MCP_AUTHORIZATION_SERVERS = OAuth issuer URL(s), comma-separated if multiple.
|
|
32
|
+
#
|
|
33
|
+
# Auth0: Dashboard → Settings → Domain → issuer is https://<Domain>/
|
|
34
|
+
# Example shape: https://dev-xxxxxxxx.us.auth0.com/
|
|
35
|
+
# If you use an Auth0 custom domain, use that as issuer (match the "iss" claim on access tokens).
|
|
36
|
+
# PQC_MCP_PUBLIC_URL=https://mcp.example.com
|
|
37
|
+
# PQC_MCP_AUTHORIZATION_SERVERS=https://dev-xxxxxxxx.us.auth0.com/
|
|
38
|
+
#
|
|
39
|
+
# RFC 9728 JSON field "resource" (default: {PQC_MCP_PUBLIC_URL}/mcp). If Auth0 API Identifier is the origin only
|
|
40
|
+
# (e.g. https://mcp.crypticpqc.com) and Claude maps resource → audience, set this to match or Auth0 may return opaque tokens:
|
|
41
|
+
# PQC_MCP_PRM_RESOURCE=https://mcp.crypticpqc.com
|
|
42
|
+
|
|
43
|
+
# Verbose JSON logs to stderr: every HTTP hit, PRM, tenant-context, mcp-exchange, auth branches (no secrets; token SHA-256 prefix only).
|
|
44
|
+
# PQC_MCP_DEBUG=1
|
|
45
|
+
|
|
46
|
+
# DEV ONLY: treat any Bearer as env tenant (ignored when NODE_ENV=production). Requires PQC_API_* above.
|
|
47
|
+
# PQC_TENANT_CONTEXT_MOCK=1
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
## Learned User Preferences
|
|
2
|
+
|
|
3
|
+
- Target one MCP codebase that works in Claude Code, Cursor, and remote Claude chat, not only a single local setup.
|
|
4
|
+
- For a broadly usable hosted MCP, plan on OAuth plus DCR-friendly setup (or a custom-credentials variant that fits the IdP) and per-user tenant context instead of one shared process-global environment for all users.
|
|
5
|
+
|
|
6
|
+
## Learned Workspace Facts
|
|
7
|
+
|
|
8
|
+
- Encrypted org object upload and download in this stack go through the managed-key API only: `POST /api/v1/keys/managed/{key_id}/objects` (multipart with `file`, `bucket_id`, optional `filename`) and `GET /api/v1/keys/managed/{key_id}/objects/{object_id}`; do not use removed legacy paths such as `/api/v1/objects/upload` or `/api/v1/objects/{id}/download` for that flow.
|
|
9
|
+
- For HTTP MCP with tenant resolution, set `PQC_TENANT_RESOLUTION_URL` to the public API origin only (no path, no trailing slash). Call `GET {origin}/api/v1/mcp/tenant-context` with `Authorization: Bearer` carrying a valid pqc-api access JWT; use the JSON body fields (for example `api_url`, `api_key`, `bucket_id`, and session TTL when present) for subsequent memory calls.
|
|
10
|
+
- The Cursor MCP command can run the local `dist/index.js` bridge while environment variables still point `PQC_API_URL` (or equivalent) at a remote host; treating the process as local does not mean the backing API is local unless those vars target a local stack.
|
|
11
|
+
- This repo root is the **generator** (`pqc-mcp-server`, `private` on npm). The publishable package is **`pqc-memory-mcp`**, produced under **`oss-bundle/pqc-memory-mcp/`** via **`npm run generate:standalone`** from [`packaging/published-package.json`](packaging/published-package.json). Do not `npm publish` from the repo root.
|
|
12
|
+
- pqc-mcp-server is primarily a typed client to pqc-db’s REST API; heavier object storage and conversion logic is expected to stay in pqc-db or workers rather than duplicating upload or download paths in the MCP.
|
|
13
|
+
- If pqc-memory MCP tools fail parsing JSON with errors such as unexpected token at position zero, the client often received HTML (login page, proxy error, or non-API response); check the configured API URL, API key and bucket, that `dist/` is rebuilt after code changes, and that the correct MCP server is attached in the active Cursor project.
|
package/README.md
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
# PQC Memory MCP Server
|
|
2
|
+
|
|
3
|
+
An MCP ([Model Context Protocol](https://modelcontextprotocol.io)) server that connects **any MCP-capable client**—IDEs, CLI agents, or hosted connectors—to your **pqc-db** memory API for persistent, org-scoped memory across sessions. **Cursor** is one supported host; the same **`pqc-memory-mcp`** package also works with **Claude Code**, **Codex**, **VS Code**, **JetBrains Junie**, **Zed**, and others that speak stdio or Streamable HTTP MCP (see [**add-mcp** supported agents](https://github.com/neondatabase/add-mcp#supported-agents)).
|
|
4
|
+
|
|
5
|
+
**This GitHub repo (`pqc-mcp-server`) is the generator / dev workspace** (`private` on npm—do not publish from the root). The **npm package `pqc-memory-mcp`** is produced under **`oss-bundle/pqc-memory-mcp/`** via **`npm run generate:standalone`**. Publish only from that folder (or use **`npm run publish:npm`** from the repo root). Manifest template: [`packaging/published-package.json`](packaging/published-package.json) (bump **`version`** there before a release).
|
|
6
|
+
|
|
7
|
+
**Consumers** use npm (`npx -y pqc-memory-mcp`), a GitHub release zip, or a clone; see [docs/standalone-distribution.md](docs/standalone-distribution.md). **Contributors** keep the full tree, including [`.cursor/`](.cursor/).
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Quick run instructions
|
|
11
|
+
- cd /path/to/pqc-mcp-server
|
|
12
|
+
- run npm install
|
|
13
|
+
- npm run build
|
|
14
|
+
- npm run generate:standalone
|
|
15
|
+
- cd oss-bundle && cd pqc-memory-mcp -- from here can run (npm run init) or
|
|
16
|
+
- npm pack - generates: pqc-memory-mcp/pqc-memory-mcp-1.0.0.tgz
|
|
17
|
+
- now take the tarball to a local workspace root in cursor, jetbrians, vscode.
|
|
18
|
+
- open a terminal in the workspace root and run the commands below
|
|
19
|
+
- npm install /full/path/to/pqc-memory-mcp-1.0.0.tgz (npm install ./pqc-memory-mcp-1.0.0.tgz)
|
|
20
|
+
- npx -y pqc-memory-mcp init
|
|
21
|
+
- setup wizard takes over
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- **Semantic Search** - Find memories by meaning, not just keywords
|
|
27
|
+
- **Reflective Memory** - Intelligent synthesis using AI to answer questions from your memory bank
|
|
28
|
+
- **Knowledge Graph** - Explore entities and relationships extracted from memories
|
|
29
|
+
- **Outcome Tracking** - Tag memories as success/failure to improve future recommendations
|
|
30
|
+
- **Mental Models** - Pre-computed knowledge summaries
|
|
31
|
+
- **Strategies** - Learned reasoning patterns from successful outcomes
|
|
32
|
+
- **Conversation Summaries** - Save important conversations for future reference
|
|
33
|
+
|
|
34
|
+
## Prerequisites
|
|
35
|
+
|
|
36
|
+
1. **pqc-db running** - The API should be accessible (default: `http://localhost:8081`)
|
|
37
|
+
2. **API Key** - Create one via the pqc-db dashboard or API
|
|
38
|
+
3. **Bucket** - Create a memory bucket in pqc-db for this agent or team
|
|
39
|
+
|
|
40
|
+
## Guided setup: Cursor, Claude Code, or Junie (no manual JSON)
|
|
41
|
+
|
|
42
|
+
Same idea as [Agentation’s `agentation-mcp init`](https://www.agentation.com/install): run a short wizard; it **writes or merges** `mcpServers` with **`command`**, **`args`**, and **`PQC_*`** env.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx -y pqc-memory-mcp init
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
(`setup` is an alias.) You pick the **client** and **scope**:
|
|
49
|
+
|
|
50
|
+
| Client | Project scope | User (global) scope |
|
|
51
|
+
|--------|---------------|----------------------|
|
|
52
|
+
| **Cursor** | `<project>/.cursor/mcp.json` | `~/.cursor/mcp.json` |
|
|
53
|
+
| **Claude Code** | `<project>/.mcp.json` | `~/.claude.json` ([docs](https://code.claude.com/docs/en/mcp)) |
|
|
54
|
+
| **JetBrains Junie** | `<project>/.junie/mcp/mcp.json` | `~/.junie/mcp/mcp.json` ([docs](https://junie.jetbrains.com/docs/junie-cli-mcp-configuration.html)) |
|
|
55
|
+
|
|
56
|
+
Then paste URL / API key / bucket, and choose **npm `npx`** vs **local `node …/cli.js`**. Restart the IDE or CLI and confirm MCP (Cursor: Settings → Tools & MCP; Claude Code / Junie: **`/mcp`**).
|
|
57
|
+
|
|
58
|
+
From a git clone of this repo (before publish):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm install && npm run build && node dist/cli.js init
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Easiest install: add-mcp (optional)
|
|
65
|
+
|
|
66
|
+
Use [**add-mcp**](https://github.com/neondatabase/add-mcp) from Neon: `npx add-mcp …` registers this server in one shot for **Cursor**, **Claude Code**, **Codex**, **VS Code**, and [many other hosts](https://github.com/neondatabase/add-mcp#supported-agents) (run `npx add-mcp list-agents`). Use **`-a <agent>`** to target one client, or omit it for detection. Local npm packages always run over **stdio**; the string you pass is the command your host invokes.
|
|
67
|
+
|
|
68
|
+
The published package is **`pqc-memory-mcp`** ([npm](https://www.npmjs.com/package/pqc-memory-mcp)); source lives in [**pqc-mcp-server**](https://github.com/CascadiaTech/pqc-mcp-server) on GitHub.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Interactive: detect agents in the current project
|
|
72
|
+
npx add-mcp "npx -y pqc-memory-mcp" --name pqc-memory
|
|
73
|
+
|
|
74
|
+
# Example: Cursor — project .cursor/mcp.json, no prompts
|
|
75
|
+
npx add-mcp "npx -y pqc-memory-mcp" -a cursor -y --name pqc-memory
|
|
76
|
+
|
|
77
|
+
# Example: Cursor — global ~/.cursor/mcp.json
|
|
78
|
+
npx add-mcp "npx -y pqc-memory-mcp" -g -a cursor -y --name pqc-memory
|
|
79
|
+
|
|
80
|
+
# Example: Claude Code only (see add-mcp for other -a names)
|
|
81
|
+
npx add-mcp "npx -y pqc-memory-mcp" -a claude-code -y --name pqc-memory
|
|
82
|
+
|
|
83
|
+
# Register all agents add-mcp supports, global configs
|
|
84
|
+
npx add-mcp "npx -y pqc-memory-mcp" -g --all -y --name pqc-memory
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**After `add-mcp`:** if you did **not** use **`npx pqc-memory-mcp init`**, you must still add **`env`** (`PQC_API_URL`, `PQC_API_KEY`, `PQC_BUCKET_ID`) to the config it wrote—or run **`npx -y pqc-memory-mcp init`** instead and skip `add-mcp` for Cursor.
|
|
88
|
+
|
|
89
|
+
**Before the package is on npm:** point at a built **`dist/index.js`** (from this repo or from the generated standalone):
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npm run generate:standalone
|
|
93
|
+
npx add-mcp "node /absolute/path/to/pqc-mcp-server/oss-bundle/pqc-memory-mcp/dist/index.js" -a claude-code -y --name pqc-memory
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
(or use `.../pqc-mcp-server/dist/index.js` right after **`npm run build`**). Swap **`-a`** for your client. Then add the same **`env`** block in that client’s config.
|
|
97
|
+
|
|
98
|
+
**Manual config** (stdio MCP) if you set up the host yourself—the **exact file and JSON shape** depend on the client (Cursor uses `mcpServers`; others use TOML or different keys). Conceptually you need **`command`**, **`args`**, and **`env`**:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"mcpServers": {
|
|
103
|
+
"pqc-memory": {
|
|
104
|
+
"command": "npx",
|
|
105
|
+
"args": ["-y", "pqc-memory-mcp"],
|
|
106
|
+
"env": {
|
|
107
|
+
"PQC_API_URL": "http://localhost:8081",
|
|
108
|
+
"PQC_API_KEY": "your-api-key",
|
|
109
|
+
"PQC_BUCKET_ID": "your-bucket-uuid"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
*(Example shape compatible with Cursor-style **`mcp.json`**; translate for your tool’s docs.)*
|
|
117
|
+
|
|
118
|
+
**Tie-in:** Put real values in **`env`**, **restart the MCP host** (IDE, CLI session, or connector) so it reloads servers, then invoke a memory tool—the first call should reach your pqc-db API using this server’s session flow.
|
|
119
|
+
|
|
120
|
+
**Maintainers:** full **change → regenerate → test → release** flow is in [Maintainer guide](#maintainer-guide-develop-regenerate-test-release) below.
|
|
121
|
+
|
|
122
|
+
**Git clone** (no npm registry): use the [standalone bundle](docs/standalone-distribution.md) or clone this repo, then follow **Setup** below.
|
|
123
|
+
|
|
124
|
+
## Setup
|
|
125
|
+
|
|
126
|
+
### 1. Install Dependencies
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
git clone https://github.com/CascadiaTech/pqc-mcp-server.git
|
|
130
|
+
cd pqc-mcp-server
|
|
131
|
+
npm install
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 2. Build
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npm run build
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 3. Configure your MCP client
|
|
141
|
+
|
|
142
|
+
Point the host at **`dist/index.js`** (stdio) with **`PQC_API_*`** env vars. Example for **Cursor** (`~/.cursor/mcp.json` or project **`.cursor/mcp.json`**):
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"mcpServers": {
|
|
147
|
+
"pqc-memory": {
|
|
148
|
+
"command": "node",
|
|
149
|
+
"args": ["/path/to/pqc-mcp-server/dist/index.js"],
|
|
150
|
+
"env": {
|
|
151
|
+
"PQC_API_URL": "http://localhost:8081",
|
|
152
|
+
"PQC_API_KEY": "your-api-key",
|
|
153
|
+
"PQC_BUCKET_ID": "your-bucket-uuid"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Other clients: use their documented MCP location and field names (often the same **`command` / `args` / `env`** idea).
|
|
161
|
+
|
|
162
|
+
### 4. Restart the client
|
|
163
|
+
|
|
164
|
+
Restart the IDE or agent (or reload MCP) so it picks up the new server.
|
|
165
|
+
|
|
166
|
+
## Available Tools
|
|
167
|
+
|
|
168
|
+
| Tool | Description |
|
|
169
|
+
|------|-------------|
|
|
170
|
+
| `memory_search` | Semantic search across memories |
|
|
171
|
+
| `memory_reflect` | Intelligent synthesis with sources |
|
|
172
|
+
| `memory_write` | Save new memory |
|
|
173
|
+
| `memory_graph_entities` | List known entities |
|
|
174
|
+
| `memory_graph_related` | Find related entities |
|
|
175
|
+
| `memory_graph_memories` | Find memories by entity |
|
|
176
|
+
| `memory_tag_outcome` | Mark memory as success/failure |
|
|
177
|
+
| `memory_mental_models_list` | List mental models |
|
|
178
|
+
| `memory_mental_model_get` | Get mental model details |
|
|
179
|
+
| `memory_mental_model_create` | Create new mental model |
|
|
180
|
+
| `memory_mental_model_refresh` | Refresh mental model |
|
|
181
|
+
| `memory_strategies_list` | List learned strategies |
|
|
182
|
+
| `memory_strategy_get` | Get strategy details |
|
|
183
|
+
| `memory_save_summary` | Save conversation summary |
|
|
184
|
+
| `memory_batch_write` | Write multiple memories |
|
|
185
|
+
| `object_upload` | Encrypted upload via managed Kyber key (`POST .../keys/managed/{key_id}/objects`) |
|
|
186
|
+
| `object_download` | Decrypted download via managed key (`GET .../objects/{object_id}`) |
|
|
187
|
+
| `object_list` | List org objects (`GET /objects`, optional `bucket`) |
|
|
188
|
+
| `object_get` | Object metadata (`GET /objects/{id}`) |
|
|
189
|
+
|
|
190
|
+
See [docs/mcp-org-object-storage.md](docs/mcp-org-object-storage.md) for the API contract.
|
|
191
|
+
|
|
192
|
+
## Usage examples
|
|
193
|
+
|
|
194
|
+
In any connected MCP client’s chat:
|
|
195
|
+
|
|
196
|
+
- "Search my memories for authentication patterns"
|
|
197
|
+
- "What do I know about this project's testing approach?"
|
|
198
|
+
- "Remember that I prefer TypeScript over JavaScript"
|
|
199
|
+
- "Save this conversation - we fixed the database migration issue"
|
|
200
|
+
|
|
201
|
+
## Remote HTTP MCP (Streamable HTTP)
|
|
202
|
+
|
|
203
|
+
For clients that only support **HTTP** (e.g. Claude.ai custom connectors), run the second entrypoint. Each MCP request carries an `Authorization: Bearer <access_token>` header. The HTTP server calls **pqc-api** once per cached tenant window:
|
|
204
|
+
|
|
205
|
+
`GET {PQC_TENANT_RESOLUTION_URL}/api/v1/mcp/tenant-context`
|
|
206
|
+
|
|
207
|
+
Alignment with **pqc-api** (see [docs/pqc-api-tenant-context-go.md](docs/pqc-api-tenant-context-go.md)):
|
|
208
|
+
|
|
209
|
+
| MCP env | Value |
|
|
210
|
+
|--------|--------|
|
|
211
|
+
| **`PQC_TENANT_RESOLUTION_URL`** | **Public API origin only** — no path, no trailing slash required, e.g. `https://crypticpqc.com` or `http://localhost:8081`. Same host you use for `/api/v1/...`. (Extra paths on this env are stripped to the origin.) |
|
|
212
|
+
| Bearer token | With **`PQC_MCP_AUTH0_EXCHANGE` unset:** pqc-api **access JWT** only. With **`retry`** or **`always`:** Claude’s **Auth0 access JWT** is exchanged via **`POST /api/v1/auth/mcp-exchange`**, then **`tenant-context`** uses the minted pqc-db JWT (see [docs/mcp-auth0-exchange-contract.md](docs/mcp-auth0-exchange-contract.md)). |
|
|
213
|
+
|
|
214
|
+
After a **200**, this server drives **all** memory traffic from the JSON body (`api_url`, `api_key`, `bucket_id`, optional `session_ttl_minutes`). It does **not** use `PQC_API_URL` / `PQC_API_KEY` / `PQC_BUCKET_ID` for HTTP mode (those remain for **stdio** and for **`PQC_TENANT_CONTEXT_MOCK`** only).
|
|
215
|
+
|
|
216
|
+
**Optional service key (both sides must match):**
|
|
217
|
+
|
|
218
|
+
| MCP | pqc-api |
|
|
219
|
+
|-----|--------|
|
|
220
|
+
| `PQC_MCP_SERVICE_API_KEY` | `MCP_TENANT_SERVICE_API_KEY` (same string) |
|
|
221
|
+
|
|
222
|
+
If set on pqc-api, MCP sends **`X-API-Key`** on **`tenant-context`** and **`mcp-exchange`**. If pqc-api does **not** require it, leave both unset (otherwise those routes return **401**).
|
|
223
|
+
|
|
224
|
+
Build and start:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
npm run build
|
|
228
|
+
export PQC_TENANT_RESOLUTION_URL="https://crypticpqc.com"
|
|
229
|
+
npm run start:http
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Point the connector at **`POST https://your-mcp-host/mcp`**.
|
|
233
|
+
|
|
234
|
+
**Health checks (for load balancers or clicking the host in a browser):**
|
|
235
|
+
|
|
236
|
+
- `GET https://your-mcp-host/` — short JSON + links
|
|
237
|
+
- `GET /health` or `GET /healthz` — minimal `{ "status": "ok", ... }`
|
|
238
|
+
- `GET /mcp` — **200** JSON explaining that MCP uses **POST** (opening `/mcp` in a browser is not an error)
|
|
239
|
+
|
|
240
|
+
**Optional OAuth discovery:** set `PQC_MCP_PUBLIC_URL` and `PQC_MCP_AUTHORIZATION_SERVERS` (comma-separated issuer URLs) to expose [RFC 9728](https://www.rfc-editor.org/rfc/rfc9728) protected-resource metadata at `/.well-known/oauth-protected-resource/mcp`.
|
|
241
|
+
|
|
242
|
+
**Cross-domain auth (Cryptic PQC):** see [docs/crypticpqc-cross-domain-auth.md](docs/crypticpqc-cross-domain-auth.md) for how **`crypticpqc.com`**, **`app.crypticpqc.com`**, **`mcp.crypticpqc.com`**, and **`crypto.crypticpqc.com`** should share Auth0, tokens, and `tenant-context`. When pqc-db ships **`POST /api/v1/auth/mcp-exchange`**, see [docs/mcp-auth0-exchange-contract.md](docs/mcp-auth0-exchange-contract.md) for the request/response contract (MCP will call exchange, then `tenant-context`). Spec vs implementation: [docs/mcp-authorization-spec-alignment.md](docs/mcp-authorization-spec-alignment.md).
|
|
243
|
+
|
|
244
|
+
**Local dev without tenant-context:** set `PQC_TENANT_CONTEXT_MOCK=1` and the usual `PQC_API_*` env vars; **any** Bearer maps to that env tenant (ignored when `NODE_ENV=production`).
|
|
245
|
+
|
|
246
|
+
## Maintainer guide: develop, regenerate, test, release
|
|
247
|
+
|
|
248
|
+
This section is for people working in **`pqc-mcp-server`** (this repo). End users install **`pqc-memory-mcp`** from npm or a release zip—they do not run these steps unless they clone.
|
|
249
|
+
|
|
250
|
+
### What lives where
|
|
251
|
+
|
|
252
|
+
| Path | Role |
|
|
253
|
+
|------|------|
|
|
254
|
+
| **`src/`**, **`package.json` (root)** | Author changes here. Root is **`private`: true** — never **`npm publish`** from repo root. |
|
|
255
|
+
| **`packaging/published-package.json`** | The **published** package name, version, `bin`, `files`, and runtime **`dependencies`**. Bump **`version`** here before each npm release. |
|
|
256
|
+
| **`oss-bundle/pqc-memory-mcp/`** | **Generated** tree: what you **`npm pack`** / **`npm publish`** and what the GitHub Action zips. Gitignored; recreated by **`generate:standalone`**. |
|
|
257
|
+
|
|
258
|
+
### Day-to-day: change code, rebuild, regenerate
|
|
259
|
+
|
|
260
|
+
**Run these commands from the `pqc-mcp-server` repo root**, not from **`oss-bundle/pqc-memory-mcp`** or an extracted npm tarball. The published package ships **`dist/`** pre-built; `npm run build` there only prints where to go (`npm run build` in the generator repo compiles **`src/`**).
|
|
261
|
+
|
|
262
|
+
1. **`git pull`** (if using git) and **`npm install`**.
|
|
263
|
+
|
|
264
|
+
2. Edit **`src/`** (and **`packaging/published-package.json`** if metadata changes).
|
|
265
|
+
|
|
266
|
+
3. **Typecheck and compile:**
|
|
267
|
+
```bash
|
|
268
|
+
npm run typecheck
|
|
269
|
+
npm run build
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
4. **Regenerate the standalone folder** (copies fresh **`dist/`**, docs, manifest from packaging, etc.):
|
|
273
|
+
```bash
|
|
274
|
+
npm run generate:standalone
|
|
275
|
+
```
|
|
276
|
+
- Offline / skip lockfile refresh inside the bundle:
|
|
277
|
+
`npm run build && node scripts/generate-standalone.mjs --no-lock`
|
|
278
|
+
- One-off version override for the generated **`package.json`**:
|
|
279
|
+
`npm run build && node scripts/generate-standalone.mjs --version=1.2.3`
|
|
280
|
+
|
|
281
|
+
5. **Automated smoke test** (what consumers get from the registry):
|
|
282
|
+
```bash
|
|
283
|
+
npm run verify:pack
|
|
284
|
+
```
|
|
285
|
+
This runs **`generate:standalone`**, then **`npm pack`** inside **`oss-bundle/pqc-memory-mcp`**, installs that `.tgz` in a temp project, and checks bins + missing-env error + stdio startup line.
|
|
286
|
+
|
|
287
|
+
### Local testing (manual, like “install my own package”)
|
|
288
|
+
|
|
289
|
+
**A. Tarball install (mirrors npm)**
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
cd oss-bundle/pqc-memory-mcp
|
|
293
|
+
npm pack
|
|
294
|
+
mkdir -p /tmp/pqc-smoke && cd /tmp/pqc-smoke
|
|
295
|
+
npm init -y
|
|
296
|
+
npm install /absolute/path/to/oss-bundle/pqc-memory-mcp/pqc-memory-mcp-x.y.z.tgz
|
|
297
|
+
export PQC_API_URL="https://your-api-origin"
|
|
298
|
+
export PQC_API_KEY="your-key"
|
|
299
|
+
export PQC_BUCKET_ID="your-bucket-uuid"
|
|
300
|
+
./node_modules/.bin/pqc-memory-mcp
|
|
301
|
+
```
|
|
302
|
+
Expect **`[pqc-memory] Server started (stdio)`** on stderr. Use **Ctrl+C** to stop.
|
|
303
|
+
`export VAR=value` must have **no space** around **`=`**.
|
|
304
|
+
|
|
305
|
+
**B. Guided `init` wizard** (from repo, before publish):
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
npm run init
|
|
309
|
+
```
|
|
310
|
+
(or **`npm run build && node dist/cli.js init`**) — picks Cursor / Claude Code / Junie and writes the right **`mcp.json`**.
|
|
311
|
+
|
|
312
|
+
**C. Point Cursor at a local build**
|
|
313
|
+
|
|
314
|
+
- After **`npm run build`**: **`command`** = **`node`**, **`args`**: **`["/absolute/path/to/pqc-mcp-server/dist/cli.js"]`**, plus **`env`**.
|
|
315
|
+
- Or after **`generate:standalone`**: use **`…/oss-bundle/pqc-memory-mcp/dist/cli.js`**.
|
|
316
|
+
|
|
317
|
+
### Release: version, verify, publish, GitHub
|
|
318
|
+
|
|
319
|
+
1. **Version** — edit **`version`** in **`packaging/published-package.json`** (semantic versioning).
|
|
320
|
+
|
|
321
|
+
2. **Verify from clean generation:**
|
|
322
|
+
```bash
|
|
323
|
+
npm run verify:pack
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
3. **Dry-run the publish tarball** (optional):
|
|
327
|
+
```bash
|
|
328
|
+
npm run pack:publish
|
|
329
|
+
```
|
|
330
|
+
Inspect **`oss-bundle/pqc-memory-mcp/pqc-memory-mcp-*.tgz`**.
|
|
331
|
+
|
|
332
|
+
4. **Publish to npm** (requires `npm login` / token and rights to the package name):
|
|
333
|
+
```bash
|
|
334
|
+
npm run publish:npm
|
|
335
|
+
```
|
|
336
|
+
Equivalent to:
|
|
337
|
+
```bash
|
|
338
|
+
npm run generate:standalone
|
|
339
|
+
cd oss-bundle/pqc-memory-mcp
|
|
340
|
+
npm publish --access public
|
|
341
|
+
```
|
|
342
|
+
Do **not** run **`npm publish`** in the repo root (it is **`private`**).
|
|
343
|
+
|
|
344
|
+
5. **Git** — commit, tag (e.g. **`v1.2.3`** matching **`packaging/published-package.json`**), push. The **OSS bundle** workflow (`.github/workflows/oss-bundle.yml`) can build a zip on **release**; attach the artifact or **`pqc-memory-mcp-standalone.zip`** from CI as needed.
|
|
345
|
+
|
|
346
|
+
### Dev commands (watch mode)
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
npm run dev # stdio server, tsx watch
|
|
350
|
+
npm run dev:http # HTTP entry, tsx watch
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### `npm start` (Zeabur, Railway, Docker)
|
|
354
|
+
|
|
355
|
+
- If **`PQC_TENANT_RESOLUTION_URL`** is set → runs **HTTP** MCP (`dist/http.js`).
|
|
356
|
+
- Otherwise → runs **stdio** MCP (`dist/index.js`, needs `PQC_API_*`).
|
|
357
|
+
|
|
358
|
+
Use **`npm run start:http`** or **`npm run start:stdio`** to force one mode regardless of env.
|
|
359
|
+
|
|
360
|
+
## Environment Variables
|
|
361
|
+
|
|
362
|
+
### Stdio (local MCP clients)
|
|
363
|
+
|
|
364
|
+
Local **stdio** transport: used by most editor and CLI integrations (e.g. Cursor, Claude Code, Codex, Junie, Zed—whatever your host supports).
|
|
365
|
+
|
|
366
|
+
| Variable | Required | Description |
|
|
367
|
+
|----------|----------|-------------|
|
|
368
|
+
| `PQC_API_URL` | Yes | pqc-db API URL |
|
|
369
|
+
| `PQC_API_KEY` | Yes | Your API key |
|
|
370
|
+
| `PQC_BUCKET_ID` | Yes | Bucket UUID for memories |
|
|
371
|
+
| `PQC_SESSION_TTL` | No | Session TTL in minutes (default: 1440) |
|
|
372
|
+
|
|
373
|
+
### HTTP MCP
|
|
374
|
+
|
|
375
|
+
| Variable | Required | Description |
|
|
376
|
+
|----------|----------|-------------|
|
|
377
|
+
| `PQC_TENANT_RESOLUTION_URL` | Yes | **pqc-api public origin only** (e.g. `https://crypticpqc.com`) for `GET /api/v1/mcp/tenant-context` |
|
|
378
|
+
| `PQC_MCP_HTTP_PORT` | No | Listen port (default: 8787) |
|
|
379
|
+
| `PQC_MCP_SERVICE_API_KEY` | No | If set, sent as `X-API-Key` on `tenant-context` and `mcp-exchange`; must equal pqc-api **`MCP_TENANT_SERVICE_API_KEY`** when that is enabled |
|
|
380
|
+
| `PQC_MCP_AUTH0_EXCHANGE` | No | `retry` / `1` / `true` = exchange on 401; `always` = always call `mcp-exchange` first for Auth0 JWT. See [mcp-auth0-exchange-contract.md](docs/mcp-auth0-exchange-contract.md) |
|
|
381
|
+
| `PQC_MCP_DEBUG` | No | Set to `1` for JSON debug lines on stderr: HTTP hits, PRM, `tenant-context`, `mcp-exchange`, auth branches (no secrets; inbound token fingerprint only). Disable after troubleshooting. |
|
|
382
|
+
| `PQC_SESSION_TTL` | No | Fallback if tenant-context **200** omits `session_ttl_minutes` (pqc-api often returns **1440**) |
|
|
383
|
+
| `PQC_MCP_ALLOWED_HOSTS` | No | Comma-separated `Host` allowlist (DNS rebinding protection) |
|
|
384
|
+
| `PQC_MCP_PUBLIC_URL` | No | Public origin for OAuth PRM (e.g. `https://mcp.example.com`) |
|
|
385
|
+
| `PQC_MCP_AUTHORIZATION_SERVERS` | No | Comma-separated issuer URLs (with `PQC_MCP_PUBLIC_URL`, serves PRM) |
|
|
386
|
+
| `PQC_MCP_PRM_RESOURCE` | No | Override RFC 9728 `resource` in PRM (default `{PUBLIC_URL}/mcp`). Set to match Auth0 **API Identifier** if clients map `resource` → `audience` and you otherwise get **opaque** tokens. |
|
|
387
|
+
| `PQC_TENANT_CONTEXT_MOCK` | No | Set to `1` for dev-only env-based tenant (see above) |
|
|
388
|
+
|
|
389
|
+
## Architecture
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
MCP host (IDE, CLI agent, or HTTP connector)
|
|
393
|
+
↓ MCP (stdio or Streamable HTTP)
|
|
394
|
+
pqc-memory-mcp
|
|
395
|
+
↓ HTTP + session token
|
|
396
|
+
pqc-db API
|
|
397
|
+
↓
|
|
398
|
+
PostgreSQL + Qdrant + Neo4j
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
**Streamable HTTP** uses the same tools; the HTTP entry resolves **Bearer → tenant** via pqc-db before opening a memory session per cached tenant runtime.
|
|
402
|
+
|
|
403
|
+
The stdio server maintains a persistent session with pqc-db for one configured bucket. The HTTP server caches **`TenantRuntime`** (client + session manager) per bearer hash with LRU eviction.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TenantContext } from "../tenant.js";
|
|
2
|
+
/** Shapes returned by verifyAccessToken; extended fields for pqc-mcp. */
|
|
3
|
+
export type TenantAuthInfo = {
|
|
4
|
+
token: string;
|
|
5
|
+
clientId: string;
|
|
6
|
+
scopes: string[];
|
|
7
|
+
expiresAt: number;
|
|
8
|
+
tenantContext: TenantContext;
|
|
9
|
+
rawToken: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* MCP SDK AccessTokenVerifier: resolves pqc-db tenant context for a bearer token.
|
|
13
|
+
* When PQC_MCP_AUTH0_EXCHANGE is set, calls POST /api/v1/auth/mcp-exchange for Auth0 JWTs (see docs).
|
|
14
|
+
*/
|
|
15
|
+
export declare function createPqcTenantVerifier(resolutionBaseUrl: string | undefined): {
|
|
16
|
+
verifyAccessToken(token: string): Promise<TenantAuthInfo>;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=tenant-verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-verifier.d.ts","sourceRoot":"","sources":["../../src/auth/tenant-verifier.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAIlD,yEAAyE;AACzE,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAiLF;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS;6BAM1C,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;EAgFlE"}
|