polydev-ai 1.4.0 → 1.4.2
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.
- package/README.md +121 -320
- package/package.json +29 -84
- package/{mcp/stdio-wrapper.js → stdio-wrapper.js} +9 -4
- package/lib/cliManager.ts +0 -755
- package/lib/smartCliCache.ts +0 -189
- package/lib/universalMemoryExtractor.js +0 -607
- package/lib/zeroKnowledgeEncryption.js +0 -289
- package/mcp/README.md +0 -160
- package/mcp/package.json +0 -46
- package/mcp/server.js +0 -959
- package/mcp/stdio-wrapper-fixed.js +0 -169
- /package/{lib/cliManager.js → cliManager.js} +0 -0
- /package/{mcp/manifest.json → manifest.json} +0 -0
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Zero-Knowledge Client-Side Encryption System
|
|
4
|
-
* All encryption keys never leave the user's browser
|
|
5
|
-
* Enterprise-grade AES-256-GCM encryption with automatic key rotation
|
|
6
|
-
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.zkEncryption = exports.ZeroKnowledgeEncryption = void 0;
|
|
9
|
-
class ZeroKnowledgeEncryption {
|
|
10
|
-
constructor() {
|
|
11
|
-
this.db = null;
|
|
12
|
-
this.activeKey = null;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Initialize the encryption system
|
|
16
|
-
*/
|
|
17
|
-
async initialize() {
|
|
18
|
-
await this.initializeIndexedDB();
|
|
19
|
-
await this.loadOrCreateActiveKey();
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Initialize IndexedDB for local key storage
|
|
23
|
-
*/
|
|
24
|
-
async initializeIndexedDB() {
|
|
25
|
-
return new Promise((resolve, reject) => {
|
|
26
|
-
const request = indexedDB.open(ZeroKnowledgeEncryption.DB_NAME, ZeroKnowledgeEncryption.DB_VERSION);
|
|
27
|
-
request.onerror = () => reject(request.error);
|
|
28
|
-
request.onsuccess = () => {
|
|
29
|
-
this.db = request.result;
|
|
30
|
-
resolve();
|
|
31
|
-
};
|
|
32
|
-
request.onupgradeneeded = (event) => {
|
|
33
|
-
const db = event.target.result;
|
|
34
|
-
// Store for encryption keys (never synchronized)
|
|
35
|
-
if (!db.objectStoreNames.contains('keys')) {
|
|
36
|
-
const keyStore = db.createObjectStore('keys', { keyPath: 'keyId' });
|
|
37
|
-
keyStore.createIndex('created', 'created', { unique: false });
|
|
38
|
-
}
|
|
39
|
-
// Cache for encrypted data
|
|
40
|
-
if (!db.objectStoreNames.contains('cache')) {
|
|
41
|
-
const cacheStore = db.createObjectStore('cache', { keyPath: 'id' });
|
|
42
|
-
cacheStore.createIndex('expires', 'expires', { unique: false });
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Generate new AES-256-GCM encryption key
|
|
49
|
-
*/
|
|
50
|
-
async generateKey() {
|
|
51
|
-
const keyId = this.generateKeyId();
|
|
52
|
-
const key = await window.crypto.subtle.generateKey({
|
|
53
|
-
name: ZeroKnowledgeEncryption.ALGORITHM,
|
|
54
|
-
length: ZeroKnowledgeEncryption.KEY_LENGTH,
|
|
55
|
-
}, true, // extractable for storage
|
|
56
|
-
['encrypt', 'decrypt']);
|
|
57
|
-
const now = new Date();
|
|
58
|
-
const rotationDue = new Date(now.getTime() + (ZeroKnowledgeEncryption.KEY_ROTATION_DAYS * 24 * 60 * 60 * 1000));
|
|
59
|
-
return {
|
|
60
|
-
keyId,
|
|
61
|
-
key,
|
|
62
|
-
created: now,
|
|
63
|
-
rotationDue
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Load active key or create new one
|
|
68
|
-
*/
|
|
69
|
-
async loadOrCreateActiveKey() {
|
|
70
|
-
if (!this.db)
|
|
71
|
-
throw new Error('Database not initialized');
|
|
72
|
-
const transaction = this.db.transaction(['keys'], 'readonly');
|
|
73
|
-
const store = transaction.objectStore('keys');
|
|
74
|
-
// Get the most recent key
|
|
75
|
-
const index = store.index('created');
|
|
76
|
-
const request = index.openCursor(null, 'prev');
|
|
77
|
-
return new Promise((resolve) => {
|
|
78
|
-
request.onsuccess = async (event) => {
|
|
79
|
-
const cursor = event.target.result;
|
|
80
|
-
if (cursor) {
|
|
81
|
-
const keyData = cursor.value;
|
|
82
|
-
// Check if key needs rotation
|
|
83
|
-
if (new Date() > new Date(keyData.rotationDue)) {
|
|
84
|
-
console.log('[ZK Encryption] Key rotation needed, generating new key');
|
|
85
|
-
await this.createAndStoreKey();
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
// Import existing key
|
|
89
|
-
const keyBuffer = new Uint8Array(keyData.keyBuffer);
|
|
90
|
-
this.activeKey = {
|
|
91
|
-
keyId: keyData.keyId,
|
|
92
|
-
key: await window.crypto.subtle.importKey('raw', keyBuffer, { name: ZeroKnowledgeEncryption.ALGORITHM }, true, ['encrypt', 'decrypt']),
|
|
93
|
-
created: new Date(keyData.created),
|
|
94
|
-
rotationDue: new Date(keyData.rotationDue)
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
// No keys exist, create first one
|
|
100
|
-
await this.createAndStoreKey();
|
|
101
|
-
}
|
|
102
|
-
resolve();
|
|
103
|
-
};
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Create and store new key
|
|
108
|
-
*/
|
|
109
|
-
async createAndStoreKey() {
|
|
110
|
-
this.activeKey = await this.generateKey();
|
|
111
|
-
await this.storeKey(this.activeKey);
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Store key in IndexedDB
|
|
115
|
-
*/
|
|
116
|
-
async storeKey(userKey) {
|
|
117
|
-
if (!this.db)
|
|
118
|
-
throw new Error('Database not initialized');
|
|
119
|
-
const keyBuffer = await window.crypto.subtle.exportKey('raw', userKey.key);
|
|
120
|
-
const transaction = this.db.transaction(['keys'], 'readwrite');
|
|
121
|
-
const store = transaction.objectStore('keys');
|
|
122
|
-
await store.put({
|
|
123
|
-
keyId: userKey.keyId,
|
|
124
|
-
keyBuffer: Array.from(new Uint8Array(keyBuffer)),
|
|
125
|
-
created: userKey.created.toISOString(),
|
|
126
|
-
rotationDue: userKey.rotationDue.toISOString()
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Encrypt sensitive data
|
|
131
|
-
*/
|
|
132
|
-
async encrypt(plaintext) {
|
|
133
|
-
if (!this.activeKey)
|
|
134
|
-
throw new Error('Encryption key not available');
|
|
135
|
-
const encoder = new TextEncoder();
|
|
136
|
-
const data = encoder.encode(plaintext);
|
|
137
|
-
const iv = window.crypto.getRandomValues(new Uint8Array(ZeroKnowledgeEncryption.IV_LENGTH));
|
|
138
|
-
const encrypted = await window.crypto.subtle.encrypt({
|
|
139
|
-
name: ZeroKnowledgeEncryption.ALGORITHM,
|
|
140
|
-
iv: iv,
|
|
141
|
-
}, this.activeKey.key, data);
|
|
142
|
-
const encryptedArray = new Uint8Array(encrypted);
|
|
143
|
-
const ciphertext = encryptedArray.slice(0, -ZeroKnowledgeEncryption.AUTH_TAG_LENGTH);
|
|
144
|
-
const authTag = encryptedArray.slice(-ZeroKnowledgeEncryption.AUTH_TAG_LENGTH);
|
|
145
|
-
return {
|
|
146
|
-
ciphertext: this.arrayBufferToBase64(ciphertext.buffer),
|
|
147
|
-
iv: this.arrayBufferToBase64(iv.buffer),
|
|
148
|
-
authTag: this.arrayBufferToBase64(authTag.buffer),
|
|
149
|
-
keyId: this.activeKey.keyId,
|
|
150
|
-
version: 1
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Decrypt sensitive data
|
|
155
|
-
*/
|
|
156
|
-
async decrypt(encryptedData) {
|
|
157
|
-
const key = await this.getKeyById(encryptedData.keyId);
|
|
158
|
-
if (!key)
|
|
159
|
-
throw new Error(`Encryption key ${encryptedData.keyId} not found`);
|
|
160
|
-
const ciphertext = this.base64ToArrayBuffer(encryptedData.ciphertext);
|
|
161
|
-
const iv = this.base64ToArrayBuffer(encryptedData.iv);
|
|
162
|
-
const authTag = this.base64ToArrayBuffer(encryptedData.authTag);
|
|
163
|
-
// Combine ciphertext and auth tag for Web Crypto API
|
|
164
|
-
const combined = new Uint8Array(ciphertext.byteLength + authTag.byteLength);
|
|
165
|
-
combined.set(new Uint8Array(ciphertext));
|
|
166
|
-
combined.set(new Uint8Array(authTag), ciphertext.byteLength);
|
|
167
|
-
const decrypted = await window.crypto.subtle.decrypt({
|
|
168
|
-
name: ZeroKnowledgeEncryption.ALGORITHM,
|
|
169
|
-
iv: new Uint8Array(iv),
|
|
170
|
-
}, key, combined);
|
|
171
|
-
const decoder = new TextDecoder();
|
|
172
|
-
return decoder.decode(decrypted);
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Get encryption key by ID
|
|
176
|
-
*/
|
|
177
|
-
async getKeyById(keyId) {
|
|
178
|
-
if (!this.db)
|
|
179
|
-
return null;
|
|
180
|
-
const transaction = this.db.transaction(['keys'], 'readonly');
|
|
181
|
-
const store = transaction.objectStore('keys');
|
|
182
|
-
const request = store.get(keyId);
|
|
183
|
-
return new Promise((resolve) => {
|
|
184
|
-
request.onsuccess = async () => {
|
|
185
|
-
if (request.result) {
|
|
186
|
-
const keyBuffer = new Uint8Array(request.result.keyBuffer);
|
|
187
|
-
const key = await window.crypto.subtle.importKey('raw', keyBuffer, { name: ZeroKnowledgeEncryption.ALGORITHM }, true, ['encrypt', 'decrypt']);
|
|
188
|
-
resolve(key);
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
resolve(null);
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
request.onerror = () => resolve(null);
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Create SHA-256 hash for content deduplication
|
|
199
|
-
*/
|
|
200
|
-
async createContentHash(content) {
|
|
201
|
-
const encoder = new TextEncoder();
|
|
202
|
-
const data = encoder.encode(content);
|
|
203
|
-
const hashBuffer = await window.crypto.subtle.digest('SHA-256', data);
|
|
204
|
-
return this.arrayBufferToHex(hashBuffer);
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Check if key rotation is needed
|
|
208
|
-
*/
|
|
209
|
-
isRotationDue() {
|
|
210
|
-
return this.activeKey ? new Date() > this.activeKey.rotationDue : true;
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Force key rotation
|
|
214
|
-
*/
|
|
215
|
-
async rotateKeys() {
|
|
216
|
-
await this.createAndStoreKey();
|
|
217
|
-
console.log('[ZK Encryption] Key rotation completed');
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Generate unique key ID
|
|
221
|
-
*/
|
|
222
|
-
generateKeyId() {
|
|
223
|
-
const timestamp = Date.now().toString(36);
|
|
224
|
-
const random = Math.random().toString(36).substr(2, 9);
|
|
225
|
-
return `zk_${timestamp}_${random}`;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Utility: ArrayBuffer to Base64
|
|
229
|
-
*/
|
|
230
|
-
arrayBufferToBase64(buffer) {
|
|
231
|
-
const bytes = new Uint8Array(buffer);
|
|
232
|
-
let binary = '';
|
|
233
|
-
for (let i = 0; i < bytes.byteLength; i++) {
|
|
234
|
-
binary += String.fromCharCode(bytes[i]);
|
|
235
|
-
}
|
|
236
|
-
return btoa(binary);
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Utility: Base64 to ArrayBuffer
|
|
240
|
-
*/
|
|
241
|
-
base64ToArrayBuffer(base64) {
|
|
242
|
-
const binary = atob(base64);
|
|
243
|
-
const bytes = new Uint8Array(binary.length);
|
|
244
|
-
for (let i = 0; i < binary.length; i++) {
|
|
245
|
-
bytes[i] = binary.charCodeAt(i);
|
|
246
|
-
}
|
|
247
|
-
return bytes.buffer;
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Utility: ArrayBuffer to Hex
|
|
251
|
-
*/
|
|
252
|
-
arrayBufferToHex(buffer) {
|
|
253
|
-
const bytes = new Uint8Array(buffer);
|
|
254
|
-
return Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Get encryption status for dashboard
|
|
258
|
-
*/
|
|
259
|
-
getEncryptionStatus() {
|
|
260
|
-
return {
|
|
261
|
-
keyId: this.activeKey?.keyId || null,
|
|
262
|
-
created: this.activeKey?.created || null,
|
|
263
|
-
rotationDue: this.activeKey?.rotationDue || null,
|
|
264
|
-
rotationNeeded: this.isRotationDue()
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Clear all keys (for user logout/reset)
|
|
269
|
-
*/
|
|
270
|
-
async clearAllKeys() {
|
|
271
|
-
if (!this.db)
|
|
272
|
-
return;
|
|
273
|
-
const transaction = this.db.transaction(['keys', 'cache'], 'readwrite');
|
|
274
|
-
await transaction.objectStore('keys').clear();
|
|
275
|
-
await transaction.objectStore('cache').clear();
|
|
276
|
-
this.activeKey = null;
|
|
277
|
-
console.log('[ZK Encryption] All keys cleared');
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
exports.ZeroKnowledgeEncryption = ZeroKnowledgeEncryption;
|
|
281
|
-
ZeroKnowledgeEncryption.ALGORITHM = 'AES-GCM';
|
|
282
|
-
ZeroKnowledgeEncryption.KEY_LENGTH = 256;
|
|
283
|
-
ZeroKnowledgeEncryption.IV_LENGTH = 12;
|
|
284
|
-
ZeroKnowledgeEncryption.AUTH_TAG_LENGTH = 16;
|
|
285
|
-
ZeroKnowledgeEncryption.KEY_ROTATION_DAYS = 30;
|
|
286
|
-
ZeroKnowledgeEncryption.DB_NAME = 'PolydevZKMemory';
|
|
287
|
-
ZeroKnowledgeEncryption.DB_VERSION = 1;
|
|
288
|
-
// Export singleton instance
|
|
289
|
-
exports.zkEncryption = new ZeroKnowledgeEncryption();
|
package/mcp/README.md
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
# Polydev AI MCP Server
|
|
2
|
-
|
|
3
|
-
Get diverse AI perspectives from multiple LLMs via Model Context Protocol (MCP). Supports Cline, Claude Code, and other MCP clients with local CLI detection and remote AI perspectives.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🤖 **Multi-Model AI Perspectives**: Get responses from GPT-4, Claude, Gemini, and more
|
|
8
|
-
- 🔧 **Local CLI Detection**: Automatically detect and use Claude Code, Codex CLI, Gemini CLI
|
|
9
|
-
- ⚡ **Smart Caching**: Intelligent refresh intervals based on CLI status
|
|
10
|
-
- 🔄 **Fallback Support**: Local CLI + remote perspectives for comprehensive responses
|
|
11
|
-
- 🔐 **Secure**: Token-based authentication with your Polydev account
|
|
12
|
-
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
### For Claude Code Users
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
# Install globally
|
|
19
|
-
npm install -g polydev-ai
|
|
20
|
-
|
|
21
|
-
# Or use directly with npx
|
|
22
|
-
npx polydev-ai
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### For Cline Users
|
|
26
|
-
|
|
27
|
-
Add to your MCP settings (`.cline/mcp_servers.json`):
|
|
28
|
-
|
|
29
|
-
```json
|
|
30
|
-
{
|
|
31
|
-
"mcpServers": {
|
|
32
|
-
"polydev": {
|
|
33
|
-
"command": "npx",
|
|
34
|
-
"args": ["polydev-ai"],
|
|
35
|
-
"env": {
|
|
36
|
-
"POLYDEV_USER_TOKEN": "your_token_here"
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Configuration
|
|
44
|
-
|
|
45
|
-
### Get Your Token
|
|
46
|
-
|
|
47
|
-
1. Sign up at [polydev.ai](https://polydev.ai)
|
|
48
|
-
2. Go to your dashboard and copy your MCP token
|
|
49
|
-
3. Set the environment variable:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
export POLYDEV_USER_TOKEN="pd_your_token_here"
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Claude Code Integration
|
|
56
|
-
|
|
57
|
-
Add to your Claude Code MCP configuration:
|
|
58
|
-
|
|
59
|
-
```json
|
|
60
|
-
"polydev": {
|
|
61
|
-
"disabled": false,
|
|
62
|
-
"timeout": 120,
|
|
63
|
-
"type": "http",
|
|
64
|
-
"url": "https://www.polydev.ai/api/mcp"
|
|
65
|
-
},
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Available Tools
|
|
69
|
-
|
|
70
|
-
- `get_perspectives` - Get AI responses from multiple models
|
|
71
|
-
- `force_cli_detection` - Force detection of local CLI tools
|
|
72
|
-
- `get_cli_status` - Check status of CLI tools (Claude Code, Codex, Gemini)
|
|
73
|
-
- `send_cli_prompt` - Send prompts to local CLI with perspectives fallback
|
|
74
|
-
|
|
75
|
-
## Usage Examples
|
|
76
|
-
|
|
77
|
-
### Get Multi-Model Perspectives
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
// Use the get_perspectives tool
|
|
81
|
-
{
|
|
82
|
-
"prompt": "How do I optimize React performance?",
|
|
83
|
-
"models": ["gpt-4", "claude-3-sonnet", "gemini-pro"]
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Check CLI Status
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
// Check all CLI tools
|
|
91
|
-
await get_cli_status({})
|
|
92
|
-
|
|
93
|
-
// Check specific tool
|
|
94
|
-
await get_cli_status({ provider_id: "claude_code" })
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Send CLI Prompt with Fallback
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
await send_cli_prompt({
|
|
101
|
-
provider_id: "claude_code",
|
|
102
|
-
prompt: "Write a Python function to parse JSON",
|
|
103
|
-
mode: "args"
|
|
104
|
-
})
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Supported CLI Tools
|
|
108
|
-
|
|
109
|
-
- **Claude Code** (`claude`) - Anthropic's official CLI
|
|
110
|
-
- **Codex CLI** (`codex`) - OpenAI's code CLI
|
|
111
|
-
- **Gemini CLI** (`gemini`) - Google's Gemini CLI
|
|
112
|
-
|
|
113
|
-
## Smart Refresh System
|
|
114
|
-
|
|
115
|
-
The MCP server automatically detects CLI status changes:
|
|
116
|
-
|
|
117
|
-
- **Unavailable CLIs**: Check every 2 minutes
|
|
118
|
-
- **Unauthenticated CLIs**: Check every 3 minutes
|
|
119
|
-
- **Working CLIs**: Check every 10 minutes
|
|
120
|
-
- **Fallback detection**: Check every 5 minutes
|
|
121
|
-
|
|
122
|
-
## Environment Variables
|
|
123
|
-
|
|
124
|
-
- `POLYDEV_USER_TOKEN` - Your Polydev authentication token (required)
|
|
125
|
-
- `POLYDEV_CLI_DEBUG` - Enable CLI debugging output
|
|
126
|
-
- `CLAUDE_CODE_PATH` - Custom path to Claude Code CLI
|
|
127
|
-
- `CODEX_CLI_PATH` - Custom path to Codex CLI
|
|
128
|
-
- `GEMINI_CLI_PATH` - Custom path to Gemini CLI
|
|
129
|
-
|
|
130
|
-
## Troubleshooting
|
|
131
|
-
|
|
132
|
-
### CLI Not Detected
|
|
133
|
-
|
|
134
|
-
1. Ensure the CLI is installed and in your PATH
|
|
135
|
-
2. Check authentication: `claude auth status` / `codex login status`
|
|
136
|
-
3. Enable debugging: `export POLYDEV_CLI_DEBUG=1`
|
|
137
|
-
|
|
138
|
-
### Token Issues
|
|
139
|
-
|
|
140
|
-
1. Verify your token at [polydev.ai/dashboard](https://polydev.ai/dashboard)
|
|
141
|
-
2. Ensure the token starts with `pd_`
|
|
142
|
-
3. Check environment variable is set correctly
|
|
143
|
-
|
|
144
|
-
### Permission Errors
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
# Fix npm permissions
|
|
148
|
-
npm config set prefix '~/.npm-global'
|
|
149
|
-
export PATH=~/.npm-global/bin:$PATH
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## Support
|
|
153
|
-
|
|
154
|
-
- 📧 Email: [support@polydev.ai](mailto:support@polydev.ai)
|
|
155
|
-
- 📖 Docs: [polydev.ai/docs](https://polydev.ai/docs)
|
|
156
|
-
- 🐛 Issues: [GitHub Issues](https://github.com/backspacevenkat/polydev-website/issues)
|
|
157
|
-
|
|
158
|
-
## License
|
|
159
|
-
|
|
160
|
-
MIT License - see LICENSE file for details.
|
package/mcp/package.json
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "polydev-ai",
|
|
3
|
-
"version": "1.2.6",
|
|
4
|
-
"description": "Get diverse AI perspectives from multiple LLMs via MCP - supports Cline, Claude Code, and other MCP clients",
|
|
5
|
-
"main": "stdio-wrapper.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"polydev-ai": "./stdio-wrapper.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"start": "node server.js",
|
|
11
|
-
"test": "node server.js --help"
|
|
12
|
-
},
|
|
13
|
-
"keywords": [
|
|
14
|
-
"mcp",
|
|
15
|
-
"model-context-protocol",
|
|
16
|
-
"ai",
|
|
17
|
-
"llm",
|
|
18
|
-
"perspectives",
|
|
19
|
-
"multi-model",
|
|
20
|
-
"cline",
|
|
21
|
-
"claude",
|
|
22
|
-
"openai",
|
|
23
|
-
"anthropic",
|
|
24
|
-
"gemini",
|
|
25
|
-
"polydev"
|
|
26
|
-
],
|
|
27
|
-
"author": "Polydev AI <support@polydev.ai>",
|
|
28
|
-
"license": "MIT",
|
|
29
|
-
"engines": {
|
|
30
|
-
"node": ">=16.0.0"
|
|
31
|
-
},
|
|
32
|
-
"files": [
|
|
33
|
-
"stdio-wrapper.js",
|
|
34
|
-
"manifest.json",
|
|
35
|
-
"README.md"
|
|
36
|
-
],
|
|
37
|
-
"repository": {
|
|
38
|
-
"type": "git",
|
|
39
|
-
"url": "https://github.com/backspacevenkat/polydev-website.git",
|
|
40
|
-
"directory": "mcp"
|
|
41
|
-
},
|
|
42
|
-
"homepage": "https://polydev.ai/docs/mcp-integration",
|
|
43
|
-
"bugs": {
|
|
44
|
-
"url": "https://github.com/backspacevenkat/polydev-website/issues"
|
|
45
|
-
}
|
|
46
|
-
}
|