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.
Files changed (155) hide show
  1. package/.env.example +47 -0
  2. package/AGENTS.md +13 -0
  3. package/README.md +403 -0
  4. package/dist/auth/tenant-verifier.d.ts +18 -0
  5. package/dist/auth/tenant-verifier.d.ts.map +1 -0
  6. package/dist/auth/tenant-verifier.js +255 -0
  7. package/dist/auth/tenant-verifier.js.map +1 -0
  8. package/dist/cli.d.ts +3 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +34 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/client.d.ts +244 -0
  13. package/dist/client.d.ts.map +1 -0
  14. package/dist/client.js +543 -0
  15. package/dist/client.js.map +1 -0
  16. package/dist/debug.d.ts +6 -0
  17. package/dist/debug.d.ts.map +1 -0
  18. package/dist/debug.js +21 -0
  19. package/dist/debug.js.map +1 -0
  20. package/dist/http.d.ts +21 -0
  21. package/dist/http.d.ts.map +1 -0
  22. package/dist/http.js +189 -0
  23. package/dist/http.js.map +1 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +28 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/init-wizard.d.ts +3 -0
  29. package/dist/init-wizard.d.ts.map +1 -0
  30. package/dist/init-wizard.js +138 -0
  31. package/dist/init-wizard.js.map +1 -0
  32. package/dist/mcp-exchange.d.ts +38 -0
  33. package/dist/mcp-exchange.d.ts.map +1 -0
  34. package/dist/mcp-exchange.js +126 -0
  35. package/dist/mcp-exchange.js.map +1 -0
  36. package/dist/server-factory.d.ts +8 -0
  37. package/dist/server-factory.d.ts.map +1 -0
  38. package/dist/server-factory.js +29 -0
  39. package/dist/server-factory.js.map +1 -0
  40. package/dist/session.d.ts +27 -0
  41. package/dist/session.d.ts.map +1 -0
  42. package/dist/session.js +121 -0
  43. package/dist/session.js.map +1 -0
  44. package/dist/tenant-cache.d.ts +20 -0
  45. package/dist/tenant-cache.d.ts.map +1 -0
  46. package/dist/tenant-cache.js +61 -0
  47. package/dist/tenant-cache.js.map +1 -0
  48. package/dist/tenant-fetch.d.ts +20 -0
  49. package/dist/tenant-fetch.d.ts.map +1 -0
  50. package/dist/tenant-fetch.js +91 -0
  51. package/dist/tenant-fetch.js.map +1 -0
  52. package/dist/tenant-runtime.d.ts +16 -0
  53. package/dist/tenant-runtime.d.ts.map +1 -0
  54. package/dist/tenant-runtime.js +31 -0
  55. package/dist/tenant-runtime.js.map +1 -0
  56. package/dist/tenant.d.ts +20 -0
  57. package/dist/tenant.d.ts.map +1 -0
  58. package/dist/tenant.js +26 -0
  59. package/dist/tenant.js.map +1 -0
  60. package/dist/tool-definitions.d.ts +9 -0
  61. package/dist/tool-definitions.d.ts.map +1 -0
  62. package/dist/tool-definitions.js +81 -0
  63. package/dist/tool-definitions.js.map +1 -0
  64. package/dist/tool-dispatch.d.ts +9 -0
  65. package/dist/tool-dispatch.d.ts.map +1 -0
  66. package/dist/tool-dispatch.js +194 -0
  67. package/dist/tool-dispatch.js.map +1 -0
  68. package/dist/tools/codegraph.d.ts +73 -0
  69. package/dist/tools/codegraph.d.ts.map +1 -0
  70. package/dist/tools/codegraph.js +203 -0
  71. package/dist/tools/codegraph.js.map +1 -0
  72. package/dist/tools/delete.d.ts +18 -0
  73. package/dist/tools/delete.d.ts.map +1 -0
  74. package/dist/tools/delete.js +23 -0
  75. package/dist/tools/delete.js.map +1 -0
  76. package/dist/tools/evolution.d.ts +90 -0
  77. package/dist/tools/evolution.d.ts.map +1 -0
  78. package/dist/tools/evolution.js +255 -0
  79. package/dist/tools/evolution.js.map +1 -0
  80. package/dist/tools/graph.d.ts +43 -0
  81. package/dist/tools/graph.d.ts.map +1 -0
  82. package/dist/tools/graph.js +94 -0
  83. package/dist/tools/graph.js.map +1 -0
  84. package/dist/tools/models.d.ts +57 -0
  85. package/dist/tools/models.d.ts.map +1 -0
  86. package/dist/tools/models.js +105 -0
  87. package/dist/tools/models.js.map +1 -0
  88. package/dist/tools/narratives.d.ts +82 -0
  89. package/dist/tools/narratives.d.ts.map +1 -0
  90. package/dist/tools/narratives.js +218 -0
  91. package/dist/tools/narratives.js.map +1 -0
  92. package/dist/tools/objects.d.ts +65 -0
  93. package/dist/tools/objects.d.ts.map +1 -0
  94. package/dist/tools/objects.js +157 -0
  95. package/dist/tools/objects.js.map +1 -0
  96. package/dist/tools/obsidian.d.ts +31 -0
  97. package/dist/tools/obsidian.d.ts.map +1 -0
  98. package/dist/tools/obsidian.js +167 -0
  99. package/dist/tools/obsidian.js.map +1 -0
  100. package/dist/tools/outcome.d.ts +21 -0
  101. package/dist/tools/outcome.d.ts.map +1 -0
  102. package/dist/tools/outcome.js +35 -0
  103. package/dist/tools/outcome.js.map +1 -0
  104. package/dist/tools/promote.d.ts +21 -0
  105. package/dist/tools/promote.d.ts.map +1 -0
  106. package/dist/tools/promote.js +31 -0
  107. package/dist/tools/promote.js.map +1 -0
  108. package/dist/tools/reflect.d.ts +27 -0
  109. package/dist/tools/reflect.d.ts.map +1 -0
  110. package/dist/tools/reflect.js +85 -0
  111. package/dist/tools/reflect.js.map +1 -0
  112. package/dist/tools/search.d.ts +27 -0
  113. package/dist/tools/search.d.ts.map +1 -0
  114. package/dist/tools/search.js +42 -0
  115. package/dist/tools/search.js.map +1 -0
  116. package/dist/tools/strategies.d.ts +43 -0
  117. package/dist/tools/strategies.d.ts.map +1 -0
  118. package/dist/tools/strategies.js +126 -0
  119. package/dist/tools/strategies.js.map +1 -0
  120. package/dist/tools/summary.d.ts +61 -0
  121. package/dist/tools/summary.d.ts.map +1 -0
  122. package/dist/tools/summary.js +124 -0
  123. package/dist/tools/summary.js.map +1 -0
  124. package/dist/tools/swarm.d.ts +71 -0
  125. package/dist/tools/swarm.d.ts.map +1 -0
  126. package/dist/tools/swarm.js +145 -0
  127. package/dist/tools/swarm.js.map +1 -0
  128. package/dist/tools/v4.d.ts +152 -0
  129. package/dist/tools/v4.d.ts.map +1 -0
  130. package/dist/tools/v4.js +348 -0
  131. package/dist/tools/v4.js.map +1 -0
  132. package/dist/tools/write.d.ts +30 -0
  133. package/dist/tools/write.d.ts.map +1 -0
  134. package/dist/tools/write.js +52 -0
  135. package/dist/tools/write.js.map +1 -0
  136. package/dist/types.d.ts +359 -0
  137. package/dist/types.d.ts.map +1 -0
  138. package/dist/types.js +2 -0
  139. package/dist/types.js.map +1 -0
  140. package/dist/zod-json-schema.d.ts +3 -0
  141. package/dist/zod-json-schema.d.ts.map +1 -0
  142. package/dist/zod-json-schema.js +52 -0
  143. package/dist/zod-json-schema.js.map +1 -0
  144. package/docs/claude-remote-oauth.md +26 -0
  145. package/docs/crypticpqc-auth-architecture.md +107 -0
  146. package/docs/crypticpqc-cross-domain-auth.md +194 -0
  147. package/docs/mcp-auth0-exchange-contract.md +75 -0
  148. package/docs/mcp-authorization-spec-alignment.md +29 -0
  149. package/docs/mcp-org-object-storage.md +55 -0
  150. package/docs/pqc-api-tenant-context-go.md +238 -0
  151. package/docs/pqc-db-mcp-tenant-context.md +15 -0
  152. package/docs/pqc-db-tenant-context-implementation.md +32 -0
  153. package/docs/standalone-distribution.md +92 -0
  154. package/package.json +52 -0
  155. 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"}