igniral-mcp-server 1.0.4

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 (46) hide show
  1. package/README.md +162 -0
  2. package/dist/api/TokenManager.d.ts +23 -0
  3. package/dist/api/TokenManager.d.ts.map +1 -0
  4. package/dist/api/TokenManager.js +82 -0
  5. package/dist/api/TokenManager.js.map +1 -0
  6. package/dist/api/igniral-client.d.ts +50 -0
  7. package/dist/api/igniral-client.d.ts.map +1 -0
  8. package/dist/api/igniral-client.js +116 -0
  9. package/dist/api/igniral-client.js.map +1 -0
  10. package/dist/config.d.ts +19 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +34 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/index.d.ts +17 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +181 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/tools/create-application.d.ts +20 -0
  19. package/dist/tools/create-application.d.ts.map +1 -0
  20. package/dist/tools/create-application.js +47 -0
  21. package/dist/tools/create-application.js.map +1 -0
  22. package/dist/tools/create-endpoint.d.ts +17 -0
  23. package/dist/tools/create-endpoint.d.ts.map +1 -0
  24. package/dist/tools/create-endpoint.js +49 -0
  25. package/dist/tools/create-endpoint.js.map +1 -0
  26. package/dist/tools/generate-schema.d.ts +25 -0
  27. package/dist/tools/generate-schema.d.ts.map +1 -0
  28. package/dist/tools/generate-schema.js +142 -0
  29. package/dist/tools/generate-schema.js.map +1 -0
  30. package/dist/tools/list-applications.d.ts +19 -0
  31. package/dist/tools/list-applications.d.ts.map +1 -0
  32. package/dist/tools/list-applications.js +27 -0
  33. package/dist/tools/list-applications.js.map +1 -0
  34. package/dist/utils/error-handler.d.ts +22 -0
  35. package/dist/utils/error-handler.d.ts.map +1 -0
  36. package/dist/utils/error-handler.js +123 -0
  37. package/dist/utils/error-handler.js.map +1 -0
  38. package/dist/utils/response-wrapper.d.ts +25 -0
  39. package/dist/utils/response-wrapper.d.ts.map +1 -0
  40. package/dist/utils/response-wrapper.js +98 -0
  41. package/dist/utils/response-wrapper.js.map +1 -0
  42. package/dist/validation/schemas.d.ts +147 -0
  43. package/dist/validation/schemas.d.ts.map +1 -0
  44. package/dist/validation/schemas.js +81 -0
  45. package/dist/validation/schemas.js.map +1 -0
  46. package/package.json +53 -0
package/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # Igniral MCP Server
2
+
3
+ > **[Igniral](https://igniral.com)** — Production-Ready Backends with AI Speed
4
+
5
+ Model Context Protocol (MCP) server that bridges AI agents (Claude, Cursor, Antigravity, etc.) with [Igniral's](https://igniral.com) backend platform. Describe your API in plain English — Igniral generates the schema, CRUD endpoints, authentication, Swagger docs, and antivirus-protected file storage automatically.
6
+
7
+ ## What is Igniral?
8
+
9
+ [Igniral](https://igniral.com) lets you generate 100% of your API infrastructure with a simple prompt, or build manually using a Visual Schema Builder. Everything is production-ready from the start:
10
+
11
+ - 🤖 **AI-Powered Generation** — Describe your data model, get a complete REST API instantly
12
+ - 🔐 **Built-in Auth & RBAC** — JWT authentication with role-based access control, no auth code needed
13
+ - 📄 **Always-Sync Swagger** — OpenAPI docs update automatically with every change
14
+ - 🛡️ **Antivirus File Storage** — Every uploaded file is scanned by ClamAV before reaching your infrastructure
15
+ - 📊 **Real-time Analytics** — Monitor API usage, error rates, and traffic from your dashboard
16
+ - 🗄️ **Managed Database** — Automatic backups and replication, zero DBA required
17
+
18
+ **Get started for free** at [igniral.com](https://igniral.com) → [Start Now](https://auth.igniral.com/subscribe)
19
+
20
+ ## Prerequisites
21
+
22
+ 1. **Create an Igniral account** at [igniral.com](https://auth.igniral.com/subscribe) (free tier available)
23
+ 2. **Generate Agent API Keys** from the [Igniral Dashboard](https://auth.igniral.com/login) → Agent API Keys
24
+ 3. **Have Node.js ≥ 18** installed on your machine
25
+
26
+ > **Important:** This is an MCP server — it runs inside your AI-powered IDE (Claude Desktop, Cursor, Antigravity, etc.), not directly from the terminal. You configure it once in your IDE settings, and the IDE handles starting and stopping it automatically.
27
+
28
+ ## Quick Start
29
+
30
+ Choose your IDE and add the following configuration. Replace `agent-xxxxxxxxxxxx` and `your-client-secret` with your actual Agent API Key credentials.
31
+
32
+ ### Claude Desktop
33
+
34
+ Edit your `claude_desktop_config.json`:
35
+
36
+ ```json
37
+ {
38
+ "mcpServers": {
39
+ "igniral": {
40
+ "command": "npx",
41
+ "args": ["-y", "igniral-mcp-server"],
42
+ "env": {
43
+ "IGNIRAL_CLIENT_ID": "agent-xxxxxxxxxxxx",
44
+ "IGNIRAL_CLIENT_SECRET": "your-client-secret"
45
+ }
46
+ }
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### Cursor
52
+
53
+ Edit your `.cursor/mcp.json`:
54
+
55
+ ```json
56
+ {
57
+ "mcpServers": {
58
+ "igniral": {
59
+ "command": "npx",
60
+ "args": ["-y", "igniral-mcp-server"],
61
+ "env": {
62
+ "IGNIRAL_CLIENT_ID": "agent-xxxxxxxxxxxx",
63
+ "IGNIRAL_CLIENT_SECRET": "your-client-secret"
64
+ }
65
+ }
66
+ }
67
+ }
68
+ ```
69
+
70
+ ### Antigravity (Google)
71
+
72
+ Edit `~/.gemini/antigravity/mcp_config.json`:
73
+
74
+ ```json
75
+ {
76
+ "mcpServers": {
77
+ "igniral": {
78
+ "command": "npx",
79
+ "args": ["-y", "igniral-mcp-server"],
80
+ "env": {
81
+ "IGNIRAL_CLIENT_ID": "agent-xxxxxxxxxxxx",
82
+ "IGNIRAL_CLIENT_SECRET": "your-client-secret"
83
+ }
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ > **Note:** Antigravity may not inherit your shell's `PATH`. Use the absolute path to `node` (e.g., `/opt/homebrew/Cellar/node/25.9.0_2/bin/node`) if you get "executable not found" errors.
90
+
91
+ That's it! After saving the configuration and restarting your IDE, you can ask your AI agent things like:
92
+
93
+ - *"Build me a gym management API"*
94
+ - *"Create a REST API for a pet store with products, orders, and users"*
95
+ - *"List my existing Igniral applications"*
96
+
97
+ ## Tools
98
+
99
+ Once configured, the following tools are available to your AI agent:
100
+
101
+ | Tool | Description |
102
+ |------|-------------|
103
+ | `igniral_generate_schema_from_prompt` | Auto-generate a complete app from a natural language description |
104
+ | `igniral_create_application` | Create an empty application shell manually |
105
+ | `igniral_create_dynamic_endpoint` | Add API endpoints to an existing application |
106
+ | `igniral_list_applications` | List the user's existing applications |
107
+
108
+ ## Architecture
109
+
110
+ ```
111
+ AI Agent (Claude/Cursor)
112
+
113
+ ▼ (MCP Protocol - stdio)
114
+ ┌──────────────────────────┐
115
+ │ Igniral MCP Server │
116
+ │ ├─ TokenManager │ ← OAuth2 client_credentials
117
+ │ ├─ Zod Validation │
118
+ │ ├─ SSE Client │
119
+ │ └─ HTTP Client │
120
+ └────────────┬─────────────┘
121
+ │ (HTTP + JWT with sub=userId)
122
+ ┌───────┼───────┐
123
+ ▼ ▼ ▼
124
+ auth- ai-schema- json-elements
125
+ server builder microservice
126
+ (token) (auto-gen) (CRUD)
127
+ ```
128
+
129
+ ## Environment Variables
130
+
131
+ | Variable | Required | Description |
132
+ |----------|----------|-------------|
133
+ | `IGNIRAL_CLIENT_ID` | ✅ | Agent API Key client ID (from Dashboard) |
134
+ | `IGNIRAL_CLIENT_SECRET` | ✅ | Agent API Key client secret (shown once at creation) |
135
+ | `IGNIRAL_AUTH_URL` | ❌ | Auth server URL (default: `https://auth.igniral.com`) |
136
+ | `IGNIRAL_API_URL` | ❌ | API URL (default: `https://api.igniral.io`) |
137
+ | `IGNIRAL_AI_API_URL` | ❌ | AI API URL (default: `https://ai.igniral.com`) |
138
+
139
+ ## Development (from source)
140
+
141
+ Only needed if you want to contribute or modify the server:
142
+
143
+ ```bash
144
+ git clone https://github.com/igniral/igniral-mcp-server.git
145
+ cd igniral-mcp-server
146
+ npm install
147
+ cp .env.example .env # Edit with your credentials
148
+ npm run dev # Start in development mode
149
+ npm run inspect # Test with MCP Inspector
150
+ ```
151
+
152
+ ## Links
153
+
154
+ - 🌐 **Website:** [igniral.com](https://igniral.com)
155
+ - 📖 **Documentation:** [igniral.com/docs](https://igniral.com/docs)
156
+ - 💬 **Community:** [Discord](https://discord.gg/ZrMbjPJh8w)
157
+ - 📧 **Support:** [support@igniral.com](mailto:support@igniral.com)
158
+
159
+ ## License
160
+
161
+ MIT
162
+
@@ -0,0 +1,23 @@
1
+ import { IgniralConfig } from "../config.js";
2
+ export declare class TokenManager {
3
+ private config;
4
+ private accessToken;
5
+ private userId;
6
+ private expiresAt;
7
+ private isFetching;
8
+ private fetchPromise;
9
+ constructor(config: IgniralConfig);
10
+ getToken(): Promise<string>;
11
+ /**
12
+ * Returns the user ID (sub claim) from the cached JWT.
13
+ * Must be called after getToken().
14
+ */
15
+ getUserId(): string | null;
16
+ private fetchNewToken;
17
+ /**
18
+ * Decode the JWT payload (base64url) to extract the 'sub' claim.
19
+ * No signature verification — the backend already validates the token.
20
+ */
21
+ private extractSubFromJwt;
22
+ }
23
+ //# sourceMappingURL=TokenManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenManager.d.ts","sourceRoot":"","sources":["../../src/api/TokenManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAa7C,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,YAAY,CAAgC;gBAExC,MAAM,EAAE,aAAa;IAI3B,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAoBjC;;;OAGG;IACH,SAAS,IAAI,MAAM,GAAG,IAAI;YAIZ,aAAa;IAqC3B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;CAU1B"}
@@ -0,0 +1,82 @@
1
+ export class TokenManager {
2
+ config;
3
+ accessToken = null;
4
+ userId = null;
5
+ expiresAt = 0;
6
+ isFetching = false;
7
+ fetchPromise = null;
8
+ constructor(config) {
9
+ this.config = config;
10
+ }
11
+ async getToken() {
12
+ // Return cached token if valid (with 30 seconds buffer)
13
+ if (this.accessToken && Date.now() < this.expiresAt - 30000) {
14
+ return this.accessToken;
15
+ }
16
+ // If already fetching, wait for the existing promise
17
+ if (this.isFetching && this.fetchPromise) {
18
+ return this.fetchPromise;
19
+ }
20
+ this.isFetching = true;
21
+ this.fetchPromise = this.fetchNewToken().finally(() => {
22
+ this.isFetching = false;
23
+ this.fetchPromise = null;
24
+ });
25
+ return this.fetchPromise;
26
+ }
27
+ /**
28
+ * Returns the user ID (sub claim) from the cached JWT.
29
+ * Must be called after getToken().
30
+ */
31
+ getUserId() {
32
+ return this.userId;
33
+ }
34
+ async fetchNewToken() {
35
+ const tokenUrl = `${this.config.authUrl}/oauth2/token`;
36
+ const basicAuth = Buffer.from(`${this.config.clientId}:${this.config.clientSecret}`).toString('base64');
37
+ const params = new URLSearchParams();
38
+ params.append('grant_type', 'client_credentials');
39
+ params.append('scope', 'ai:generate');
40
+ try {
41
+ const response = await fetch(tokenUrl, {
42
+ method: 'POST',
43
+ headers: {
44
+ 'Authorization': `Basic ${basicAuth}`,
45
+ 'Content-Type': 'application/x-www-form-urlencoded'
46
+ },
47
+ body: params
48
+ });
49
+ if (!response.ok) {
50
+ const errText = await response.text();
51
+ throw new Error(`Failed to fetch Agent API token: HTTP ${response.status} - ${errText}`);
52
+ }
53
+ const data = await response.json();
54
+ this.accessToken = data.access_token;
55
+ // expires_in is in seconds, convert to absolute ms timestamp
56
+ this.expiresAt = Date.now() + (data.expires_in * 1000);
57
+ // Decode JWT payload to extract sub (userId)
58
+ this.userId = this.extractSubFromJwt(data.access_token);
59
+ return this.accessToken;
60
+ }
61
+ catch (err) {
62
+ throw err;
63
+ }
64
+ }
65
+ /**
66
+ * Decode the JWT payload (base64url) to extract the 'sub' claim.
67
+ * No signature verification — the backend already validates the token.
68
+ */
69
+ extractSubFromJwt(token) {
70
+ try {
71
+ const parts = token.split('.');
72
+ if (parts.length !== 3)
73
+ return null;
74
+ const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString());
75
+ return payload.sub ?? null;
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=TokenManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenManager.js","sourceRoot":"","sources":["../../src/api/TokenManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { IgniralConfig } from "../config.js";
2
+ export interface ApiResponse<T = unknown> {
3
+ ok: boolean;
4
+ status: number;
5
+ data?: T;
6
+ error?: string;
7
+ }
8
+ /**
9
+ * HTTP client that handles authentication and error normalization
10
+ * for all Igniral backend calls.
11
+ */
12
+ export declare class IgniralClient {
13
+ private config;
14
+ private tokenManager;
15
+ constructor(config: IgniralConfig);
16
+ /**
17
+ * Common headers for all requests.
18
+ * Includes Authorization (Bearer token) and X-Acting-User (from JWT sub).
19
+ */
20
+ private getHeaders;
21
+ /**
22
+ * POST request to the JSON Elements microservice.
23
+ * Used by Tools 2, 3, and 4.
24
+ */
25
+ postToApi<T = unknown>(path: string, body: Record<string, unknown>, extraHeaders?: Record<string, string>): Promise<ApiResponse<T>>;
26
+ /**
27
+ * GET request to the JSON Elements microservice.
28
+ * Used by Tool 4 (list applications).
29
+ */
30
+ getFromApi<T = unknown>(path: string, extraHeaders?: Record<string, string>): Promise<ApiResponse<T>>;
31
+ /**
32
+ * POST request to the AI Schema Builder microservice.
33
+ * Used by Tool 1 (generate schema from prompt).
34
+ */
35
+ postToAiApi<T = unknown>(path: string, body: Record<string, unknown>): Promise<ApiResponse<T>>;
36
+ /**
37
+ * Returns the SSE subscription URL for generation events.
38
+ * Used by Tool 1 to listen for async generation progress.
39
+ */
40
+ getSseUrl(): string;
41
+ /**
42
+ * Returns the common headers needed for SSE connections.
43
+ */
44
+ getSseHeaders(): Promise<Record<string, string>>;
45
+ /**
46
+ * Internal fetch wrapper with error normalization.
47
+ */
48
+ private doFetch;
49
+ }
50
+ //# sourceMappingURL=igniral-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"igniral-client.d.ts","sourceRoot":"","sources":["../../src/api/igniral-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,YAAY,CAAe;gBAEvB,MAAM,EAAE,aAAa;IAKjC;;;OAGG;YACW,UAAU;IAaxB;;;OAGG;IACG,SAAS,CAAC,CAAC,GAAG,OAAO,EACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAK1B;;;OAGG;IACG,UAAU,CAAC,CAAC,GAAG,OAAO,EAC1B,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAK1B;;;OAGG;IACG,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAK1B;;;OAGG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAItD;;OAEG;YACW,OAAO;CAyDtB"}
@@ -0,0 +1,116 @@
1
+ import { TokenManager } from "./TokenManager.js";
2
+ /**
3
+ * HTTP client that handles authentication and error normalization
4
+ * for all Igniral backend calls.
5
+ */
6
+ export class IgniralClient {
7
+ config;
8
+ tokenManager;
9
+ constructor(config) {
10
+ this.config = config;
11
+ this.tokenManager = new TokenManager(config);
12
+ }
13
+ /**
14
+ * Common headers for all requests.
15
+ * Includes Authorization (Bearer token) and X-Acting-User (from JWT sub).
16
+ */
17
+ async getHeaders() {
18
+ const token = await this.tokenManager.getToken();
19
+ const userId = this.tokenManager.getUserId();
20
+ const headers = {
21
+ Authorization: `Bearer ${token}`,
22
+ "Content-Type": "application/json",
23
+ };
24
+ if (userId) {
25
+ headers["X-Acting-User"] = userId;
26
+ }
27
+ return headers;
28
+ }
29
+ /**
30
+ * POST request to the JSON Elements microservice.
31
+ * Used by Tools 2, 3, and 4.
32
+ */
33
+ async postToApi(path, body, extraHeaders) {
34
+ const url = `${this.config.apiUrl}${path}`;
35
+ return this.doFetch(url, "POST", body, extraHeaders);
36
+ }
37
+ /**
38
+ * GET request to the JSON Elements microservice.
39
+ * Used by Tool 4 (list applications).
40
+ */
41
+ async getFromApi(path, extraHeaders) {
42
+ const url = `${this.config.apiUrl}${path}`;
43
+ return this.doFetch(url, "GET", undefined, extraHeaders);
44
+ }
45
+ /**
46
+ * POST request to the AI Schema Builder microservice.
47
+ * Used by Tool 1 (generate schema from prompt).
48
+ */
49
+ async postToAiApi(path, body) {
50
+ const url = `${this.config.aiApiUrl}${path}`;
51
+ return this.doFetch(url, "POST", body);
52
+ }
53
+ /**
54
+ * Returns the SSE subscription URL for generation events.
55
+ * Used by Tool 1 to listen for async generation progress.
56
+ */
57
+ getSseUrl() {
58
+ return `${this.config.aiApiUrl}/api/ai/generation-events/subscribe`;
59
+ }
60
+ /**
61
+ * Returns the common headers needed for SSE connections.
62
+ */
63
+ async getSseHeaders() {
64
+ return this.getHeaders();
65
+ }
66
+ /**
67
+ * Internal fetch wrapper with error normalization.
68
+ */
69
+ async doFetch(url, method, body, extraHeaders) {
70
+ try {
71
+ const baseHeaders = await this.getHeaders();
72
+ const headers = { ...baseHeaders, ...extraHeaders };
73
+ const fetchOptions = {
74
+ method,
75
+ headers,
76
+ };
77
+ if (body) {
78
+ fetchOptions.body = JSON.stringify(body);
79
+ }
80
+ const response = await fetch(url, fetchOptions);
81
+ if (response.ok) {
82
+ // Handle 204 No Content
83
+ if (response.status === 204) {
84
+ return { ok: true, status: response.status };
85
+ }
86
+ const text = await response.text();
87
+ let data;
88
+ try {
89
+ data = JSON.parse(text);
90
+ }
91
+ catch {
92
+ // Response may not be JSON (e.g., plain text for 202 Accepted)
93
+ data = text;
94
+ }
95
+ return { ok: true, status: response.status, data };
96
+ }
97
+ // Error response — try to extract error message from body
98
+ let errorMessage;
99
+ try {
100
+ const errorBody = await response.text();
101
+ const parsed = JSON.parse(errorBody);
102
+ errorMessage =
103
+ parsed.message || parsed.error || `HTTP ${response.status}`;
104
+ }
105
+ catch {
106
+ errorMessage = `HTTP ${response.status}: ${response.statusText}`;
107
+ }
108
+ return { ok: false, status: response.status, error: errorMessage };
109
+ }
110
+ catch (error) {
111
+ const message = error instanceof Error ? error.message : "Unknown network error";
112
+ return { ok: false, status: 0, error: `Network error: ${message}` };
113
+ }
114
+ }
115
+ }
116
+ //# sourceMappingURL=igniral-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"igniral-client.js","sourceRoot":"","sources":["../../src/api/igniral-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Igniral MCP Server — Configuration
3
+ *
4
+ * Reads and validates environment variables required to connect
5
+ * to Igniral's backend microservices.
6
+ */
7
+ export interface IgniralConfig {
8
+ clientId: string;
9
+ clientSecret: string;
10
+ authUrl: string;
11
+ apiUrl: string;
12
+ aiApiUrl: string;
13
+ }
14
+ /**
15
+ * Loads configuration from environment variables.
16
+ * Throws if any required variable is missing.
17
+ */
18
+ export declare function loadConfig(): IgniralConfig;
19
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,aAAa,CAyB1C"}
package/dist/config.js ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Igniral MCP Server — Configuration
3
+ *
4
+ * Reads and validates environment variables required to connect
5
+ * to Igniral's backend microservices.
6
+ */
7
+ /**
8
+ * Loads configuration from environment variables.
9
+ * Throws if any required variable is missing.
10
+ */
11
+ export function loadConfig() {
12
+ const clientId = process.env.IGNIRAL_CLIENT_ID;
13
+ const clientSecret = process.env.IGNIRAL_CLIENT_SECRET;
14
+ const authUrl = process.env.IGNIRAL_AUTH_URL || "https://auth.igniral.com";
15
+ const apiUrl = process.env.IGNIRAL_API_URL || "https://api.igniral.io";
16
+ const aiApiUrl = process.env.IGNIRAL_AI_API_URL || "https://ai.igniral.com";
17
+ const missing = [];
18
+ if (!clientId)
19
+ missing.push("IGNIRAL_CLIENT_ID");
20
+ if (!clientSecret)
21
+ missing.push("IGNIRAL_CLIENT_SECRET");
22
+ if (missing.length > 0) {
23
+ throw new Error(`Missing required environment variables: ${missing.join(", ")}. ` +
24
+ `See .env.example for the expected configuration.`);
25
+ }
26
+ return {
27
+ clientId: clientId,
28
+ clientSecret: clientSecret,
29
+ authUrl: authUrl.replace(/\/$/, ""),
30
+ apiUrl: apiUrl.replace(/\/$/, ""),
31
+ aiApiUrl: aiApiUrl.replace(/\/$/, ""),
32
+ };
33
+ }
34
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;IAC3E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB,CAAC;IACvE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,wBAAwB,CAAC;IAE5E,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACjD,IAAI,CAAC,YAAY;QAAE,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAEzD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,2CAA2C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YAC/D,kDAAkD,CACrD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,QAAS;QACnB,YAAY,EAAE,YAAa;QAC3B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QACnC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QACjC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;KACtC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Igniral MCP Server — Entry Point
4
+ *
5
+ * A Model Context Protocol server that bridges AI agents (Claude, Cursor, etc.)
6
+ * with Igniral's backend microservices for dynamic API creation and management.
7
+ *
8
+ * Transport: stdio (standard for IDE integrations like Cursor and Claude Desktop)
9
+ *
10
+ * Tools exposed:
11
+ * 1. igniral_generate_schema_from_prompt — Auto-generate a complete app from description
12
+ * 2. igniral_create_application — Create an empty app shell manually
13
+ * 3. igniral_create_dynamic_endpoint — Add endpoints to an existing app
14
+ * 4. igniral_list_applications — List the user's existing applications
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}