@nodusapi/mcp-server 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 (50) hide show
  1. package/IMPLEMENTATION_SUMMARY.md +210 -0
  2. package/LICENSE +21 -0
  3. package/NPM_TOKEN_GUIDE.md +58 -0
  4. package/PUBLISH_GUIDE.md +152 -0
  5. package/QUICKSTART.md +139 -0
  6. package/README.md +394 -0
  7. package/cursor-config.example.json +13 -0
  8. package/dist/client/nodus-client.d.ts +30 -0
  9. package/dist/client/nodus-client.d.ts.map +1 -0
  10. package/dist/client/nodus-client.js +121 -0
  11. package/dist/client/nodus-client.js.map +1 -0
  12. package/dist/client/types.d.ts +81 -0
  13. package/dist/client/types.d.ts.map +1 -0
  14. package/dist/client/types.js +2 -0
  15. package/dist/client/types.js.map +1 -0
  16. package/dist/config.d.ts +6 -0
  17. package/dist/config.d.ts.map +1 -0
  18. package/dist/config.js +75 -0
  19. package/dist/config.js.map +1 -0
  20. package/dist/index.d.ts +3 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +63 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/resources/schema-resources.d.ts +4 -0
  25. package/dist/resources/schema-resources.d.ts.map +1 -0
  26. package/dist/resources/schema-resources.js +113 -0
  27. package/dist/resources/schema-resources.js.map +1 -0
  28. package/dist/tools/data-tools.d.ts +4 -0
  29. package/dist/tools/data-tools.d.ts.map +1 -0
  30. package/dist/tools/data-tools.js +229 -0
  31. package/dist/tools/data-tools.js.map +1 -0
  32. package/dist/tools/project-tools.d.ts +4 -0
  33. package/dist/tools/project-tools.d.ts.map +1 -0
  34. package/dist/tools/project-tools.js +226 -0
  35. package/dist/tools/project-tools.js.map +1 -0
  36. package/dist/tools/schema-tools.d.ts +4 -0
  37. package/dist/tools/schema-tools.d.ts.map +1 -0
  38. package/dist/tools/schema-tools.js +274 -0
  39. package/dist/tools/schema-tools.js.map +1 -0
  40. package/dist/utils/auth.d.ts +5 -0
  41. package/dist/utils/auth.d.ts.map +1 -0
  42. package/dist/utils/auth.js +27 -0
  43. package/dist/utils/auth.js.map +1 -0
  44. package/dist/utils/validation.d.ts +168 -0
  45. package/dist/utils/validation.d.ts.map +1 -0
  46. package/dist/utils/validation.js +68 -0
  47. package/dist/utils/validation.js.map +1 -0
  48. package/docs/project-goal-mcp.md +129 -0
  49. package/docs/research/mcp-links.md +2 -0
  50. package/package.json +51 -0
package/README.md ADDED
@@ -0,0 +1,394 @@
1
+ # Nodus MCP Server
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@nodusapi/mcp-server.svg)](https://www.npmjs.com/package/@nodusapi/mcp-server)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Model Context Protocol (MCP) server for NodusAPI - Enable LLMs to interact directly with your Backend-as-a-Service platform.
7
+
8
+ ## Overview
9
+
10
+ Nodus MCP Server exposes your NodusAPI backend as MCP tools, allowing AI assistants like Claude to:
11
+
12
+ - Query and manipulate data in your tables
13
+ - Create and modify database schemas
14
+ - Manage projects and API keys
15
+ - Access table schemas as contextual resources
16
+
17
+ All through natural language conversations!
18
+
19
+ ## Features
20
+
21
+ - **Data CRUD Operations**: List, get, create, update, and delete rows
22
+ - **Schema Management**: Create tables, add columns, update schemas
23
+ - **Project Management**: List projects, create new projects, manage API keys
24
+ - **Automatic Context**: Table schemas are automatically available to the LLM
25
+ - **Secure Authentication**: API key-based authentication with multiple configuration options
26
+ - **TypeScript**: Fully typed with comprehensive error handling
27
+
28
+ ## Installation
29
+
30
+ ### Quick Start (npx)
31
+
32
+ The easiest way to use Nodus MCP Server is with npx:
33
+
34
+ ```bash
35
+ npx @nodusapi/mcp-server
36
+ ```
37
+
38
+ ### Global Installation
39
+
40
+ ```bash
41
+ npm install -g @nodusapi/mcp-server
42
+ ```
43
+
44
+ ### Local Development
45
+
46
+ ```bash
47
+ git clone https://github.com/yourusername/nodusmcp.git
48
+ cd nodusmcp
49
+ npm install
50
+ npm run build
51
+ ```
52
+
53
+ ## Configuration
54
+
55
+ ### Option 1: Environment Variables (Recommended for Cursor)
56
+
57
+ Set these environment variables in your MCP client configuration:
58
+
59
+ ```bash
60
+ NODUS_API_KEY=nds_your_api_key_here
61
+ NODUS_PROJECT_ID=your_project_uuid (optional)
62
+ NODUS_API_URL=https://api.nodus.com (optional, defaults to production)
63
+ ```
64
+
65
+ ### Option 2: Interactive Setup
66
+
67
+ If no configuration is found, the server will prompt you for:
68
+ - API Key
69
+ - API URL (defaults to https://api.nodus.com)
70
+ - Project ID (optional)
71
+
72
+ Configuration is saved to `~/.nodus-mcp/config.json` for future use.
73
+
74
+ ### Option 3: Manual Configuration
75
+
76
+ Create `~/.nodus-mcp/config.json`:
77
+
78
+ ```json
79
+ {
80
+ "apiKey": "nds_your_api_key_here",
81
+ "projectId": "your_project_uuid",
82
+ "apiUrl": "https://api.nodus.com"
83
+ }
84
+ ```
85
+
86
+ ## Cursor Integration
87
+
88
+ Add to your `.cursor/settings.json` or Cursor MCP settings:
89
+
90
+ ```json
91
+ {
92
+ "mcpServers": {
93
+ "nodus": {
94
+ "command": "npx",
95
+ "args": ["-y", "@nodusapi/mcp-server"],
96
+ "env": {
97
+ "NODUS_API_KEY": "nds_your_api_key_here",
98
+ "NODUS_PROJECT_ID": "your_project_id"
99
+ }
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ Or use a local path during development:
106
+
107
+ ```json
108
+ {
109
+ "mcpServers": {
110
+ "nodus": {
111
+ "command": "node",
112
+ "args": ["/absolute/path/to/nodusmcp/dist/index.js"],
113
+ "env": {
114
+ "NODUS_API_KEY": "nds_your_api_key_here"
115
+ }
116
+ }
117
+ }
118
+ }
119
+ ```
120
+
121
+ ## Available Tools
122
+
123
+ ### Data CRUD Tools
124
+
125
+ #### `list_rows`
126
+ List rows from a table with pagination and filtering.
127
+
128
+ **Parameters:**
129
+ - `tableSlug` (string, required): Table identifier
130
+ - `page` (number, optional): Page number (default: 1)
131
+ - `limit` (number, optional): Rows per page, max 100 (default: 20)
132
+ - `orderBy` (string, optional): Column to sort by
133
+ - `orderDir` (string, optional): Sort direction ('ASC' or 'DESC')
134
+ - `filters` (object, optional): Filter conditions (column: value pairs)
135
+
136
+ **Example:**
137
+ ```
138
+ "Show me the first 10 users ordered by created date"
139
+ ```
140
+
141
+ #### `get_row`
142
+ Get a single row by ID.
143
+
144
+ **Parameters:**
145
+ - `tableSlug` (string, required): Table identifier
146
+ - `id` (string, required): Row UUID
147
+
148
+ **Example:**
149
+ ```
150
+ "Get the user with ID 123e4567-e89b-12d3-a456-426614174000"
151
+ ```
152
+
153
+ #### `create_row`
154
+ Create a new row in a table.
155
+
156
+ **Parameters:**
157
+ - `tableSlug` (string, required): Table identifier
158
+ - `data` (object, required): Row data matching table schema
159
+
160
+ **Example:**
161
+ ```
162
+ "Create a new user with name 'John Doe' and email 'john@example.com'"
163
+ ```
164
+
165
+ #### `update_row`
166
+ Update an existing row.
167
+
168
+ **Parameters:**
169
+ - `tableSlug` (string, required): Table identifier
170
+ - `id` (string, required): Row UUID
171
+ - `data` (object, required): Partial row data to update
172
+
173
+ **Example:**
174
+ ```
175
+ "Update user 123... and set their status to 'active'"
176
+ ```
177
+
178
+ #### `delete_row`
179
+ Delete a row from a table.
180
+
181
+ **Parameters:**
182
+ - `tableSlug` (string, required): Table identifier
183
+ - `id` (string, required): Row UUID
184
+
185
+ **Example:**
186
+ ```
187
+ "Delete the row with ID 123... from users table"
188
+ ```
189
+
190
+ ### Schema Management Tools
191
+
192
+ #### `list_tables`
193
+ List all tables in the project.
194
+
195
+ **Example:**
196
+ ```
197
+ "Show me all my database tables"
198
+ ```
199
+
200
+ #### `get_table_schema`
201
+ Get detailed schema for a specific table.
202
+
203
+ **Parameters:**
204
+ - `tableSlug` (string, required): Table identifier
205
+
206
+ **Example:**
207
+ ```
208
+ "What columns does the users table have?"
209
+ ```
210
+
211
+ #### `create_table`
212
+ Create a new table.
213
+
214
+ **Parameters:**
215
+ - `name` (string, required): Human-readable table name
216
+ - `slug` (string, required): Table slug (lowercase, numbers, underscores only)
217
+
218
+ **Example:**
219
+ ```
220
+ "Create a new table called 'Products' with slug 'products'"
221
+ ```
222
+
223
+ #### `update_table`
224
+ Update table name.
225
+
226
+ **Parameters:**
227
+ - `tableSlug` (string, required): Current table slug
228
+ - `name` (string, required): New table name
229
+
230
+ #### `add_column`
231
+ Add a new column to a table.
232
+
233
+ **Parameters:**
234
+ - `tableSlug` (string, required): Table identifier
235
+ - `name` (string, required): Column name
236
+ - `slug` (string, required): Column slug
237
+ - `type` (string, required): Column type (string, text, integer, float, boolean, datetime, json)
238
+ - `isRequired` (boolean, optional): Whether column is required
239
+ - `defaultValue` (any, optional): Default value
240
+
241
+ **Example:**
242
+ ```
243
+ "Add a 'bio' column of type text to the users table"
244
+ ```
245
+
246
+ #### `update_column`
247
+ Update column properties.
248
+
249
+ **Parameters:**
250
+ - `tableSlug` (string, required): Table identifier
251
+ - `columnSlug` (string, required): Column identifier
252
+ - `name` (string, optional): New column name
253
+ - `isRequired` (boolean, optional): Required status
254
+ - `defaultValue` (any, optional): Default value
255
+
256
+ ### Project Management Tools
257
+
258
+ #### `list_projects`
259
+ List all projects for the authenticated user.
260
+
261
+ **Example:**
262
+ ```
263
+ "Show me my projects"
264
+ ```
265
+
266
+ #### `create_project`
267
+ Create a new project.
268
+
269
+ **Parameters:**
270
+ - `name` (string, required): Project name
271
+
272
+ **Example:**
273
+ ```
274
+ "Create a new project called 'My Blog API'"
275
+ ```
276
+
277
+ #### `switch_project`
278
+ Switch to a different project.
279
+
280
+ **Parameters:**
281
+ - `projectId` (string, required): Project UUID
282
+
283
+ #### `list_api_keys`
284
+ List API keys for a project.
285
+
286
+ **Parameters:**
287
+ - `projectId` (string, required): Project UUID
288
+
289
+ #### `create_api_key`
290
+ Create a new API key.
291
+
292
+ **Parameters:**
293
+ - `projectId` (string, required): Project UUID
294
+ - `name` (string, required): API key name
295
+
296
+ **Note:** The full API key is only shown once during creation!
297
+
298
+ ## Resources
299
+
300
+ ### `nodus://schemas/tables`
301
+ Automatically provides the LLM with information about all tables and their schemas in your project.
302
+
303
+ ## Usage Examples
304
+
305
+ ### Example Conversation
306
+
307
+ ```
308
+ User: "Show me all my database tables"
309
+ Assistant: [Calls list_tables tool]
310
+ "You have 3 tables: users, posts, and comments"
311
+
312
+ User: "What columns does the users table have?"
313
+ Assistant: [Calls get_table_schema with tableSlug: "users"]
314
+ "The users table has the following columns:
315
+ - id (string, required)
316
+ - name (string, required)
317
+ - email (string, required)
318
+ - bio (text, optional)
319
+ - created_at (datetime)"
320
+
321
+ User: "Create a new user named Alice with email alice@example.com"
322
+ Assistant: [Calls create_row with tableSlug: "users", data: {name: "Alice", email: "alice@example.com"}]
323
+ "Successfully created user Alice with ID abc-123..."
324
+
325
+ User: "List all users"
326
+ Assistant: [Calls list_rows with tableSlug: "users"]
327
+ "Found 5 users: Alice, Bob, Charlie, Diana, Eve"
328
+ ```
329
+
330
+ ## Security Notes
331
+
332
+ - **No Delete Operations**: Table and project deletion are NOT exposed through MCP for safety
333
+ - **API Key Security**: Store API keys securely using environment variables
334
+ - **Row-Level Operations**: Only individual row deletion is allowed (no bulk delete)
335
+ - **Validation**: All inputs are validated with Zod schemas
336
+
337
+ ## Development
338
+
339
+ ```bash
340
+ # Install dependencies
341
+ npm install
342
+
343
+ # Build
344
+ npm run build
345
+
346
+ # Development mode with auto-reload
347
+ npm run dev
348
+
349
+ # Run locally
350
+ npm start
351
+ ```
352
+
353
+ ## Troubleshooting
354
+
355
+ ### "Cannot connect to Nodus API"
356
+ - Check your API URL (default: https://api.nodus.com)
357
+ - Verify network connectivity
358
+
359
+ ### "Authentication failed"
360
+ - Verify your API key starts with `nds_`
361
+ - Generate a new API key from Nodus dashboard if needed
362
+
363
+ ### "Access denied"
364
+ - Ensure your API key has necessary permissions
365
+ - Check if you're using the correct project ID
366
+
367
+ ### "Resource not found"
368
+ - Verify table slug spelling
369
+ - Use `list_tables` to see available tables
370
+
371
+ ## Requirements
372
+
373
+ - Node.js >= 18.0.0
374
+ - NodusAPI account with valid API key
375
+
376
+ ## License
377
+
378
+ MIT
379
+
380
+ ## Contributing
381
+
382
+ Contributions are welcome! Please feel free to submit a Pull Request.
383
+
384
+ ## Support
385
+
386
+ - Documentation: https://docs.nodus.com
387
+ - Issues: https://github.com/nodusapi/nodusmcp/issues
388
+ - NodusAPI: https://nodus.com
389
+
390
+ ## Related Projects
391
+
392
+ - [NodusAPI](https://github.com/nodusapi/nodusapi) - Backend-as-a-Service platform
393
+ - [NodusWeb](https://github.com/nodusapi/nodusweb) - Web dashboard for NodusAPI
394
+ - [Model Context Protocol](https://modelcontextprotocol.io) - MCP specification
@@ -0,0 +1,13 @@
1
+ {
2
+ "mcpServers": {
3
+ "nodus": {
4
+ "command": "npx",
5
+ "args": ["-y", "@nodusapi/mcp-server"],
6
+ "env": {
7
+ "NODUS_API_KEY": "nds_your_api_key_here",
8
+ "NODUS_PROJECT_ID": "your_project_id_here",
9
+ "NODUS_API_URL": "https://api.nodus.com"
10
+ }
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,30 @@
1
+ import { Project, ApiKey, Table, TableWithColumns, DataRow, PaginatedResponse, QueryOptions, ColumnInput } from './types.js';
2
+ export declare class NodusClient {
3
+ private client;
4
+ private apiKey;
5
+ constructor(apiKey: string, baseURL?: string);
6
+ private request;
7
+ getProjects(): Promise<Project[]>;
8
+ createProject(name: string): Promise<Project>;
9
+ switchProject(projectId: string): Promise<{
10
+ project: Project;
11
+ token: string;
12
+ }>;
13
+ getApiKeys(projectId: string): Promise<ApiKey[]>;
14
+ createApiKey(projectId: string, name: string): Promise<{
15
+ apiKey: ApiKey;
16
+ fullKey: string;
17
+ }>;
18
+ getTables(): Promise<Table[]>;
19
+ getTable(tableSlug: string): Promise<TableWithColumns>;
20
+ createTable(name: string, slug: string): Promise<Table>;
21
+ updateTable(tableSlug: string, name: string): Promise<Table>;
22
+ addColumn(tableSlug: string, column: ColumnInput): Promise<TableWithColumns>;
23
+ updateColumn(tableSlug: string, columnSlug: string, updates: Partial<Omit<ColumnInput, 'slug' | 'type'>>): Promise<TableWithColumns>;
24
+ listRows(tableSlug: string, options?: QueryOptions): Promise<PaginatedResponse<DataRow>>;
25
+ getRow(tableSlug: string, id: string): Promise<DataRow>;
26
+ createRow(tableSlug: string, data: Record<string, any>): Promise<DataRow>;
27
+ updateRow(tableSlug: string, id: string, data: Record<string, any>): Promise<DataRow>;
28
+ deleteRow(tableSlug: string, id: string): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=nodus-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodus-client.d.ts","sourceRoot":"","sources":["../../src/client/nodus-client.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,OAAO,EACP,MAAM,EACN,KAAK,EACL,gBAAgB,EAChB,OAAO,EACP,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,MAAgC;YAYvD,OAAO;IA0Cf,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIjC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI7C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAO9E,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIhD,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAQ3F,SAAS,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAI7B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAItD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAIvD,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAI5D,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAQ5E,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,GACnD,OAAO,CAAC,gBAAgB,CAAC;IAQtB,QAAQ,CACZ,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IA6BhC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvD,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAIzE,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrF,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG9D"}
@@ -0,0 +1,121 @@
1
+ import axios from 'axios';
2
+ export class NodusClient {
3
+ client;
4
+ apiKey;
5
+ constructor(apiKey, baseURL = 'https://api.nodus.com') {
6
+ this.apiKey = apiKey;
7
+ this.client = axios.create({
8
+ baseURL,
9
+ headers: {
10
+ 'X-API-Key': apiKey,
11
+ 'Content-Type': 'application/json',
12
+ },
13
+ timeout: 30000,
14
+ });
15
+ }
16
+ async request(method, url, data, params) {
17
+ try {
18
+ const response = await this.client.request({
19
+ method,
20
+ url,
21
+ data,
22
+ params,
23
+ });
24
+ if (!response.data.success) {
25
+ throw new Error(response.data.error?.message || 'API request failed');
26
+ }
27
+ return response.data.data;
28
+ }
29
+ catch (error) {
30
+ if (axios.isAxiosError(error)) {
31
+ const axiosError = error;
32
+ if (axiosError.response?.data?.error) {
33
+ throw new Error(`API Error: ${axiosError.response.data.error.message}`);
34
+ }
35
+ if (axiosError.code === 'ECONNREFUSED') {
36
+ throw new Error('Cannot connect to Nodus API. Please check your API URL.');
37
+ }
38
+ if (axiosError.response?.status === 401) {
39
+ throw new Error('Authentication failed. Please check your API key.');
40
+ }
41
+ if (axiosError.response?.status === 403) {
42
+ throw new Error('Access denied. You do not have permission to perform this action.');
43
+ }
44
+ if (axiosError.response?.status === 404) {
45
+ throw new Error('Resource not found.');
46
+ }
47
+ }
48
+ throw error;
49
+ }
50
+ }
51
+ async getProjects() {
52
+ return this.request('get', '/api/v1/projects');
53
+ }
54
+ async createProject(name) {
55
+ return this.request('post', '/api/v1/projects', { name });
56
+ }
57
+ async switchProject(projectId) {
58
+ return this.request('post', `/api/v1/projects/${projectId}/switch`);
59
+ }
60
+ async getApiKeys(projectId) {
61
+ return this.request('get', `/api/v1/projects/${projectId}/api-keys`);
62
+ }
63
+ async createApiKey(projectId, name) {
64
+ return this.request('post', `/api/v1/projects/${projectId}/api-keys`, { name });
65
+ }
66
+ async getTables() {
67
+ return this.request('get', '/api/v1/schemas/tables');
68
+ }
69
+ async getTable(tableSlug) {
70
+ return this.request('get', `/api/v1/schemas/tables/${tableSlug}`);
71
+ }
72
+ async createTable(name, slug) {
73
+ return this.request('post', '/api/v1/schemas/tables', { name, slug });
74
+ }
75
+ async updateTable(tableSlug, name) {
76
+ return this.request('put', `/api/v1/schemas/tables/${tableSlug}`, { name });
77
+ }
78
+ async addColumn(tableSlug, column) {
79
+ return this.request('post', `/api/v1/schemas/tables/${tableSlug}/columns`, column);
80
+ }
81
+ async updateColumn(tableSlug, columnSlug, updates) {
82
+ return this.request('put', `/api/v1/schemas/tables/${tableSlug}/columns/${columnSlug}`, updates);
83
+ }
84
+ async listRows(tableSlug, options) {
85
+ const params = {};
86
+ if (options?.page)
87
+ params.page = options.page;
88
+ if (options?.limit)
89
+ params.limit = options.limit;
90
+ if (options?.orderBy)
91
+ params.orderBy = options.orderBy;
92
+ if (options?.orderDir)
93
+ params.orderDir = options.orderDir;
94
+ if (options?.filters) {
95
+ Object.entries(options.filters).forEach(([key, value]) => {
96
+ params[key] = value;
97
+ });
98
+ }
99
+ const response = await this.client.get(`/api/v1/data/${tableSlug}`, { params });
100
+ if (!response.data.success) {
101
+ throw new Error(response.data.error?.message || 'Failed to fetch rows');
102
+ }
103
+ return {
104
+ data: response.data.data || [],
105
+ meta: response.data.meta || { page: 1, limit: 20, total: 0, totalPages: 0 },
106
+ };
107
+ }
108
+ async getRow(tableSlug, id) {
109
+ return this.request('get', `/api/v1/data/${tableSlug}/${id}`);
110
+ }
111
+ async createRow(tableSlug, data) {
112
+ return this.request('post', `/api/v1/data/${tableSlug}`, data);
113
+ }
114
+ async updateRow(tableSlug, id, data) {
115
+ return this.request('put', `/api/v1/data/${tableSlug}/${id}`, data);
116
+ }
117
+ async deleteRow(tableSlug, id) {
118
+ return this.request('delete', `/api/v1/data/${tableSlug}/${id}`);
119
+ }
120
+ }
121
+ //# sourceMappingURL=nodus-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodus-client.js","sourceRoot":"","sources":["../../src/client/nodus-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ export interface NodusConfig {
2
+ apiKey: string;
3
+ projectId?: string;
4
+ apiUrl: string;
5
+ }
6
+ export interface Project {
7
+ id: string;
8
+ name: string;
9
+ slug: string;
10
+ userId: string;
11
+ createdAt: string;
12
+ updatedAt: string;
13
+ }
14
+ export interface ApiKey {
15
+ id: string;
16
+ projectId: string;
17
+ name: string;
18
+ prefix: string;
19
+ createdAt: string;
20
+ lastUsedAt: string | null;
21
+ }
22
+ export interface Table {
23
+ id: string;
24
+ projectId: string;
25
+ name: string;
26
+ slug: string;
27
+ createdAt: string;
28
+ updatedAt: string;
29
+ rowCount?: number;
30
+ }
31
+ export interface Column {
32
+ id: string;
33
+ tableId: string;
34
+ name: string;
35
+ slug: string;
36
+ type: 'string' | 'text' | 'integer' | 'float' | 'boolean' | 'datetime' | 'json';
37
+ isRequired: boolean;
38
+ defaultValue: any;
39
+ createdAt: string;
40
+ updatedAt: string;
41
+ }
42
+ export interface TableWithColumns extends Table {
43
+ columns: Column[];
44
+ }
45
+ export interface DataRow {
46
+ id: string;
47
+ [key: string]: any;
48
+ }
49
+ export interface PaginatedResponse<T> {
50
+ data: T[];
51
+ meta: {
52
+ page: number;
53
+ limit: number;
54
+ total: number;
55
+ totalPages: number;
56
+ };
57
+ }
58
+ export interface ApiResponse<T = any> {
59
+ success: boolean;
60
+ data?: T;
61
+ meta?: any;
62
+ error?: {
63
+ code: string;
64
+ message: string;
65
+ };
66
+ }
67
+ export interface QueryOptions {
68
+ page?: number;
69
+ limit?: number;
70
+ orderBy?: string;
71
+ orderDir?: 'ASC' | 'DESC';
72
+ filters?: Record<string, any>;
73
+ }
74
+ export interface ColumnInput {
75
+ name: string;
76
+ slug: string;
77
+ type: 'string' | 'text' | 'integer' | 'float' | 'boolean' | 'datetime' | 'json';
78
+ isRequired?: boolean;
79
+ defaultValue?: any;
80
+ }
81
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { NodusConfig } from './client/types.js';
2
+ export declare function loadConfig(): Promise<NodusConfig | null>;
3
+ export declare function saveConfig(config: NodusConfig): Promise<void>;
4
+ export declare function getConfig(): Promise<NodusConfig>;
5
+ export declare function promptForConfig(): Promise<NodusConfig>;
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKhD,wBAAsB,UAAU,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAO9D;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAOnE;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,CAqBtD;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,CAuC5D"}