0nmcp 1.4.0 → 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.
@@ -0,0 +1,254 @@
1
+ // ============================================================
2
+ // 0nMCP — Engine: Platform Config Generator
3
+ // ============================================================
4
+ // Generates MCP server configurations for all major AI
5
+ // platforms: Claude Desktop, Cursor, Windsurf, Gemini,
6
+ // Continue, Cline, and OpenAI.
7
+ // ============================================================
8
+
9
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from "fs";
10
+ import { join, dirname } from "path";
11
+ import { homedir, platform as osPlatform } from "os";
12
+
13
+ const HOME = homedir();
14
+ const IS_MAC = osPlatform() === "darwin";
15
+ const IS_WIN = osPlatform() === "win32";
16
+
17
+ // ── Platform definitions ───────────────────────────────────
18
+
19
+ const PLATFORMS = {
20
+ claude_desktop: {
21
+ name: "Claude Desktop",
22
+ format: "json",
23
+ configPath: () => {
24
+ if (IS_MAC) return join(HOME, "Library", "Application Support", "Claude", "claude_desktop_config.json");
25
+ if (IS_WIN) return join(process.env.APPDATA || "", "Claude", "claude_desktop_config.json");
26
+ return join(HOME, ".config", "Claude", "claude_desktop_config.json");
27
+ },
28
+ generate: (opts) => ({
29
+ mcpServers: {
30
+ "0nmcp": {
31
+ command: opts.command || "npx",
32
+ args: opts.args || ["-y", "0nmcp"],
33
+ ...(opts.env && Object.keys(opts.env).length > 0 ? { env: opts.env } : {}),
34
+ },
35
+ },
36
+ }),
37
+ },
38
+
39
+ cursor: {
40
+ name: "Cursor",
41
+ format: "json",
42
+ configPath: () => join(HOME, ".cursor", "mcp.json"),
43
+ generate: (opts) => ({
44
+ mcpServers: {
45
+ "0nmcp": {
46
+ command: opts.command || "npx",
47
+ args: opts.args || ["-y", "0nmcp"],
48
+ ...(opts.env && Object.keys(opts.env).length > 0 ? { env: opts.env } : {}),
49
+ },
50
+ },
51
+ }),
52
+ },
53
+
54
+ windsurf: {
55
+ name: "Windsurf",
56
+ format: "json",
57
+ configPath: () => join(HOME, ".codeium", "windsurf", "mcp_config.json"),
58
+ generate: (opts) => {
59
+ if (opts.mode === "http") {
60
+ return {
61
+ mcpServers: {
62
+ "0nmcp": {
63
+ serverUrl: opts.httpUrl || "http://localhost:3000/mcp",
64
+ },
65
+ },
66
+ };
67
+ }
68
+ return {
69
+ mcpServers: {
70
+ "0nmcp": {
71
+ command: opts.command || "npx",
72
+ args: opts.args || ["-y", "0nmcp"],
73
+ ...(opts.env && Object.keys(opts.env).length > 0 ? { env: opts.env } : {}),
74
+ },
75
+ },
76
+ };
77
+ },
78
+ },
79
+
80
+ gemini: {
81
+ name: "Gemini",
82
+ format: "json",
83
+ configPath: () => join(HOME, ".gemini", "settings.json"),
84
+ generate: (opts) => ({
85
+ mcpServers: {
86
+ "0nmcp": {
87
+ command: opts.command || "npx",
88
+ args: opts.args || ["-y", "0nmcp"],
89
+ },
90
+ },
91
+ }),
92
+ },
93
+
94
+ continue: {
95
+ name: "Continue",
96
+ format: "yaml",
97
+ configPath: () => join(HOME, ".continue", "config.yaml"),
98
+ generate: (opts) => {
99
+ const cmd = opts.command || "npx";
100
+ const args = opts.args || ["-y", "0nmcp"];
101
+ const argsYaml = args.map(a => ` - "${a}"`).join("\n");
102
+ let yaml = `mcpServers:\n - name: 0nmcp\n command: ${cmd}\n args:\n${argsYaml}\n`;
103
+ if (opts.env && Object.keys(opts.env).length > 0) {
104
+ yaml += " env:\n";
105
+ for (const [k, v] of Object.entries(opts.env)) {
106
+ yaml += ` ${k}: "${v}"\n`;
107
+ }
108
+ }
109
+ return yaml;
110
+ },
111
+ },
112
+
113
+ cline: {
114
+ name: "Cline",
115
+ format: "json",
116
+ configPath: () => {
117
+ if (IS_MAC) return join(HOME, "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json");
118
+ if (IS_WIN) return join(process.env.APPDATA || "", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json");
119
+ return join(HOME, ".config", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json");
120
+ },
121
+ generate: (opts) => ({
122
+ mcpServers: {
123
+ "0nmcp": {
124
+ command: opts.command || "npx",
125
+ args: opts.args || ["-y", "0nmcp"],
126
+ ...(opts.env && Object.keys(opts.env).length > 0 ? { env: opts.env } : {}),
127
+ alwaysAllow: [],
128
+ disabled: false,
129
+ },
130
+ },
131
+ }),
132
+ },
133
+
134
+ openai: {
135
+ name: "OpenAI",
136
+ format: "json",
137
+ configPath: () => null, // No local config file — HTTP only
138
+ generate: (opts) => ({
139
+ type: "streamable-http",
140
+ url: opts.httpUrl || "http://localhost:3000/mcp",
141
+ instructions: "Start the 0nMCP HTTP server first: npx 0nmcp serve --port 3000. Then add this URL as an MCP connector in OpenAI settings.",
142
+ }),
143
+ },
144
+ };
145
+
146
+ /**
147
+ * Generate config for a single platform.
148
+ * @param {string} platform - Platform key
149
+ * @param {object} options - { command?, args?, env?, mode?, httpUrl? }
150
+ * @returns {{ config: object|string, path: string|null, format: string, name: string }}
151
+ */
152
+ export function generatePlatformConfig(platform, options = {}) {
153
+ const p = PLATFORMS[platform];
154
+ if (!p) throw new Error(`Unknown platform: ${platform}. Available: ${Object.keys(PLATFORMS).join(", ")}`);
155
+
156
+ return {
157
+ config: p.generate(options),
158
+ path: p.configPath(),
159
+ format: p.format,
160
+ name: p.name,
161
+ };
162
+ }
163
+
164
+ /**
165
+ * Generate configs for all platforms.
166
+ * @param {object} options
167
+ * @returns {Record<string, { config: object|string, path: string|null, format: string, name: string }>}
168
+ */
169
+ export function generateAllPlatformConfigs(options = {}) {
170
+ const configs = {};
171
+ for (const key of Object.keys(PLATFORMS)) {
172
+ configs[key] = generatePlatformConfig(key, options);
173
+ }
174
+ return configs;
175
+ }
176
+
177
+ /**
178
+ * Install a platform config to disk.
179
+ * Merges 0nmcp entry into existing config if present. Backs up existing file.
180
+ * @param {string} platform
181
+ * @param {object} options
182
+ * @returns {{ success: boolean, path: string, backed_up?: string, error?: string }}
183
+ */
184
+ export function installPlatformConfig(platform, options = {}) {
185
+ const { config, path, format, name } = generatePlatformConfig(platform, options);
186
+
187
+ if (!path) {
188
+ return { success: false, path: null, error: `${name} does not use a local config file (HTTP-only).` };
189
+ }
190
+
191
+ try {
192
+ const dir = dirname(path);
193
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
194
+
195
+ let backed_up;
196
+
197
+ if (format === "json") {
198
+ let existing = {};
199
+ if (existsSync(path)) {
200
+ // Backup existing
201
+ backed_up = `${path}.bak.${Date.now()}`;
202
+ copyFileSync(path, backed_up);
203
+ existing = JSON.parse(readFileSync(path, "utf-8"));
204
+ }
205
+
206
+ // Merge mcpServers
207
+ if (config.mcpServers) {
208
+ existing.mcpServers = existing.mcpServers || {};
209
+ Object.assign(existing.mcpServers, config.mcpServers);
210
+ }
211
+
212
+ writeFileSync(path, JSON.stringify(existing, null, 2));
213
+ } else if (format === "yaml") {
214
+ if (existsSync(path)) {
215
+ backed_up = `${path}.bak.${Date.now()}`;
216
+ copyFileSync(path, backed_up);
217
+ // Append to existing YAML
218
+ const existing = readFileSync(path, "utf-8");
219
+ writeFileSync(path, existing + "\n" + config);
220
+ } else {
221
+ writeFileSync(path, typeof config === "string" ? config : JSON.stringify(config, null, 2));
222
+ }
223
+ }
224
+
225
+ return { success: true, path, backed_up, name };
226
+ } catch (err) {
227
+ return { success: false, path, error: err.message };
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Get info about all platforms and whether configs are installed.
233
+ * @returns {Array<{ platform: string, name: string, configPath: string|null, installed: boolean, format: string }>}
234
+ */
235
+ export function getPlatformInfo() {
236
+ return Object.entries(PLATFORMS).map(([key, p]) => {
237
+ const path = p.configPath();
238
+ return {
239
+ platform: key,
240
+ name: p.name,
241
+ configPath: path,
242
+ installed: path ? existsSync(path) : false,
243
+ format: p.format,
244
+ };
245
+ });
246
+ }
247
+
248
+ /**
249
+ * Get list of supported platform keys.
250
+ * @returns {string[]}
251
+ */
252
+ export function listPlatforms() {
253
+ return Object.keys(PLATFORMS);
254
+ }
@@ -0,0 +1,257 @@
1
+ // ============================================================
2
+ // 0nMCP — Engine: API Key Validator
3
+ // ============================================================
4
+ // Verifies API credentials by making lightweight, read-only
5
+ // test calls to each service. All calls are non-destructive.
6
+ // ============================================================
7
+
8
+ import { SERVICE_CATALOG } from "../catalog.js";
9
+
10
+ const TIMEOUT_MS = 10000;
11
+
12
+ // ── Verification endpoints per service ─────────────────────
13
+
14
+ const VERIFICATION_ENDPOINTS = {
15
+ stripe: {
16
+ url: "https://api.stripe.com/v1/balance",
17
+ method: "GET",
18
+ headers: (c) => ({ Authorization: `Bearer ${c.apiKey}` }),
19
+ check: (r) => r.status === 200,
20
+ },
21
+ openai: {
22
+ url: "https://api.openai.com/v1/models",
23
+ method: "GET",
24
+ headers: (c) => ({ Authorization: `Bearer ${c.apiKey}` }),
25
+ check: (r) => r.status === 200,
26
+ },
27
+ slack: {
28
+ url: "https://slack.com/api/auth.test",
29
+ method: "POST",
30
+ headers: (c) => ({ Authorization: `Bearer ${c.botToken}`, "Content-Type": "application/json" }),
31
+ check: (r, d) => d?.ok === true,
32
+ },
33
+ discord: {
34
+ url: "https://discord.com/api/v10/users/@me",
35
+ method: "GET",
36
+ headers: (c) => ({ Authorization: `Bot ${c.botToken}` }),
37
+ check: (r) => r.status === 200,
38
+ },
39
+ github: {
40
+ url: "https://api.github.com/user",
41
+ method: "GET",
42
+ headers: (c) => ({ Authorization: `Bearer ${c.token}`, "User-Agent": "0nMCP-Engine", Accept: "application/vnd.github+json" }),
43
+ check: (r) => r.status === 200,
44
+ },
45
+ twilio: {
46
+ url: (c) => `https://api.twilio.com/2010-04-01/Accounts/${c.accountSid}.json`,
47
+ method: "GET",
48
+ headers: (c) => ({ Authorization: "Basic " + Buffer.from(`${c.accountSid}:${c.authToken}`).toString("base64") }),
49
+ check: (r) => r.status === 200,
50
+ },
51
+ sendgrid: {
52
+ url: "https://api.sendgrid.com/v3/scopes",
53
+ method: "GET",
54
+ headers: (c) => ({ Authorization: `Bearer ${c.apiKey}` }),
55
+ check: (r) => r.status === 200,
56
+ },
57
+ resend: {
58
+ url: "https://api.resend.com/domains",
59
+ method: "GET",
60
+ headers: (c) => ({ Authorization: `Bearer ${c.apiKey}` }),
61
+ check: (r) => r.status === 200,
62
+ },
63
+ airtable: {
64
+ url: "https://api.airtable.com/v0/meta/bases",
65
+ method: "GET",
66
+ headers: (c) => ({ Authorization: `Bearer ${c.apiKey}` }),
67
+ check: (r) => r.status === 200,
68
+ },
69
+ notion: {
70
+ url: "https://api.notion.com/v1/users/me",
71
+ method: "GET",
72
+ headers: (c) => ({ Authorization: `Bearer ${c.apiKey}`, "Notion-Version": "2022-06-28" }),
73
+ check: (r) => r.status === 200,
74
+ },
75
+ linear: {
76
+ url: "https://api.linear.app/graphql",
77
+ method: "POST",
78
+ headers: (c) => ({ Authorization: c.apiKey, "Content-Type": "application/json" }),
79
+ body: JSON.stringify({ query: "{ viewer { id } }" }),
80
+ check: (r, d) => !!d?.data?.viewer?.id,
81
+ },
82
+ shopify: {
83
+ url: (c) => `https://${c.store}.myshopify.com/admin/api/2024-01/shop.json`,
84
+ method: "GET",
85
+ headers: (c) => ({ "X-Shopify-Access-Token": c.accessToken }),
86
+ check: (r) => r.status === 200,
87
+ },
88
+ hubspot: {
89
+ url: "https://api.hubapi.com/crm/v3/objects/contacts?limit=1",
90
+ method: "GET",
91
+ headers: (c) => ({ Authorization: `Bearer ${c.accessToken}` }),
92
+ check: (r) => r.status === 200,
93
+ },
94
+ supabase: {
95
+ url: (c) => `https://${c.projectRef}.supabase.co/rest/v1/`,
96
+ method: "GET",
97
+ headers: (c) => ({ apikey: c.apiKey, Authorization: `Bearer ${c.apiKey}` }),
98
+ check: (r) => r.status <= 404, // 200 or 404 both mean auth works
99
+ },
100
+ calendly: {
101
+ url: "https://api.calendly.com/users/me",
102
+ method: "GET",
103
+ headers: (c) => ({ Authorization: `Bearer ${c.apiKey}` }),
104
+ check: (r) => r.status === 200,
105
+ },
106
+ google_calendar: {
107
+ url: "https://www.googleapis.com/calendar/v3/users/me/calendarList?maxResults=1",
108
+ method: "GET",
109
+ headers: (c) => ({ Authorization: `Bearer ${c.access_token}` }),
110
+ check: (r) => r.status === 200,
111
+ },
112
+ gmail: {
113
+ url: "https://gmail.googleapis.com/gmail/v1/users/me/profile",
114
+ method: "GET",
115
+ headers: (c) => ({ Authorization: `Bearer ${c.access_token}` }),
116
+ check: (r) => r.status === 200,
117
+ },
118
+ google_sheets: {
119
+ url: "https://sheets.googleapis.com/v4/spreadsheets",
120
+ method: "GET",
121
+ headers: (c) => ({ Authorization: `Bearer ${c.access_token}` }),
122
+ check: (r) => r.status === 200 || r.status === 400, // 400 = auth works, no spreadsheet ID
123
+ },
124
+ google_drive: {
125
+ url: "https://www.googleapis.com/drive/v3/about?fields=user",
126
+ method: "GET",
127
+ headers: (c) => ({ Authorization: `Bearer ${c.access_token}` }),
128
+ check: (r) => r.status === 200,
129
+ },
130
+ jira: {
131
+ url: (c) => `https://${c.domain}.atlassian.net/rest/api/3/myself`,
132
+ method: "GET",
133
+ headers: (c) => ({ Authorization: "Basic " + Buffer.from(`${c.email}:${c.apiToken}`).toString("base64"), Accept: "application/json" }),
134
+ check: (r) => r.status === 200,
135
+ },
136
+ zendesk: {
137
+ url: (c) => `https://${c.subdomain}.zendesk.com/api/v2/users/me.json`,
138
+ method: "GET",
139
+ headers: (c) => ({ Authorization: "Basic " + Buffer.from(`${c.email}/token:${c.apiToken}`).toString("base64") }),
140
+ check: (r) => r.status === 200,
141
+ },
142
+ mailchimp: {
143
+ url: (c) => {
144
+ const dc = c.apiKey.includes("-") ? c.apiKey.split("-").pop() : "us1";
145
+ return `https://${dc}.api.mailchimp.com/3.0/`;
146
+ },
147
+ method: "GET",
148
+ headers: (c) => ({ Authorization: "Basic " + Buffer.from(`anystring:${c.apiKey}`).toString("base64") }),
149
+ check: (r) => r.status === 200,
150
+ },
151
+ zoom: {
152
+ url: "https://api.zoom.us/v2/users/me",
153
+ method: "GET",
154
+ headers: (c) => ({ Authorization: `Bearer ${c.access_token}` }),
155
+ check: (r) => r.status === 200,
156
+ },
157
+ microsoft: {
158
+ url: "https://graph.microsoft.com/v1.0/me",
159
+ method: "GET",
160
+ headers: (c) => ({ Authorization: `Bearer ${c.access_token}` }),
161
+ check: (r) => r.status === 200,
162
+ },
163
+ mongodb: {
164
+ url: (c) => `https://data.mongodb-api.com/app/${c.appId}/endpoint/data/v1/action/find`,
165
+ method: "POST",
166
+ headers: (c) => ({ "api-key": c.apiKey, "Content-Type": "application/json" }),
167
+ body: JSON.stringify({ dataSource: "Cluster0", database: "test", collection: "test" }),
168
+ check: (r) => r.status === 200 || r.status === 400, // 400 = auth works, bad params
169
+ },
170
+ crm: {
171
+ url: "https://services.leadconnectorhq.com/contacts/?limit=1",
172
+ method: "GET",
173
+ headers: (c) => ({ Authorization: `Bearer ${c.access_token}`, Version: "2021-07-28" }),
174
+ check: (r) => r.status === 200,
175
+ },
176
+ };
177
+
178
+ /**
179
+ * Verify credentials for a single service.
180
+ * @param {string} service
181
+ * @param {Record<string, string>} credentials
182
+ * @returns {Promise<{ valid: boolean, status: number, message: string, latency_ms: number }>}
183
+ */
184
+ export async function verifyCredentials(service, credentials) {
185
+ const endpoint = VERIFICATION_ENDPOINTS[service];
186
+ if (!endpoint) {
187
+ return { valid: false, status: 0, message: "No verification endpoint available", latency_ms: 0, skipped: true };
188
+ }
189
+
190
+ const start = Date.now();
191
+ const controller = new AbortController();
192
+ const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);
193
+
194
+ try {
195
+ const url = typeof endpoint.url === "function" ? endpoint.url(credentials) : endpoint.url;
196
+ const headers = endpoint.headers(credentials);
197
+ const options = { method: endpoint.method, headers, signal: controller.signal };
198
+
199
+ if (endpoint.body && endpoint.method !== "GET") {
200
+ options.body = endpoint.body;
201
+ }
202
+
203
+ const response = await fetch(url, options);
204
+ const data = await response.json().catch(() => null);
205
+ const latency_ms = Date.now() - start;
206
+
207
+ const valid = endpoint.check(response, data);
208
+ return {
209
+ valid,
210
+ status: response.status,
211
+ message: valid ? "Credentials verified" : `Verification failed (HTTP ${response.status})`,
212
+ latency_ms,
213
+ };
214
+ } catch (err) {
215
+ return {
216
+ valid: false,
217
+ status: 0,
218
+ message: err.name === "AbortError" ? "Verification timed out" : err.message,
219
+ latency_ms: Date.now() - start,
220
+ };
221
+ } finally {
222
+ clearTimeout(timeout);
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Verify all connected services in parallel.
228
+ * @param {Record<string, { credentials: Record<string, string> }>} connections
229
+ * @returns {Promise<{ results: Record<string, object>, summary: { total: number, valid: number, invalid: number, skipped: number } }>}
230
+ */
231
+ export async function verifyAll(connections) {
232
+ const entries = Object.entries(connections);
233
+ const results = {};
234
+ const summary = { total: entries.length, valid: 0, invalid: 0, skipped: 0 };
235
+
236
+ // Run in parallel batches of 5
237
+ const batchSize = 5;
238
+ for (let i = 0; i < entries.length; i += batchSize) {
239
+ const batch = entries.slice(i, i + batchSize);
240
+ const promises = batch.map(([service, conn]) =>
241
+ verifyCredentials(service, conn.credentials).then(r => ({ service, ...r }))
242
+ );
243
+ const batchResults = await Promise.allSettled(promises);
244
+
245
+ for (const result of batchResults) {
246
+ if (result.status === "fulfilled") {
247
+ const r = result.value;
248
+ results[r.service] = r;
249
+ if (r.skipped) summary.skipped++;
250
+ else if (r.valid) summary.valid++;
251
+ else summary.invalid++;
252
+ }
253
+ }
254
+ }
255
+
256
+ return { results, summary };
257
+ }
package/index.js CHANGED
@@ -27,15 +27,19 @@ import { Orchestrator } from "./orchestrator.js";
27
27
  import { WorkflowRunner } from "./workflow.js";
28
28
  import { registerAllTools } from "./tools.js";
29
29
  import { registerCrmTools } from "./crm/index.js";
30
+ import { registerVaultTools, autoUnseal } from "./vault/index.js";
31
+ import { unsealedCache } from "./vault/cache.js";
32
+ import { registerEngineTools } from "./engine/index.js";
30
33
 
31
34
  // ── Initialize ─────────────────────────────────────────────
32
35
  const connections = new ConnectionManager();
36
+ connections._vaultCache = unsealedCache;
33
37
  const orchestrator = new Orchestrator(connections);
34
38
  const workflowRunner = new WorkflowRunner(connections);
35
39
 
36
40
  const server = new McpServer({
37
41
  name: "0nMCP",
38
- version: "1.4.0",
42
+ version: "1.6.0",
39
43
  });
40
44
 
41
45
  // ============================================================
@@ -51,6 +55,24 @@ registerAllTools(server, connections, orchestrator, workflowRunner);
51
55
  import { z } from "zod";
52
56
  registerCrmTools(server, z);
53
57
 
58
+ // ============================================================
59
+ // VAULT TOOLS (machine-bound credential encryption)
60
+ // ============================================================
61
+
62
+ registerVaultTools(server, z);
63
+
64
+ // Auto-unseal sealed connections if ON_VAULT_PASSPHRASE is set
65
+ const vaultResult = autoUnseal();
66
+ if (vaultResult.unsealed.length > 0) {
67
+ console.error(`Vault: auto-unsealed ${vaultResult.unsealed.length} connection(s)`);
68
+ }
69
+
70
+ // ============================================================
71
+ // ENGINE TOOLS (.0n conversion engine + AI brain bundles)
72
+ // ============================================================
73
+
74
+ registerEngineTools(server, z);
75
+
54
76
  // ============================================================
55
77
  // START SERVER (stdio transport)
56
78
  // ============================================================
package/lib/badges.json CHANGED
@@ -26,7 +26,7 @@
26
26
  "total": {
27
27
  "schemaVersion": 1,
28
28
  "label": "capabilities",
29
- "message": "693",
29
+ "message": "703",
30
30
  "color": "00ff88"
31
31
  }
32
32
  }
package/lib/stats.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-02-15T00:13:31.784Z",
2
+ "generated": "2026-02-15T01:13:33.591Z",
3
3
  "catalogVersion": "1.2.2",
4
4
  "services": 26,
5
5
  "tools": 290,
@@ -792,6 +792,8 @@
792
792
  "mongodb"
793
793
  ],
794
794
  "crmTools": 245,
795
- "totalTools": 535,
796
- "totalCapabilities": 693
795
+ "vaultTools": 4,
796
+ "engineTools": 6,
797
+ "totalTools": 545,
798
+ "totalCapabilities": 703
797
799
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "0nmcp",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "mcpName": "io.github.0nork/0nMCP",
5
- "description": "Universal AI API Orchestrator — 535 tools, 26 services, natural language interface. The most comprehensive MCP server available. Free and open source from 0nORK.",
5
+ "description": "Universal AI API Orchestrator — 545 tools, 26 services, portable AI Brain bundles + machine-bound vault encryption. The most comprehensive MCP server available. Free and open source from 0nORK.",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "types": "types/index.d.ts",
@@ -43,6 +43,12 @@
43
43
  },
44
44
  "./server": {
45
45
  "import": "./server.js"
46
+ },
47
+ "./vault": {
48
+ "import": "./vault/index.js"
49
+ },
50
+ "./engine": {
51
+ "import": "./engine/index.js"
46
52
  }
47
53
  },
48
54
  "scripts": {
@@ -107,6 +113,14 @@
107
113
  "teams",
108
114
  "onedrive",
109
115
  "mongodb",
116
+ "vault",
117
+ "encryption",
118
+ "machine-bound",
119
+ "credential-storage",
120
+ "portable-bundle",
121
+ "ai-brain",
122
+ "credential-import",
123
+ "platform-config",
110
124
  "0n",
111
125
  "0nork",
112
126
  "0nmcp"
@@ -156,6 +170,8 @@
156
170
  "crm/",
157
171
  "webhooks.js",
158
172
  "ratelimit.js",
173
+ "vault/",
174
+ "engine/",
159
175
  "lib/",
160
176
  "types/",
161
177
  "README.md",
@@ -164,12 +180,14 @@
164
180
  "0nmcp-stats": {
165
181
  "tools": 290,
166
182
  "crmTools": 245,
167
- "totalTools": 535,
183
+ "vaultTools": 4,
184
+ "engineTools": 6,
185
+ "totalTools": 545,
168
186
  "services": 26,
169
187
  "actions": 65,
170
188
  "triggers": 93,
171
- "totalCapabilities": 693,
189
+ "totalCapabilities": 703,
172
190
  "categories": 13,
173
- "lastUpdated": "2026-02-15T00:13:31.784Z"
191
+ "lastUpdated": "2026-02-15T01:13:33.591Z"
174
192
  }
175
193
  }