0nmcp 2.9.2 → 3.0.1

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,440 @@
1
+ /**
2
+ * 0n Knowledge Layers — Patent #5 Prototype Implementation
3
+ *
4
+ * User-Configurable Multi-Layer AI Knowledge Architecture
5
+ * with Cross-Platform Portable Deployment and Automatic
6
+ * Capability Discovery via Service Connection
7
+ *
8
+ * US Provisional Patent — RocketOpp LLC
9
+ * Inventor: Michael A. Mento Jr.
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ // ── Layer Taxonomy (K1-K7) ──────────────────────────────────────────
15
+
16
+ const LAYER_SCHEMA = {
17
+ brand_voice: {
18
+ id: 'K1',
19
+ name: 'Brand Voice',
20
+ description: 'Brand identity, tone, communication style',
21
+ composition: 'override', // User layer replaces defaults entirely
22
+ fields: ['tone', 'formality', 'humor', 'vocabulary_additions', 'vocabulary_prohibitions', 'style_rules', 'personality_attributes'],
23
+ },
24
+ terminology: {
25
+ id: 'K2',
26
+ name: 'Terminology',
27
+ description: 'Business-specific terms, acronyms, slang',
28
+ composition: 'merge', // User values merge with defaults
29
+ fields: ['acronyms', 'proper_nouns', 'slang', 'corrections', 'industry_terms'],
30
+ },
31
+ business_structure: {
32
+ id: 'K3',
33
+ name: 'Business Structure',
34
+ description: 'Organizational context, services, team',
35
+ composition: 'merge',
36
+ fields: ['business_name', 'phone', 'email', 'address', 'hours', 'timezone', 'team', 'departments', 'services', 'pricing'],
37
+ },
38
+ visual_identity: {
39
+ id: 'K4',
40
+ name: 'Visual Identity',
41
+ description: 'Brand colors, typography, visual preferences',
42
+ composition: 'override',
43
+ fields: ['primary_color', 'secondary_color', 'accent_color', 'font_display', 'font_body', 'logo_url', 'icon_style', 'theme_preference'],
44
+ },
45
+ domain_knowledge: {
46
+ id: 'K5',
47
+ name: 'Domain Knowledge',
48
+ description: 'Industry expertise, FAQs, procedures',
49
+ composition: 'append', // Adds to defaults, never removes
50
+ fields: ['faq_pairs', 'procedures', 'compliance', 'best_practices', 'competitive_positioning', 'unique_selling_points'],
51
+ },
52
+ credentials: {
53
+ id: 'K6',
54
+ name: 'Credentials',
55
+ description: 'API keys, tokens, service endpoints',
56
+ composition: 'replace', // User layer is sole source
57
+ fields: ['api_keys', 'oauth_tokens', 'webhook_urls', 'mcp_configs', 'service_endpoints'],
58
+ encrypted: true, // Double-encrypted via Argon2id per 0nVault patent
59
+ },
60
+ operational_context: {
61
+ id: 'K7',
62
+ name: 'Operational Context',
63
+ description: 'Runtime state, history, active workflows',
64
+ composition: 'append',
65
+ fields: ['active_workflows', 'recent_interactions', 'pending_tasks', 'calendar_state', 'pipeline_state', 'seasonal_context'],
66
+ system_managed: true, // Updated automatically, not user-edited
67
+ },
68
+ };
69
+
70
+ // ── Known Credential Patterns ───────────────────────────────────────
71
+
72
+ const CREDENTIAL_PATTERNS = [
73
+ { pattern: /^sk-ant-/, service: 'anthropic', name: 'Anthropic API Key' },
74
+ { pattern: /^sk-[a-zA-Z0-9]{48}/, service: 'openai', name: 'OpenAI API Key' },
75
+ { pattern: /^rk_live_/, service: 'stripe', name: 'Stripe Secret Key' },
76
+ { pattern: /^pk_live_/, service: 'stripe', name: 'Stripe Publishable Key' },
77
+ { pattern: /^whsec_/, service: 'stripe', name: 'Stripe Webhook Secret' },
78
+ { pattern: /^pit-[a-f0-9-]{36}$/, service: 'crm', name: 'CRM PIT Token' },
79
+ { pattern: /^xoxb-/, service: 'slack', name: 'Slack Bot Token' },
80
+ { pattern: /^xoxp-/, service: 'slack', name: 'Slack User Token' },
81
+ { pattern: /^gsk_/, service: 'groq', name: 'Groq API Key' },
82
+ { pattern: /^SG\./, service: 'sendgrid', name: 'SendGrid API Key' },
83
+ { pattern: /^AC[a-f0-9]{32}$/, service: 'twilio', name: 'Twilio Account SID' },
84
+ { pattern: /^ghp_/, service: 'github', name: 'GitHub Personal Access Token' },
85
+ { pattern: /^gho_/, service: 'github', name: 'GitHub OAuth Token' },
86
+ { pattern: /^eyJ[A-Za-z0-9_-]+\.eyJ/, service: 'supabase', name: 'Supabase JWT' },
87
+ { pattern: /^AKIA[A-Z0-9]{16}$/, service: 'aws', name: 'AWS Access Key' },
88
+ { pattern: /^AIza[A-Za-z0-9_-]{35}$/, service: 'google', name: 'Google API Key' },
89
+ { pattern: /^re_[A-Za-z0-9]+$/, service: 'resend', name: 'Resend API Key' },
90
+ ];
91
+
92
+ // ── Knowledge Layer Manager ─────────────────────────────────────────
93
+
94
+ class KnowledgeLayers {
95
+
96
+ constructor(locationId) {
97
+ this.locationId = locationId;
98
+ this.layers = {};
99
+ this.completion = { total: 0, filled: 0, pct: 0, missing: [] };
100
+ }
101
+
102
+ /**
103
+ * Load layers from vault data.
104
+ */
105
+ load(vaultData) {
106
+ for (const [key, schema] of Object.entries(LAYER_SCHEMA)) {
107
+ this.layers[key] = {
108
+ ...schema,
109
+ data: vaultData?.[key] || {},
110
+ version: vaultData?.[key]?._version || 1,
111
+ updated_at: vaultData?.[key]?._updated_at || null,
112
+ };
113
+ }
114
+ return this;
115
+ }
116
+
117
+ /**
118
+ * Update a specific field in a layer.
119
+ */
120
+ updateField(layerKey, field, value) {
121
+ if (!this.layers[layerKey]) throw new Error(`Unknown layer: ${layerKey}`);
122
+ if (!this.layers[layerKey].data) this.layers[layerKey].data = {};
123
+ this.layers[layerKey].data[field] = value;
124
+ this.layers[layerKey].version++;
125
+ this.layers[layerKey].updated_at = new Date().toISOString();
126
+ return this;
127
+ }
128
+
129
+ /**
130
+ * Compose layers using the defined strategies.
131
+ * Merges user data with defaults according to each layer's composition type.
132
+ */
133
+ compose(defaults = {}) {
134
+ const result = {};
135
+
136
+ for (const [key, layer] of Object.entries(this.layers)) {
137
+ const userLayer = layer.data || {};
138
+ const defaultLayer = defaults[key] || {};
139
+ const strategy = layer.composition;
140
+
141
+ switch (strategy) {
142
+ case 'override':
143
+ // User layer completely replaces default
144
+ result[key] = Object.keys(userLayer).length > 0 ? userLayer : defaultLayer;
145
+ break;
146
+
147
+ case 'merge':
148
+ // Merge: user values take precedence for duplicate keys
149
+ result[key] = { ...defaultLayer, ...userLayer };
150
+ break;
151
+
152
+ case 'append':
153
+ // Append: combine arrays, merge objects, user values added
154
+ result[key] = {};
155
+ for (const field of new Set([...Object.keys(defaultLayer), ...Object.keys(userLayer)])) {
156
+ const dv = defaultLayer[field];
157
+ const uv = userLayer[field];
158
+ if (Array.isArray(dv) && Array.isArray(uv)) {
159
+ result[key][field] = [...dv, ...uv];
160
+ } else if (typeof dv === 'object' && typeof uv === 'object' && dv && uv) {
161
+ result[key][field] = { ...dv, ...uv };
162
+ } else {
163
+ result[key][field] = uv !== undefined ? uv : dv;
164
+ }
165
+ }
166
+ break;
167
+
168
+ case 'replace':
169
+ // Replace: user layer only, ignore defaults
170
+ result[key] = userLayer;
171
+ break;
172
+
173
+ default:
174
+ result[key] = { ...defaultLayer, ...userLayer };
175
+ }
176
+ }
177
+
178
+ return result;
179
+ }
180
+
181
+ /**
182
+ * Resolve cross-layer template references.
183
+ * "Always refer to {{business_structure.business_name}} in full"
184
+ * → "Always refer to The Spa In Ligonier in full"
185
+ */
186
+ resolveReferences(text, composedLayers) {
187
+ return text.replace(/\{\{(\w+)\.(\w+)\}\}/g, (match, layerKey, field) => {
188
+ const layer = composedLayers[layerKey];
189
+ if (layer && layer[field] !== undefined) {
190
+ return String(layer[field]);
191
+ }
192
+ return match; // Keep unresolved references as-is
193
+ });
194
+ }
195
+
196
+ /**
197
+ * Adapt composed layers to a specific platform format.
198
+ */
199
+ adaptForPlatform(platform, composedLayers) {
200
+ const adapters = {
201
+ 'openai': () => this._adaptOpenAI(composedLayers),
202
+ 'anthropic': () => this._adaptAnthropic(composedLayers),
203
+ 'gemini': () => this._adaptGemini(composedLayers),
204
+ 'ollama': () => this._adaptOllama(composedLayers),
205
+ 'mcp': () => this._adaptMCP(composedLayers),
206
+ 'wordpress': () => this._adaptWordPress(composedLayers),
207
+ 'slack': () => this._adaptSlack(composedLayers),
208
+ 'system_prompt': () => this._adaptSystemPrompt(composedLayers),
209
+ };
210
+
211
+ const adapter = adapters[platform] || adapters['system_prompt'];
212
+ return adapter();
213
+ }
214
+
215
+ // ── Platform Adapters ───────────────────────────────────────────
216
+
217
+ _adaptSystemPrompt(layers) {
218
+ let prompt = '';
219
+
220
+ // K1: Brand Voice
221
+ if (layers.brand_voice?.tone) {
222
+ prompt += `## Communication Style\nTone: ${layers.brand_voice.tone}\n`;
223
+ if (layers.brand_voice.formality !== undefined) prompt += `Formality level: ${layers.brand_voice.formality}/1.0\n`;
224
+ if (layers.brand_voice.style_rules?.length) {
225
+ prompt += 'Rules:\n' + layers.brand_voice.style_rules.map(r => `- ${r}`).join('\n') + '\n';
226
+ }
227
+ if (layers.brand_voice.vocabulary_prohibitions?.length) {
228
+ prompt += `Never use: ${layers.brand_voice.vocabulary_prohibitions.join(', ')}\n`;
229
+ }
230
+ prompt += '\n';
231
+ }
232
+
233
+ // K2: Terminology
234
+ if (layers.terminology?.acronyms && Object.keys(layers.terminology.acronyms).length) {
235
+ prompt += '## Terminology\n';
236
+ for (const [abbr, full] of Object.entries(layers.terminology.acronyms)) {
237
+ prompt += `- ${abbr} = ${full}\n`;
238
+ }
239
+ if (layers.terminology.proper_nouns) {
240
+ for (const [noun, rule] of Object.entries(layers.terminology.proper_nouns)) {
241
+ prompt += `- "${noun}": ${rule}\n`;
242
+ }
243
+ }
244
+ prompt += '\n';
245
+ }
246
+
247
+ // K3: Business Structure
248
+ if (layers.business_structure?.business_name) {
249
+ prompt += '## Business Information\n';
250
+ const bs = layers.business_structure;
251
+ if (bs.business_name) prompt += `Business: ${bs.business_name}\n`;
252
+ if (bs.phone) prompt += `Phone: ${bs.phone}\n`;
253
+ if (bs.email) prompt += `Email: ${bs.email}\n`;
254
+ if (bs.address) prompt += `Address: ${bs.address}\n`;
255
+ if (bs.hours) prompt += `Hours: ${JSON.stringify(bs.hours)}\n`;
256
+ if (bs.services?.length) {
257
+ prompt += '\nServices:\n';
258
+ for (const svc of bs.services) {
259
+ prompt += `- ${svc.name}${svc.price ? ` (${svc.price})` : ''}${svc.duration ? ` — ${svc.duration}` : ''}\n`;
260
+ }
261
+ }
262
+ prompt += '\n';
263
+ }
264
+
265
+ // K5: Domain Knowledge
266
+ if (layers.domain_knowledge?.faq_pairs?.length) {
267
+ prompt += '## FAQ\n';
268
+ for (const faq of layers.domain_knowledge.faq_pairs) {
269
+ prompt += `Q: ${faq.q}\nA: ${faq.a}\n\n`;
270
+ }
271
+ }
272
+
273
+ return { type: 'system_prompt', content: prompt.trim() };
274
+ }
275
+
276
+ _adaptOpenAI(layers) {
277
+ const systemPrompt = this._adaptSystemPrompt(layers);
278
+ // OpenAI GPTs have 128K context — we can include everything
279
+ return {
280
+ type: 'openai_gpt',
281
+ instructions: systemPrompt.content,
282
+ knowledge_files: this._extractKnowledgeFiles(layers),
283
+ };
284
+ }
285
+
286
+ _adaptAnthropic(layers) {
287
+ const systemPrompt = this._adaptSystemPrompt(layers);
288
+ return {
289
+ type: 'anthropic_project',
290
+ system: systemPrompt.content,
291
+ project_knowledge: this._extractKnowledgeFiles(layers),
292
+ };
293
+ }
294
+
295
+ _adaptGemini(layers) {
296
+ const systemPrompt = this._adaptSystemPrompt(layers);
297
+ // Gemini Gems have 4K char limit — truncate by priority
298
+ const truncated = systemPrompt.content.substring(0, 4000);
299
+ return {
300
+ type: 'gemini_gem',
301
+ instructions: truncated,
302
+ truncated: systemPrompt.content.length > 4000,
303
+ original_length: systemPrompt.content.length,
304
+ };
305
+ }
306
+
307
+ _adaptOllama(layers) {
308
+ const systemPrompt = this._adaptSystemPrompt(layers);
309
+ return {
310
+ type: 'ollama_brain',
311
+ system: systemPrompt.content,
312
+ brain_file: this._generateBrainFile(layers),
313
+ };
314
+ }
315
+
316
+ _adaptMCP(layers) {
317
+ const systemPrompt = this._adaptSystemPrompt(layers);
318
+ return {
319
+ type: 'mcp_context',
320
+ system_prefix: systemPrompt.content,
321
+ tool_context: layers.credentials || {},
322
+ };
323
+ }
324
+
325
+ _adaptWordPress(layers) {
326
+ const systemPrompt = this._adaptSystemPrompt(layers);
327
+ return {
328
+ type: 'wordpress_onpress',
329
+ chat_system_prompt: systemPrompt.content,
330
+ theme_colors: layers.visual_identity || {},
331
+ business_info: layers.business_structure || {},
332
+ };
333
+ }
334
+
335
+ _adaptSlack(layers) {
336
+ const systemPrompt = this._adaptSystemPrompt(layers);
337
+ return {
338
+ type: 'slack_bot',
339
+ bot_personality: systemPrompt.content,
340
+ slash_commands: this._generateSlashCommands(layers),
341
+ };
342
+ }
343
+
344
+ _extractKnowledgeFiles(layers) {
345
+ const files = [];
346
+ if (layers.domain_knowledge?.procedures?.length) {
347
+ files.push({ name: 'procedures.md', content: layers.domain_knowledge.procedures.join('\n\n---\n\n') });
348
+ }
349
+ if (layers.domain_knowledge?.faq_pairs?.length) {
350
+ const faqContent = layers.domain_knowledge.faq_pairs.map(f => `## ${f.q}\n\n${f.a}`).join('\n\n');
351
+ files.push({ name: 'faq.md', content: faqContent });
352
+ }
353
+ return files;
354
+ }
355
+
356
+ _generateBrainFile(layers) {
357
+ return {
358
+ format: '0n-brain-v1',
359
+ layers: Object.fromEntries(
360
+ Object.entries(layers).filter(([k]) => k !== 'credentials')
361
+ ),
362
+ generated_at: new Date().toISOString(),
363
+ };
364
+ }
365
+
366
+ _generateSlashCommands(layers) {
367
+ const commands = ['/0n help'];
368
+ if (layers.business_structure?.services?.length) commands.push('/0n services');
369
+ if (layers.business_structure?.hours) commands.push('/0n hours');
370
+ if (layers.credentials?.api_keys?.stripe) commands.push('/0n invoice');
371
+ return commands;
372
+ }
373
+ }
374
+
375
+ // ── Credential Harvester ────────────────────────────────────────────
376
+
377
+ class CredentialHarvester {
378
+
379
+ /**
380
+ * Analyze a set of key-value pairs and identify credentials.
381
+ * Works with .env files, JSON configs, process.env, etc.
382
+ */
383
+ static harvest(keyValuePairs) {
384
+ const discovered = [];
385
+
386
+ for (const [key, value] of Object.entries(keyValuePairs)) {
387
+ if (!value || typeof value !== 'string') continue;
388
+
389
+ for (const pattern of CREDENTIAL_PATTERNS) {
390
+ if (pattern.pattern.test(value)) {
391
+ discovered.push({
392
+ key,
393
+ service: pattern.service,
394
+ name: pattern.name,
395
+ value_preview: value.substring(0, 8) + '...',
396
+ // Actual value stored only in encrypted K6 layer
397
+ });
398
+ break;
399
+ }
400
+ }
401
+ }
402
+
403
+ return discovered;
404
+ }
405
+
406
+ /**
407
+ * Verify a discovered credential by making a health-check API call.
408
+ */
409
+ static async verify(service, value) {
410
+ const healthChecks = {
411
+ anthropic: () => fetch('https://api.anthropic.com/v1/messages', {
412
+ method: 'POST', headers: { 'x-api-key': value, 'anthropic-version': '2023-06-01', 'Content-Type': 'application/json' },
413
+ body: JSON.stringify({ model: 'claude-haiku-4-5-20251001', max_tokens: 1, messages: [{ role: 'user', content: 'hi' }] }),
414
+ }),
415
+ openai: () => fetch('https://api.openai.com/v1/models', { headers: { Authorization: `Bearer ${value}` } }),
416
+ stripe: () => fetch('https://api.stripe.com/v1/balance', { headers: { Authorization: `Bearer ${value}` } }),
417
+ groq: () => fetch('https://api.groq.com/openai/v1/models', { headers: { Authorization: `Bearer ${value}` } }),
418
+ github: () => fetch('https://api.github.com/user', { headers: { Authorization: `Bearer ${value}` } }),
419
+ };
420
+
421
+ const check = healthChecks[service];
422
+ if (!check) return { verified: false, reason: 'No health check available' };
423
+
424
+ try {
425
+ const res = await check();
426
+ return { verified: res.status < 400, status: res.status };
427
+ } catch (err) {
428
+ return { verified: false, reason: err.message };
429
+ }
430
+ }
431
+ }
432
+
433
+ // ── Exports ─────────────────────────────────────────────────────────
434
+
435
+ module.exports = {
436
+ LAYER_SCHEMA,
437
+ CREDENTIAL_PATTERNS,
438
+ KnowledgeLayers,
439
+ CredentialHarvester,
440
+ };
package/lib/stats.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-03-29T20:40:55.698Z",
2
+ "generated": "2026-04-03T09:56:25.359Z",
3
3
  "catalogVersion": "2.2.0",
4
4
  "services": 48,
5
5
  "tools": 545,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0nmcp",
3
- "version": "2.9.2",
3
+ "version": "3.0.1",
4
4
  "mcpName": "io.github.0nork/0nMCP",
5
5
  "description": "Universal AI API Orchestrator — 819 tools, 48 services, portable AI Brain bundles + machine-bound vault encryption + Application Engine. The most comprehensive MCP server available. Free and open source from 0nORK.",
6
6
  "type": "module",
@@ -106,31 +106,25 @@
106
106
  "mcp-server",
107
107
  "model-context-protocol",
108
108
  "ai-orchestrator",
109
+ "ai-tools",
109
110
  "api-integration",
110
111
  "workflow-automation",
112
+ "claude",
113
+ "gpt",
114
+ "gemini",
115
+ "cursor",
116
+ "vscode",
117
+ "slack",
111
118
  "stripe",
112
119
  "crm",
113
- "slack",
114
- "github",
115
- "supabase",
116
- "figma",
117
- "sendgrid",
118
- "twilio",
119
120
  "shopify",
120
- "openai",
121
- "anthropic",
122
- "ai-agent",
123
- "ai-tools",
124
- "universal-api",
125
- "no-code",
126
- "automation",
127
- "saas",
128
- "api-connector",
121
+ "pipedrive",
122
+ "woocommerce",
123
+ "square",
129
124
  "vault",
130
125
  "encryption",
131
- "aes-256",
132
- "capability-routing",
133
- "portable-workflows"
126
+ "0nmcp",
127
+ "0nork"
134
128
  ],
135
129
  "author": {
136
130
  "name": "0nORK",
@@ -205,6 +199,6 @@
205
199
  "triggers": 155,
206
200
  "totalCapabilities": 1078,
207
201
  "categories": 21,
208
- "lastUpdated": "2026-03-29T20:40:55.698Z"
202
+ "lastUpdated": "2026-04-03T09:56:25.359Z"
209
203
  }
210
204
  }