@nestcorehq/mcp-server 0.0.0-stage → 1.6.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 (240) hide show
  1. package/.env.example +26 -0
  2. package/.mcp.json +3 -0
  3. package/README.md +500 -2
  4. package/dist/auth/credentials.service.d.ts +12 -0
  5. package/dist/auth/credentials.service.d.ts.map +1 -0
  6. package/dist/auth/credentials.service.js +120 -0
  7. package/dist/auth/credentials.service.js.map +1 -0
  8. package/dist/auth/oauth-login.d.ts +25 -0
  9. package/dist/auth/oauth-login.d.ts.map +1 -0
  10. package/dist/auth/oauth-login.js +146 -0
  11. package/dist/auth/oauth-login.js.map +1 -0
  12. package/dist/auth/session.service.d.ts +20 -0
  13. package/dist/auth/session.service.d.ts.map +1 -0
  14. package/dist/auth/session.service.js +185 -0
  15. package/dist/auth/session.service.js.map +1 -0
  16. package/dist/auth/token.service.d.ts +5 -0
  17. package/dist/auth/token.service.d.ts.map +1 -0
  18. package/dist/auth/token.service.js +31 -0
  19. package/dist/auth/token.service.js.map +1 -0
  20. package/dist/config.d.ts +8 -0
  21. package/dist/config.d.ts.map +1 -0
  22. package/dist/config.js +45 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/context/project.service.d.ts +8 -0
  25. package/dist/context/project.service.d.ts.map +1 -0
  26. package/dist/context/project.service.js +20 -0
  27. package/dist/context/project.service.js.map +1 -0
  28. package/dist/context/schema.service.d.ts +12 -0
  29. package/dist/context/schema.service.d.ts.map +1 -0
  30. package/dist/context/schema.service.js +45 -0
  31. package/dist/context/schema.service.js.map +1 -0
  32. package/dist/context/session-tracker.d.ts +32 -0
  33. package/dist/context/session-tracker.d.ts.map +1 -0
  34. package/dist/context/session-tracker.js +55 -0
  35. package/dist/context/session-tracker.js.map +1 -0
  36. package/dist/context/workspace.service.d.ts +15 -0
  37. package/dist/context/workspace.service.d.ts.map +1 -0
  38. package/dist/context/workspace.service.js +74 -0
  39. package/dist/context/workspace.service.js.map +1 -0
  40. package/dist/index.d.ts +3 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +57 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/legacy-tool-names.d.ts +16 -0
  45. package/dist/legacy-tool-names.d.ts.map +1 -0
  46. package/dist/legacy-tool-names.js +38 -0
  47. package/dist/legacy-tool-names.js.map +1 -0
  48. package/dist/migrations/index.d.ts +11 -0
  49. package/dist/migrations/index.d.ts.map +1 -0
  50. package/dist/migrations/index.js +18 -0
  51. package/dist/migrations/index.js.map +1 -0
  52. package/dist/migrations/migrationExecutor.d.ts +12 -0
  53. package/dist/migrations/migrationExecutor.d.ts.map +1 -0
  54. package/dist/migrations/migrationExecutor.js +25 -0
  55. package/dist/migrations/migrationExecutor.js.map +1 -0
  56. package/dist/migrations/migrationRegistry.d.ts +12 -0
  57. package/dist/migrations/migrationRegistry.d.ts.map +1 -0
  58. package/dist/migrations/migrationRegistry.js +57 -0
  59. package/dist/migrations/migrationRegistry.js.map +1 -0
  60. package/dist/migrations/migrationRunner.d.ts +30 -0
  61. package/dist/migrations/migrationRunner.d.ts.map +1 -0
  62. package/dist/migrations/migrationRunner.js +104 -0
  63. package/dist/migrations/migrationRunner.js.map +1 -0
  64. package/dist/migrations/migrationScanner.d.ts +10 -0
  65. package/dist/migrations/migrationScanner.d.ts.map +1 -0
  66. package/dist/migrations/migrationScanner.js +66 -0
  67. package/dist/migrations/migrationScanner.js.map +1 -0
  68. package/dist/migrations/types.d.ts +67 -0
  69. package/dist/migrations/types.d.ts.map +1 -0
  70. package/dist/migrations/types.js +13 -0
  71. package/dist/migrations/types.js.map +1 -0
  72. package/dist/prompts/project-intelligence.prompts.d.ts +4 -0
  73. package/dist/prompts/project-intelligence.prompts.d.ts.map +1 -0
  74. package/dist/prompts/project-intelligence.prompts.js +66 -0
  75. package/dist/prompts/project-intelligence.prompts.js.map +1 -0
  76. package/dist/safety/auth-table.guard.d.ts +6 -0
  77. package/dist/safety/auth-table.guard.d.ts.map +1 -0
  78. package/dist/safety/auth-table.guard.js +56 -0
  79. package/dist/safety/auth-table.guard.js.map +1 -0
  80. package/dist/safety/operation.guard.d.ts +5 -0
  81. package/dist/safety/operation.guard.d.ts.map +1 -0
  82. package/dist/safety/operation.guard.js +26 -0
  83. package/dist/safety/operation.guard.js.map +1 -0
  84. package/dist/safety/sql.guard.d.ts +17 -0
  85. package/dist/safety/sql.guard.d.ts.map +1 -0
  86. package/dist/safety/sql.guard.js +82 -0
  87. package/dist/safety/sql.guard.js.map +1 -0
  88. package/dist/sdk/endpoints.d.ts +179 -0
  89. package/dist/sdk/endpoints.d.ts.map +1 -0
  90. package/dist/sdk/endpoints.js +214 -0
  91. package/dist/sdk/endpoints.js.map +1 -0
  92. package/dist/sdk/nestcore.client.d.ts +437 -0
  93. package/dist/sdk/nestcore.client.d.ts.map +1 -0
  94. package/dist/sdk/nestcore.client.js +855 -0
  95. package/dist/sdk/nestcore.client.js.map +1 -0
  96. package/dist/server.d.ts +18 -0
  97. package/dist/server.d.ts.map +1 -0
  98. package/dist/server.js +190 -0
  99. package/dist/server.js.map +1 -0
  100. package/dist/tools/admin.tools.d.ts +4 -0
  101. package/dist/tools/admin.tools.d.ts.map +1 -0
  102. package/dist/tools/admin.tools.js +137 -0
  103. package/dist/tools/admin.tools.js.map +1 -0
  104. package/dist/tools/analytics.tools.d.ts +4 -0
  105. package/dist/tools/analytics.tools.d.ts.map +1 -0
  106. package/dist/tools/analytics.tools.js +265 -0
  107. package/dist/tools/analytics.tools.js.map +1 -0
  108. package/dist/tools/auth.tools.d.ts +4 -0
  109. package/dist/tools/auth.tools.d.ts.map +1 -0
  110. package/dist/tools/auth.tools.js +201 -0
  111. package/dist/tools/auth.tools.js.map +1 -0
  112. package/dist/tools/background-jobs.tools.d.ts +4 -0
  113. package/dist/tools/background-jobs.tools.d.ts.map +1 -0
  114. package/dist/tools/background-jobs.tools.js +197 -0
  115. package/dist/tools/background-jobs.tools.js.map +1 -0
  116. package/dist/tools/dashboard.tools.d.ts +4 -0
  117. package/dist/tools/dashboard.tools.d.ts.map +1 -0
  118. package/dist/tools/dashboard.tools.js +36 -0
  119. package/dist/tools/dashboard.tools.js.map +1 -0
  120. package/dist/tools/database.tools.d.ts +4 -0
  121. package/dist/tools/database.tools.d.ts.map +1 -0
  122. package/dist/tools/database.tools.js +301 -0
  123. package/dist/tools/database.tools.js.map +1 -0
  124. package/dist/tools/function.tools.d.ts +4 -0
  125. package/dist/tools/function.tools.d.ts.map +1 -0
  126. package/dist/tools/function.tools.js +237 -0
  127. package/dist/tools/function.tools.js.map +1 -0
  128. package/dist/tools/index.d.ts +19 -0
  129. package/dist/tools/index.d.ts.map +1 -0
  130. package/dist/tools/index.js +37 -0
  131. package/dist/tools/index.js.map +1 -0
  132. package/dist/tools/integrations.tools.d.ts +4 -0
  133. package/dist/tools/integrations.tools.d.ts.map +1 -0
  134. package/dist/tools/integrations.tools.js +308 -0
  135. package/dist/tools/integrations.tools.js.map +1 -0
  136. package/dist/tools/logging.tools.d.ts +4 -0
  137. package/dist/tools/logging.tools.d.ts.map +1 -0
  138. package/dist/tools/logging.tools.js +105 -0
  139. package/dist/tools/logging.tools.js.map +1 -0
  140. package/dist/tools/migration.tools.d.ts +4 -0
  141. package/dist/tools/migration.tools.d.ts.map +1 -0
  142. package/dist/tools/migration.tools.js +106 -0
  143. package/dist/tools/migration.tools.js.map +1 -0
  144. package/dist/tools/project-intelligence.tools.d.ts +4 -0
  145. package/dist/tools/project-intelligence.tools.d.ts.map +1 -0
  146. package/dist/tools/project-intelligence.tools.js +436 -0
  147. package/dist/tools/project-intelligence.tools.js.map +1 -0
  148. package/dist/tools/project.tools.d.ts +4 -0
  149. package/dist/tools/project.tools.d.ts.map +1 -0
  150. package/dist/tools/project.tools.js +224 -0
  151. package/dist/tools/project.tools.js.map +1 -0
  152. package/dist/tools/realtime.tools.d.ts +4 -0
  153. package/dist/tools/realtime.tools.d.ts.map +1 -0
  154. package/dist/tools/realtime.tools.js +96 -0
  155. package/dist/tools/realtime.tools.js.map +1 -0
  156. package/dist/tools/rls.tools.d.ts +4 -0
  157. package/dist/tools/rls.tools.d.ts.map +1 -0
  158. package/dist/tools/rls.tools.js +143 -0
  159. package/dist/tools/rls.tools.js.map +1 -0
  160. package/dist/tools/smtp.tools.d.ts +4 -0
  161. package/dist/tools/smtp.tools.d.ts.map +1 -0
  162. package/dist/tools/smtp.tools.js +51 -0
  163. package/dist/tools/smtp.tools.js.map +1 -0
  164. package/dist/tools/storage.tools.d.ts +4 -0
  165. package/dist/tools/storage.tools.d.ts.map +1 -0
  166. package/dist/tools/storage.tools.js +221 -0
  167. package/dist/tools/storage.tools.js.map +1 -0
  168. package/dist/types/api.types.d.ts +144 -0
  169. package/dist/types/api.types.d.ts.map +1 -0
  170. package/dist/types/api.types.js +2 -0
  171. package/dist/types/api.types.js.map +1 -0
  172. package/dist/types/config.types.d.ts +13 -0
  173. package/dist/types/config.types.d.ts.map +1 -0
  174. package/dist/types/config.types.js +2 -0
  175. package/dist/types/config.types.js.map +1 -0
  176. package/dist/types/session.types.d.ts +95 -0
  177. package/dist/types/session.types.d.ts.map +1 -0
  178. package/dist/types/session.types.js +2 -0
  179. package/dist/types/session.types.js.map +1 -0
  180. package/dist/utils/errors.d.ts +28 -0
  181. package/dist/utils/errors.d.ts.map +1 -0
  182. package/dist/utils/errors.js +75 -0
  183. package/dist/utils/errors.js.map +1 -0
  184. package/dist/utils/logger.d.ts +8 -0
  185. package/dist/utils/logger.d.ts.map +1 -0
  186. package/dist/utils/logger.js +42 -0
  187. package/dist/utils/logger.js.map +1 -0
  188. package/dist/utils/validators.d.ts +4 -0
  189. package/dist/utils/validators.d.ts.map +1 -0
  190. package/dist/utils/validators.js +21 -0
  191. package/dist/utils/validators.js.map +1 -0
  192. package/package.json +52 -4
  193. package/src/auth/credentials.service.ts +104 -0
  194. package/src/auth/oauth-login.ts +189 -0
  195. package/src/auth/session.service.ts +211 -0
  196. package/src/auth/token.service.ts +28 -0
  197. package/src/config.ts +50 -0
  198. package/src/context/project.service.ts +24 -0
  199. package/src/context/schema.service.ts +55 -0
  200. package/src/context/session-tracker.ts +72 -0
  201. package/src/context/workspace.service.ts +78 -0
  202. package/src/index.ts +61 -0
  203. package/src/legacy-tool-names.ts +42 -0
  204. package/src/migrations/index.ts +21 -0
  205. package/src/migrations/migrationExecutor.ts +26 -0
  206. package/src/migrations/migrationRegistry.ts +75 -0
  207. package/src/migrations/migrationRunner.ts +128 -0
  208. package/src/migrations/migrationScanner.ts +77 -0
  209. package/src/migrations/types.ts +68 -0
  210. package/src/prompts/project-intelligence.prompts.ts +70 -0
  211. package/src/safety/auth-table.guard.ts +67 -0
  212. package/src/safety/operation.guard.ts +41 -0
  213. package/src/safety/sql.guard.ts +122 -0
  214. package/src/sdk/endpoints.ts +231 -0
  215. package/src/sdk/nestcore.client.ts +1028 -0
  216. package/src/server.ts +217 -0
  217. package/src/tools/admin.tools.ts +140 -0
  218. package/src/tools/analytics.tools.ts +267 -0
  219. package/src/tools/auth.tools.ts +205 -0
  220. package/src/tools/background-jobs.tools.ts +203 -0
  221. package/src/tools/dashboard.tools.ts +38 -0
  222. package/src/tools/database.tools.ts +306 -0
  223. package/src/tools/function.tools.ts +244 -0
  224. package/src/tools/index.ts +56 -0
  225. package/src/tools/integrations.tools.ts +314 -0
  226. package/src/tools/logging.tools.ts +109 -0
  227. package/src/tools/migration.tools.ts +116 -0
  228. package/src/tools/project-intelligence.tools.ts +453 -0
  229. package/src/tools/project.tools.ts +226 -0
  230. package/src/tools/realtime.tools.ts +102 -0
  231. package/src/tools/rls.tools.ts +145 -0
  232. package/src/tools/smtp.tools.ts +53 -0
  233. package/src/tools/storage.tools.ts +224 -0
  234. package/src/types/api.types.ts +176 -0
  235. package/src/types/config.types.ts +12 -0
  236. package/src/types/session.types.ts +106 -0
  237. package/src/utils/errors.ts +85 -0
  238. package/src/utils/logger.ts +44 -0
  239. package/src/utils/validators.ts +25 -0
  240. package/tsconfig.json +20 -0
package/.env.example ADDED
@@ -0,0 +1,26 @@
1
+ # NestCore Backend Configuration
2
+ # NESTCORE_API_URL must point at the NestCore API whose console hosts the
3
+ # OAuth callback page — used by the nestcore_login (Google/GitHub/Apple) tool.
4
+ NESTCORE_API_URL=https://api.nestcore.io
5
+ NESTCORE_API_BASE_PATH=/api
6
+ # (The pre-rename ORBITNEST_API_URL / ORBITNEST_API_BASE_PATH are still read as fallbacks.)
7
+
8
+ # Authentication
9
+ # Sign in at runtime with nestcore_admin_signin (email + password) or
10
+ # nestcore_login (Google/GitHub/Apple via browser). Tokens are stored in
11
+ # ~/.nestcore/credentials.json — no token needs to be set here.
12
+
13
+ # MCP Server Configuration
14
+ MCP_SERVER_NAME=nestcore
15
+ LOG_LEVEL=info
16
+
17
+ # Workspace Configuration (optional, can be detected)
18
+ DEFAULT_PROJECT_ID=
19
+
20
+ # Safety Configuration
21
+ ENABLE_SQL_GUARD=true
22
+ BLOCK_AUTH_TABLE_MUTATIONS=true
23
+
24
+ # Cache Configuration
25
+ SCHEMA_CACHE_TTL=300000
26
+ TOKEN_REFRESH_THRESHOLD=60000
package/.mcp.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "mcpServers": {}
3
+ }
package/README.md CHANGED
@@ -1,3 +1,501 @@
1
- # Temporary Holding Version
1
+ # NestCore MCP Server
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for [NestCore](https://nestcore.io) that enables AI agents (Claude, etc.) to manage your NestCore projects, databases, edge functions, storage, and more through a structured tool interface.
4
+
5
+ ## Architecture
6
+
7
+ ```
8
+ Claude / AI Agent
9
+ ↓ MCP Protocol (stdio)
10
+ NestCore MCP Server ← this project
11
+ ↓ REST API + JWT
12
+ NestCore Backend (https://api.nestcore.io)
13
+ ↓
14
+ PostgreSQL / Storage / Edge Functions
15
+ ```
16
+
17
+ The MCP server **never accesses the database directly** — all operations are proxied through the NestCore backend API with full JWT authentication.
18
+
19
+ ---
20
+
21
+ ## Prerequisites
22
+
23
+ - **Node.js** v18 or later
24
+ - **npm** v9 or later
25
+ - Access to the GitHub repository `Orbitnest/nestcore_mcp` (or install `@nestcorehq/mcp-server` from npm)
26
+ - NestCore account — sign in at [nestcore.io](https://nestcore.io)
27
+
28
+ ---
29
+
30
+ ## Installation
31
+
32
+ ### Option A — Install directly from GitHub (recommended for new devices)
33
+
34
+ No cloning required. `npm install` downloads the package from GitHub and automatically compiles it via the `prepare` script.
35
+
36
+ ```bash
37
+ npm install -g github:Orbitnest/nestcore_mcp
38
+ ```
39
+
40
+ After installation the `nestcore-mcp` binary is available globally:
41
+
42
+ ```bash
43
+ nestcore-mcp # starts the MCP server
44
+ ```
45
+
46
+ The pre-rename `orbitnest-mcp` command is installed too and starts the same server.
47
+
48
+ To install a specific commit or tag:
49
+
50
+ ```bash
51
+ npm install -g github:Orbitnest/nestcore_mcp#v1.0.0
52
+ ```
53
+
54
+ > **Private repo?** Make sure the machine has GitHub access. Either:
55
+ > - SSH key added to the GitHub account (`git@github.com:...`), or
56
+ > - A [Personal Access Token](https://github.com/settings/tokens) with `repo` scope configured in `~/.npmrc`:
57
+ > ```
58
+ > //npm.pkg.github.com/:_authToken=YOUR_TOKEN
59
+ > ```
60
+
61
+ ---
62
+
63
+ ### Option B — Clone and build locally (for development)
64
+
65
+ ```bash
66
+ git clone https://github.com/Orbitnest/nestcore_mcp.git
67
+ cd nestcore_mcp
68
+ npm install # also runs `npm run build` automatically via prepare script
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Configuration
74
+
75
+ All settings are passed as environment variables. No `.env` file is required when configuring via an MCP client (see below) — simply set them in the `env` block of your MCP config.
76
+
77
+ For standalone use, copy the example file:
78
+
79
+ ```bash
80
+ cp .env.example .env
81
+ # then edit .env as needed
82
+ ```
83
+
84
+ | Variable | Default | Description |
85
+ |----------|---------|-------------|
86
+ | `NESTCORE_API_URL` | `https://api.nestcore.io` | NestCore backend URL (falls back to `ORBITNEST_API_URL`) |
87
+ | `NESTCORE_API_BASE_PATH` | `/api` | API base path (falls back to `ORBITNEST_API_BASE_PATH`) |
88
+ | `NESTCORE_MIGRATIONS_DIR` | `migrations` | Default migrations directory (falls back to `ORBITNEST_MIGRATIONS_DIR`) |
89
+ | `MCP_SERVER_NAME` | `nestcore` | MCP server identifier |
90
+ | `LOG_LEVEL` | `info` | Logging level: `debug`, `info`, `warn`, `error` |
91
+ | `DEFAULT_PROJECT_ID` | _(empty)_ | Auto-select project on startup |
92
+ | `ENABLE_SQL_GUARD` | `true` | Validate SQL before execution |
93
+ | `BLOCK_AUTH_TABLE_MUTATIONS` | `true` | Block writes to `auth_*` tables |
94
+ | `SCHEMA_CACHE_TTL` | `300000` | Schema cache lifetime in ms (5 min) |
95
+ | `TOKEN_REFRESH_THRESHOLD` | `60000` | Refresh token when < 60s from expiry |
96
+
97
+ ---
98
+
99
+ ## Connecting to Claude Code
100
+
101
+ ### Option 1 — Via GitHub (no local clone needed)
102
+
103
+ Add the server globally so it is available in any project. Claude Code will run it directly from the GitHub package:
104
+
105
+ ```bash
106
+ claude mcp add nestcore -- npx -y github:Orbitnest/nestcore_mcp
107
+ ```
108
+
109
+ Or edit `~/.claude.json` manually:
110
+
111
+ ```json
112
+ {
113
+ "mcpServers": {
114
+ "nestcore": {
115
+ "command": "npx",
116
+ "args": ["-y", "github:Orbitnest/nestcore_mcp"],
117
+ "env": {
118
+ "NESTCORE_API_URL": "https://api.nestcore.io"
119
+ }
120
+ }
121
+ }
122
+ }
123
+ ```
124
+
125
+ ### Option 2 — Via globally installed binary
126
+
127
+ If you installed with `npm install -g`:
128
+
129
+ ```bash
130
+ claude mcp add nestcore -- nestcore-mcp
131
+ ```
132
+
133
+ ### Option 3 — Project-level from local clone
134
+
135
+ The repository's `.mcp.json` is picked up automatically when you open this directory in Claude Code:
136
+
137
+ ```bash
138
+ npm run build # only needed the first time if prepare didn't run
139
+ ```
140
+
141
+ ### Verifying the connection
142
+
143
+ ```bash
144
+ claude mcp list
145
+ # Should show: nestcore connected
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Connecting to VSCode
151
+
152
+ The repository includes `.vscode/mcp.json` which is automatically picked up by the **GitHub Copilot / Claude VSCode extension** with MCP support enabled.
153
+
154
+ **Using a local clone (development):**
155
+
156
+ 1. Open this folder in VSCode
157
+ 2. The `nestcore` server entry in `.vscode/mcp.json` points to `dist/index.js` and starts automatically
158
+
159
+ **Using GitHub install on any other machine:**
160
+
161
+ 1. Create or edit `.vscode/mcp.json` in your project:
162
+
163
+ ```jsonc
164
+ {
165
+ "servers": {
166
+ "nestcore": {
167
+ "type": "stdio",
168
+ "command": "npx",
169
+ "args": ["-y", "github:Orbitnest/nestcore_mcp"],
170
+ "env": {
171
+ "NESTCORE_API_URL": "https://api.nestcore.io",
172
+ "LOG_LEVEL": "info",
173
+ "ENABLE_SQL_GUARD": "true",
174
+ "BLOCK_AUTH_TABLE_MUTATIONS": "true"
175
+ }
176
+ }
177
+ }
178
+ }
179
+ ```
180
+
181
+ 2. Reload the VSCode window (`Ctrl+Shift+P` → `Developer: Reload Window`) — the server starts automatically.
182
+
183
+ To point at a different backend URL, change `NESTCORE_API_URL` in the `env` block.
184
+
185
+ ---
186
+
187
+ ## First-Time Setup
188
+
189
+ Once connected via Claude Code or VSCode, authenticate and set your project context:
190
+
191
+ **1. Sign in as admin:**
192
+
193
+ If your account has a password:
194
+ ```
195
+ Use nestcore_admin_signin with:
196
+ email: "admin@example.com"
197
+ password: "your-password"
198
+ ```
199
+
200
+ If you signed up with **Google, GitHub, or Apple** (no password), use OAuth.
201
+ This opens your browser to complete sign-in and captures the session
202
+ automatically via a one-time localhost callback:
203
+ ```
204
+ Use nestcore_login with:
205
+ provider: "google" # or "github" / "apple"
206
+ ```
207
+
208
+ Credentials are saved to `~/.nestcore/credentials.json` and reloaded automatically on subsequent starts.
209
+
210
+ > `nestcore_login` opens a browser, so run it on the machine where the MCP
211
+ > server runs. It requires `NESTCORE_API_URL` to point at the NestCore API
212
+ > whose console hosts the OAuth callback page (default `https://api.nestcore.io`).
213
+
214
+ **2. List your projects:**
215
+ ```
216
+ Use nestcore_list_projects
217
+ ```
218
+
219
+ **3. Set active project:**
220
+ ```
221
+ Use nestcore_set_active_project with:
222
+ projectId: "proj_abc123"
223
+ ```
224
+
225
+ All subsequent tools automatically use the active project — you rarely need to specify `projectId` again.
226
+
227
+ ---
228
+
229
+ ## Available Tools
230
+
231
+ Every tool is named `nestcore_*`. Tools were called `orbitnest_*` before the
232
+ rename: `tools/list` only returns the new names, but a `tools/call` for an old
233
+ `orbitnest_*` name still runs the matching `nestcore_*` tool, so clients with a
234
+ cached tool list keep working.
235
+
236
+ ### Authentication (8 tools)
237
+ | Tool | Description |
238
+ |------|-------------|
239
+ | `nestcore_admin_signin` | Sign in with email + password and save JWT credentials |
240
+ | `nestcore_login` | Sign in with Google / GitHub / Apple via browser (for password-less accounts) |
241
+ | `nestcore_admin_signup` | Create a new admin account |
242
+ | `nestcore_admin_signup_verified` | Signup with email verification |
243
+ | `nestcore_request_verification` | Request verification code |
244
+ | `nestcore_refresh_token` | Manually refresh JWT token |
245
+ | `nestcore_admin_signout` | Sign out and clear saved credentials |
246
+ | `nestcore_get_profile` | Get current admin profile |
247
+
248
+ ### Projects (7 tools)
249
+ | Tool | Description |
250
+ |------|-------------|
251
+ | `nestcore_create_project` | Create project with dedicated database |
252
+ | `nestcore_list_projects` | List all projects |
253
+ | `nestcore_get_project` | Get project details |
254
+ | `nestcore_update_project` | Rename or update project settings |
255
+ | `nestcore_delete_project` | Delete project (requires `confirmDeletion: true`) |
256
+ | `nestcore_get_project_stats` | Get project statistics |
257
+ | `nestcore_get_project_health` | Check project health status |
258
+
259
+ ### Database (12 tools)
260
+ | Tool | Description |
261
+ |------|-------------|
262
+ | `nestcore_get_schema` | Fetch full database schema (cached 5 min) |
263
+ | `nestcore_execute_sql` | Execute raw SQL with safety validation |
264
+ | `nestcore_create_table` | Create a table from a structured definition |
265
+ | `nestcore_list_tables` | List all tables |
266
+ | `nestcore_get_table_data` | Query table data with pagination and filtering |
267
+ | `nestcore_insert_row` | Insert a single row |
268
+ | `nestcore_update_row` | Update a row by ID |
269
+ | `nestcore_delete_row` | Delete a row by ID |
270
+ | `nestcore_bulk_insert` | Insert multiple rows |
271
+ | `nestcore_bulk_update` | Update multiple rows |
272
+ | `nestcore_bulk_delete` | Delete multiple rows |
273
+ | `nestcore_get_sql_history` | Retrieve SQL query history |
274
+
275
+ ### Row-Level Security (6 tools)
276
+ | Tool | Description |
277
+ |------|-------------|
278
+ | `nestcore_get_rls_status` | Check RLS status on a table |
279
+ | `nestcore_enable_rls` | Enable RLS on a table |
280
+ | `nestcore_disable_rls` | Disable RLS on a table |
281
+ | `nestcore_list_policies` | List RLS policies |
282
+ | `nestcore_create_policy` | Create a new RLS policy |
283
+ | `nestcore_delete_policy` | Delete an RLS policy |
284
+
285
+ ### Edge Functions (7 tools)
286
+ | Tool | Description |
287
+ |------|-------------|
288
+ | `nestcore_create_function` | Create an edge function |
289
+ | `nestcore_list_functions` | List all functions |
290
+ | `nestcore_get_function` | Get function details |
291
+ | `nestcore_update_function` | Update function source code |
292
+ | `nestcore_delete_function` | Delete a function |
293
+ | `nestcore_invoke_function` | Execute a function |
294
+ | `nestcore_get_function_logs` | Get function execution logs |
295
+
296
+ > **Function environment:** inside a function, read env vars with `Deno.env.get('NAME')`. Available by default: `NESTCORE_URL`, `NESTCORE_ANON_KEY` (public/RLS-protected), `PROJECT_ID`, `PROJECT_URL`, `FUNCTION_NAME`, plus any project env vars you add. **`NESTCORE_SERVICE_ROLE_KEY` (RLS-bypassing) is NOT provided by default** — if a function needs privileged DB access, add it as a project env var (copy the service_role key from the dashboard → API Keys, or use `nestcore_create_env_variable`). See `docs/known-issues.md` §7.
297
+
298
+ ### Storage (9 tools)
299
+ | Tool | Description |
300
+ |------|-------------|
301
+ | `nestcore_list_buckets` | List storage buckets |
302
+ | `nestcore_create_bucket` | Create a new bucket |
303
+ | `nestcore_upload_file` | Upload a file to a bucket |
304
+ | `nestcore_download_file` | Download a file |
305
+ | `nestcore_list_files` | List files in a bucket |
306
+ | `nestcore_delete_files` | Delete files |
307
+ | `nestcore_delete_bucket` | Delete a bucket |
308
+ | `nestcore_get_bucket_size` | Get bucket storage usage |
309
+ | `nestcore_get_public_url` | Get a public file URL |
310
+
311
+ ### Logging (6 tools)
312
+ | Tool | Description |
313
+ |------|-------------|
314
+ | `nestcore_get_logs` | Get general logs with filtering |
315
+ | `nestcore_get_database_logs` | Get database operation logs |
316
+ | `nestcore_get_slow_query_logs` | Get slow query logs |
317
+ | `nestcore_get_auth_logs` | Get authentication logs |
318
+ | `nestcore_get_edge_function_logs` | Get edge function logs |
319
+ | `nestcore_export_logs` | Export logs in a specified format |
320
+
321
+ ### Admin Management (6 tools)
322
+ | Tool | Description |
323
+ |------|-------------|
324
+ | `nestcore_list_admins` | List all admin users |
325
+ | `nestcore_create_admin` | Create a new admin |
326
+ | `nestcore_get_admin` | Get admin details |
327
+ | `nestcore_update_admin` | Update admin settings |
328
+ | `nestcore_delete_admin` | Delete an admin user |
329
+ | `nestcore_update_admin_password` | Reset admin password |
330
+
331
+ ### SMTP (4 tools)
332
+ | Tool | Description |
333
+ |------|-------------|
334
+ | `nestcore_get_smtp_settings` | Get SMTP configuration |
335
+ | `nestcore_update_smtp_settings` | Update SMTP settings |
336
+ | `nestcore_delete_smtp_settings` | Remove SMTP configuration |
337
+ | `nestcore_test_smtp_connection` | Test SMTP connectivity |
338
+
339
+ ### Integrations (13 tools)
340
+ | Tool | Description |
341
+ |------|-------------|
342
+ | `nestcore_get_connection_string` | Get the direct Postgres connection string (when enabled) |
343
+ | `nestcore_get_auth_security` | End-user auth limits in force (code length, wrong codes, codes per hour, lockout) |
344
+ | `nestcore_set_auth_security` | Change those limits (admin) |
345
+ | `nestcore_get_ai_settings` | AI gateway keys (masked), default models and spend caps |
346
+ | `nestcore_ai_usage` | AI calls, tokens and cost per day, model and end user |
347
+ | `nestcore_list_webhooks` | List database webhooks |
348
+ | `nestcore_create_webhook` | Create a signed row-change webhook |
349
+ | `nestcore_delete_webhook` | Delete a webhook |
350
+ | `nestcore_test_webhook` | Send a test event to a webhook |
351
+ | `nestcore_get_sms_config` | Get the project's Twilio/SMS config |
352
+ | `nestcore_set_sms_config` | Configure Twilio (auth token stored encrypted) |
353
+ | `nestcore_test_sms` | Send a test SMS |
354
+ | `nestcore_enable_extension` | Enable a Postgres extension (e.g. `vector` for pgvector) |
355
+
356
+ ### AI data (6 tools)
357
+ | Tool | Description |
358
+ |------|-------------|
359
+ | `nestcore_ai_overview` | Counts of memories, subjects, collections, documents, threads, messages, traces (24 h) and embedded columns |
360
+ | `nestcore_list_collections` | Vector collections with model, chunking and document counts |
361
+ | `nestcore_memory_subjects` | Subjects that have memories (`user:<id>`, `agent:support`, ...) with counts |
362
+ | `nestcore_list_embeddings` | Automatically embedded columns with progress (rows, embedded, pending, failed, last error) |
363
+ | `nestcore_ai_traces` | Recent AI calls: model, tokens, cost, latency, status (never prompt text) |
364
+ | `nestcore_enable_embeddings` | Embed a table's text columns into a `vector(768)` column kept up to date (admin; requires `confirmEnable: true`) |
365
+
366
+ ### Dashboard (2 tools)
367
+ | Tool | Description |
368
+ |------|-------------|
369
+ | `nestcore_get_dashboard_stats` | Get overall statistics |
370
+ | `nestcore_get_dashboard_activity` | Get recent activity feed |
371
+
372
+ ---
373
+
374
+ ## Safety Features
375
+
376
+ ### SQL Guard
377
+ - Detects and blocks SQL injection patterns
378
+ - Requires `confirmDestructive: true` for `DROP`, `TRUNCATE`, `DELETE` without `WHERE`
379
+ - Blocks mutations on `auth_*` tables (configurable via `BLOCK_AUTH_TABLE_MUTATIONS`)
380
+
381
+ ### Operation Guard
382
+ - Bulk operations affecting more than 1,000 rows require explicit confirmation
383
+ - Project deletion always requires `confirmDeletion: true`
384
+ - RLS cannot be disabled on auth tables
385
+
386
+ ### Auth Table Protection
387
+ - Tables prefixed with `auth_` are read-only by default
388
+ - Schema changes and direct mutations are blocked
389
+
390
+ ---
391
+
392
+ ## Common Workflows
393
+
394
+ **Create a table with RLS:**
395
+ ```
396
+ nestcore_create_table({
397
+ tableName: "posts",
398
+ columns: [
399
+ { name: "id", type: "uuid", primaryKey: true, default: "gen_random_uuid()" },
400
+ { name: "title", type: "text", nullable: false },
401
+ { name: "body", type: "text" },
402
+ { name: "created_at", type: "timestamptz", default: "now()" }
403
+ ],
404
+ enableRLS: true
405
+ })
406
+ ```
407
+
408
+ **Execute a safe query:**
409
+ ```
410
+ nestcore_execute_sql({ sql: "SELECT * FROM posts ORDER BY created_at DESC LIMIT 10" })
411
+ ```
412
+
413
+ **Execute a destructive query (requires explicit confirmation):**
414
+ ```
415
+ nestcore_execute_sql({
416
+ sql: "DELETE FROM posts WHERE status = 'draft'",
417
+ confirmDestructive: true
418
+ })
419
+ ```
420
+
421
+ **Deploy an edge function:**
422
+ ```
423
+ nestcore_create_function({
424
+ name: "send-welcome",
425
+ sourceCode: "export default async (req) => { return new Response('Hello!'); }"
426
+ })
427
+ ```
428
+
429
+ ---
430
+
431
+ ## Development
432
+
433
+ ```bash
434
+ npm install # installs deps and runs `npm run build` automatically (prepare script)
435
+ npm run dev # TypeScript watch mode (tsx)
436
+ npm run build # Compile to dist/
437
+ npm start # Run compiled server
438
+ ```
439
+
440
+ Logs are written to **stderr** (MCP protocol uses stdout for communication), so they do not interfere with the MCP message stream.
441
+
442
+ ---
443
+
444
+ ## Workspace Auto-Detection
445
+
446
+ If your project root contains `.nestcore/config.json`, the MCP server automatically loads the project context on startup:
447
+
448
+ ```json
449
+ {
450
+ "projectId": "proj_abc123",
451
+ "projectSlug": "my-project",
452
+ "name": "My Project",
453
+ "apiUrl": "https://api.nestcore.io"
454
+ }
455
+ ```
456
+
457
+ This is the same file `nestcore link` (the CLI) writes; older CLI versions wrote `slug` instead of `projectSlug`, which is still read. A pre-rename `.orbitnest/config.json` is read when a directory has no `.nestcore/config.json`; saving the active project then writes `.nestcore/config.json`. `nestcore_set_active_project` updates this file when one was found, and never creates one elsewhere.
458
+
459
+ ---
460
+
461
+ ## Credentials Storage
462
+
463
+ After signing in, tokens are persisted to `~/.nestcore/credentials.json` (mode `0600`) and automatically reloaded on the next server start. If that file doesn't exist yet, the pre-rename `~/.orbitnest/credentials.json` is used (and kept in sync while it exists, so older CLI/MCP versions sharing it stay signed in). Tokens are refreshed automatically when they are within 60 seconds of expiry.
464
+
465
+ ---
466
+
467
+ ## Troubleshooting
468
+
469
+ **Server fails to start**
470
+ - If using a local clone, run `npm run build` — the `dist/` directory must exist
471
+ - Check that Node.js v18+ is installed: `node --version`
472
+ - If using `npx github:Orbitnest/nestcore_mcp`, ensure you have GitHub access (SSH key or token)
473
+
474
+ **`Not authenticated` errors**
475
+ - Run `nestcore_admin_signin` to sign in
476
+ - Credentials are stored in `~/.nestcore/credentials.json`
477
+
478
+ **`No active project` errors**
479
+ - Run `nestcore_list_projects` then `nestcore_set_active_project`
480
+ - Or set `DEFAULT_PROJECT_ID` in your environment / MCP `env` block
481
+
482
+ **MCP server not appearing in VSCode**
483
+ - Ensure MCP support is enabled in the extension settings
484
+ - Confirm `npm run build` has been run if using a local clone
485
+ - Reload the VSCode window (`Ctrl+Shift+P` → `Developer: Reload Window`)
486
+ - When using `npx github:...`, the first start may take a few seconds while npm downloads the package
487
+
488
+ **MCP server not appearing in Claude Code**
489
+ - Run `claude mcp list` to see registered servers
490
+ - Re-register: `claude mcp remove nestcore && claude mcp add nestcore -- npx -y github:Orbitnest/nestcore_mcp`
491
+ - If using project-level `.mcp.json`, ensure you opened Claude Code from this project directory
492
+
493
+ **GitHub access errors during npx install**
494
+ - Add your SSH key: `ssh-add ~/.ssh/id_rsa`
495
+ - Or create a GitHub Personal Access Token with `repo` scope and set it in `~/.npmrc`:
496
+
497
+ ---
498
+
499
+ ## License
500
+
501
+ MIT — NestCore Team
@@ -0,0 +1,12 @@
1
+ import type { StoredCredentials } from '../types/session.types.js';
2
+ export declare function loadCredentials(): StoredCredentials | null;
3
+ /**
4
+ * Merge into the existing file (keeps fields the CLI owns, e.g. `apiUrl`) and
5
+ * write atomically (temp file + rename) so a concurrent reader never sees a
6
+ * partial file.
7
+ */
8
+ export declare function saveCredentials(credentials: StoredCredentials): void;
9
+ /** Run `fn` while holding the cross-process credentials lock (shared with the CLI). */
10
+ export declare function withCredentialsLock<T>(fn: () => Promise<T>): Promise<T>;
11
+ export declare function clearCredentials(): void;
12
+ //# sourceMappingURL=credentials.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.service.d.ts","sourceRoot":"","sources":["../../src/auth/credentials.service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAYnE,wBAAgB,eAAe,IAAI,iBAAiB,GAAG,IAAI,CAa1D;AAgBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAapE;AAED,uFAAuF;AACvF,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAuB7E;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAYvC"}
@@ -0,0 +1,120 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as os from 'node:os';
4
+ import { logger } from '../utils/logger.js';
5
+ const CREDENTIALS_DIR = path.join(os.homedir(), '.nestcore');
6
+ const CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, 'credentials.json');
7
+ // Pre-rename location: read when the new file is absent, and kept in sync while it
8
+ // exists so an older CLI/MCP sharing it never replays a rotated refresh token.
9
+ const LEGACY_CREDENTIALS_FILE = path.join(os.homedir(), '.orbitnest', 'credentials.json');
10
+ // Advisory lock shared with the NestCore CLI — serialises refresh-token
11
+ // rotation across processes (the API revokes every session of the admin when a
12
+ // consumed refresh token is replayed).
13
+ const CREDENTIALS_LOCK = path.join(CREDENTIALS_DIR, 'credentials.lock');
14
+ export function loadCredentials() {
15
+ try {
16
+ const file = [CREDENTIALS_FILE, LEGACY_CREDENTIALS_FILE].find((f) => fs.existsSync(f));
17
+ if (!file) {
18
+ logger.debug('No credentials file found');
19
+ return null;
20
+ }
21
+ const raw = fs.readFileSync(file, 'utf-8');
22
+ return JSON.parse(raw);
23
+ }
24
+ catch (err) {
25
+ logger.warn('Failed to load credentials', { error: String(err) });
26
+ return null;
27
+ }
28
+ }
29
+ function writeAtomic(file, body) {
30
+ const tmp = `${file}.${process.pid}.tmp`;
31
+ fs.writeFileSync(tmp, body, { mode: 0o600 });
32
+ try {
33
+ fs.renameSync(tmp, file);
34
+ }
35
+ catch {
36
+ // Windows can refuse the rename while another process has the file open.
37
+ fs.writeFileSync(file, body, { mode: 0o600 });
38
+ try {
39
+ fs.unlinkSync(tmp);
40
+ }
41
+ catch { /* ignore */ }
42
+ }
43
+ // `mode` only applies on creation — tighten a pre-existing wider file too.
44
+ try {
45
+ fs.chmodSync(file, 0o600);
46
+ }
47
+ catch { /* no-op on Windows */ }
48
+ }
49
+ /**
50
+ * Merge into the existing file (keeps fields the CLI owns, e.g. `apiUrl`) and
51
+ * write atomically (temp file + rename) so a concurrent reader never sees a
52
+ * partial file.
53
+ */
54
+ export function saveCredentials(credentials) {
55
+ try {
56
+ fs.mkdirSync(CREDENTIALS_DIR, { recursive: true, mode: 0o700 });
57
+ const body = JSON.stringify({ ...(loadCredentials() ?? {}), ...credentials }, null, 2);
58
+ writeAtomic(CREDENTIALS_FILE, body);
59
+ if (fs.existsSync(LEGACY_CREDENTIALS_FILE)) {
60
+ try {
61
+ writeAtomic(LEGACY_CREDENTIALS_FILE, body);
62
+ }
63
+ catch { /* best-effort */ }
64
+ }
65
+ logger.info('Credentials saved');
66
+ }
67
+ catch (err) {
68
+ logger.error('Failed to save credentials', { error: String(err) });
69
+ throw err;
70
+ }
71
+ }
72
+ /** Run `fn` while holding the cross-process credentials lock (shared with the CLI). */
73
+ export async function withCredentialsLock(fn) {
74
+ fs.mkdirSync(CREDENTIALS_DIR, { recursive: true, mode: 0o700 });
75
+ const deadline = Date.now() + 90_000;
76
+ let fd;
77
+ while (fd === undefined) {
78
+ try {
79
+ fd = fs.openSync(CREDENTIALS_LOCK, 'wx');
80
+ }
81
+ catch (e) {
82
+ if (e.code !== 'EEXIST')
83
+ throw e;
84
+ // A holder that crashed leaves the lock behind; a refresh never takes 75s.
85
+ try {
86
+ if (Date.now() - fs.statSync(CREDENTIALS_LOCK).mtimeMs > 75_000)
87
+ fs.unlinkSync(CREDENTIALS_LOCK);
88
+ }
89
+ catch { /* raced with the holder */ }
90
+ if (Date.now() > deadline)
91
+ throw new Error(`Timed out waiting for ${CREDENTIALS_LOCK}`);
92
+ await new Promise((r) => setTimeout(r, 100));
93
+ }
94
+ }
95
+ try {
96
+ return await fn();
97
+ }
98
+ finally {
99
+ fs.closeSync(fd);
100
+ try {
101
+ fs.unlinkSync(CREDENTIALS_LOCK);
102
+ }
103
+ catch { /* ignore */ }
104
+ }
105
+ }
106
+ export function clearCredentials() {
107
+ try {
108
+ // Clear the pre-rename file too, or it would be read back as a fallback.
109
+ for (const file of [CREDENTIALS_FILE, LEGACY_CREDENTIALS_FILE]) {
110
+ if (fs.existsSync(file)) {
111
+ fs.unlinkSync(file);
112
+ logger.info('Credentials cleared', { file });
113
+ }
114
+ }
115
+ }
116
+ catch (err) {
117
+ logger.warn('Failed to clear credentials', { error: String(err) });
118
+ }
119
+ }
120
+ //# sourceMappingURL=credentials.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.service.js","sourceRoot":"","sources":["../../src/auth/credentials.service.ts"],"names":[],"mappings":"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"}