@fentz26/envcp 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 (95) hide show
  1. package/.github/workflows/publish.yml +27 -0
  2. package/LICENSE +21 -0
  3. package/README.md +381 -0
  4. package/dist/adapters/base.d.ts +79 -0
  5. package/dist/adapters/base.d.ts.map +1 -0
  6. package/dist/adapters/base.js +317 -0
  7. package/dist/adapters/base.js.map +1 -0
  8. package/dist/adapters/gemini.d.ts +12 -0
  9. package/dist/adapters/gemini.d.ts.map +1 -0
  10. package/dist/adapters/gemini.js +284 -0
  11. package/dist/adapters/gemini.js.map +1 -0
  12. package/dist/adapters/index.d.ts +5 -0
  13. package/dist/adapters/index.d.ts.map +1 -0
  14. package/dist/adapters/index.js +5 -0
  15. package/dist/adapters/index.js.map +1 -0
  16. package/dist/adapters/openai.d.ts +12 -0
  17. package/dist/adapters/openai.d.ts.map +1 -0
  18. package/dist/adapters/openai.js +294 -0
  19. package/dist/adapters/openai.js.map +1 -0
  20. package/dist/adapters/rest.d.ts +12 -0
  21. package/dist/adapters/rest.d.ts.map +1 -0
  22. package/dist/adapters/rest.js +265 -0
  23. package/dist/adapters/rest.js.map +1 -0
  24. package/dist/cli/index.d.ts +2 -0
  25. package/dist/cli/index.d.ts.map +1 -0
  26. package/dist/cli/index.js +472 -0
  27. package/dist/cli/index.js.map +1 -0
  28. package/dist/cli.d.ts +3 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +3 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/config/manager.d.ts +11 -0
  33. package/dist/config/manager.d.ts.map +1 -0
  34. package/dist/config/manager.js +117 -0
  35. package/dist/config/manager.js.map +1 -0
  36. package/dist/index.d.ts +5 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +5 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/mcp/index.d.ts +2 -0
  41. package/dist/mcp/index.d.ts.map +1 -0
  42. package/dist/mcp/index.js +2 -0
  43. package/dist/mcp/index.js.map +1 -0
  44. package/dist/mcp/server.d.ts +24 -0
  45. package/dist/mcp/server.d.ts.map +1 -0
  46. package/dist/mcp/server.js +539 -0
  47. package/dist/mcp/server.js.map +1 -0
  48. package/dist/server/index.d.ts +2 -0
  49. package/dist/server/index.d.ts.map +1 -0
  50. package/dist/server/index.js +2 -0
  51. package/dist/server/index.js.map +1 -0
  52. package/dist/server/unified.d.ts +21 -0
  53. package/dist/server/unified.d.ts.map +1 -0
  54. package/dist/server/unified.js +397 -0
  55. package/dist/server/unified.js.map +1 -0
  56. package/dist/storage/index.d.ts +23 -0
  57. package/dist/storage/index.d.ts.map +1 -0
  58. package/dist/storage/index.js +92 -0
  59. package/dist/storage/index.js.map +1 -0
  60. package/dist/types.d.ts +404 -0
  61. package/dist/types.d.ts.map +1 -0
  62. package/dist/types.js +92 -0
  63. package/dist/types.js.map +1 -0
  64. package/dist/utils/crypto.d.ts +17 -0
  65. package/dist/utils/crypto.d.ts.map +1 -0
  66. package/dist/utils/crypto.js +73 -0
  67. package/dist/utils/crypto.js.map +1 -0
  68. package/dist/utils/http.d.ts +6 -0
  69. package/dist/utils/http.d.ts.map +1 -0
  70. package/dist/utils/http.js +43 -0
  71. package/dist/utils/http.js.map +1 -0
  72. package/dist/utils/session.d.ts +19 -0
  73. package/dist/utils/session.d.ts.map +1 -0
  74. package/dist/utils/session.js +112 -0
  75. package/dist/utils/session.js.map +1 -0
  76. package/package.json +50 -0
  77. package/src/adapters/base.ts +411 -0
  78. package/src/adapters/gemini.ts +314 -0
  79. package/src/adapters/index.ts +4 -0
  80. package/src/adapters/openai.ts +324 -0
  81. package/src/adapters/rest.ts +294 -0
  82. package/src/cli/index.ts +640 -0
  83. package/src/cli.ts +2 -0
  84. package/src/config/manager.ts +134 -0
  85. package/src/index.ts +4 -0
  86. package/src/mcp/index.ts +1 -0
  87. package/src/mcp/server.ts +623 -0
  88. package/src/server/index.ts +1 -0
  89. package/src/server/unified.ts +460 -0
  90. package/src/storage/index.ts +112 -0
  91. package/src/types.ts +181 -0
  92. package/src/utils/crypto.ts +100 -0
  93. package/src/utils/http.ts +45 -0
  94. package/src/utils/session.ts +141 -0
  95. package/tsconfig.json +20 -0
@@ -0,0 +1,27 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ['v*']
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: actions/setup-node@v4
17
+ with:
18
+ node-version: '20'
19
+ registry-url: 'https://registry.npmjs.org'
20
+
21
+ - run: npm install
22
+
23
+ - run: npm run build
24
+
25
+ - run: npm publish --access=public
26
+ env:
27
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fentz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,381 @@
1
+ # EnvCP
2
+
3
+ **Secure Environment Variable Management for AI-Assisted Coding**
4
+
5
+ EnvCP is a universal tool server that allows developers to safely use AI assistants for coding without exposing sensitive environment variables, API keys, or secrets. Works with Claude, ChatGPT, Gemini, Cursor, and any AI tool.
6
+
7
+ ## Why EnvCP?
8
+
9
+ When using AI coding assistants, you often need to reference environment variables, API keys, or other secrets. But you don't want to share these with the AI. EnvCP solves this by:
10
+
11
+ - **Local-only storage** - Your secrets never leave your machine
12
+ - **Encrypted at rest** - AES-256-GCM encryption with PBKDF2 key derivation (100,000 iterations)
13
+ - **Reference-based access** - AI references variables by name, never sees the actual values
14
+ - **Automatic .env injection** - Values can be automatically injected into your .env files
15
+ - **AI Access Control** - Block AI from proactively checking or listing your secrets
16
+ - **Universal Compatibility** - Works with any AI tool via multiple protocols
17
+
18
+ ## Platform Compatibility
19
+
20
+ | Platform | Support | Protocol |
21
+ |----------|---------|----------|
22
+ | Claude Desktop | Native | MCP |
23
+ | Claude Code | Native | MCP |
24
+ | Cursor | Native | MCP |
25
+ | Cline (VS Code) | Native | MCP |
26
+ | Continue.dev | Native | MCP |
27
+ | Zed Editor | Native | MCP |
28
+ | ChatGPT | Via API | OpenAI Function Calling |
29
+ | GPT-4 API | Via API | OpenAI Function Calling |
30
+ | Gemini | Via API | Google Function Calling |
31
+ | Gemini API | Via API | Google Function Calling |
32
+ | Local LLMs (Ollama) | Via API | REST / OpenAI-compatible |
33
+ | LM Studio | Via API | REST / OpenAI-compatible |
34
+ | Open WebUI | Via API | REST |
35
+ | Any HTTP Client | Via API | REST |
36
+
37
+ ## Features
38
+
39
+ - **Multi-Protocol Support** - MCP, REST API, OpenAI, and Gemini protocols
40
+ - **Auto-Detection** - Automatically detects client type from request headers
41
+ - **AES-256-GCM Encryption** - Military-grade encryption with PBKDF2-SHA512 key derivation
42
+ - **Flexible Passwords** - No complexity requirements - use any password you want
43
+ - **Session Management** - Quick password mode with configurable session duration
44
+ - **AI Access Control** - Prevent AI from actively checking variables without permission
45
+ - **Blacklist Patterns** - Block AI access to sensitive variables matching patterns
46
+ - **Project-based Organization** - Separate environments per project
47
+ - **Auto .env Sync** - Automatically sync to .env files
48
+ - **Audit Logging** - All operations logged for security review
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ npm install -g envcp
54
+ ```
55
+
56
+ Or use with npx:
57
+
58
+ ```bash
59
+ npx envcp init
60
+ ```
61
+
62
+ ## Quick Start
63
+
64
+ ### 1. Initialize EnvCP in your project
65
+
66
+ ```bash
67
+ envcp init
68
+ ```
69
+
70
+ ### 2. Add your secrets
71
+
72
+ ```bash
73
+ envcp add API_KEY --value "your-secret-key"
74
+ envcp add DATABASE_URL --value "postgres://..."
75
+ ```
76
+
77
+ ### 3. Start the server
78
+
79
+ ```bash
80
+ # Auto mode - detects client type automatically (recommended)
81
+ envcp serve --mode auto --port 3456
82
+
83
+ # Or specific modes:
84
+ envcp serve --mode mcp # For Claude Desktop, Cursor, etc.
85
+ envcp serve --mode rest # For REST API clients
86
+ envcp serve --mode openai # For ChatGPT/OpenAI-compatible
87
+ envcp serve --mode gemini # For Google Gemini
88
+ envcp serve --mode all # All protocols on same port
89
+ ```
90
+
91
+ ## Integration Guides
92
+
93
+ ### Claude Desktop / Cursor / Cline (MCP)
94
+
95
+ Add to your config file:
96
+
97
+ ```json
98
+ {
99
+ "mcpServers": {
100
+ "envcp": {
101
+ "command": "npx",
102
+ "args": ["envcp", "serve", "--mode", "mcp"]
103
+ }
104
+ }
105
+ }
106
+ ```
107
+
108
+ ### ChatGPT / OpenAI API
109
+
110
+ Start the server in OpenAI mode:
111
+
112
+ ```bash
113
+ envcp serve --mode openai --port 3456 --api-key your-secret-key
114
+ ```
115
+
116
+ Use with OpenAI client:
117
+
118
+ ```python
119
+ import openai
120
+
121
+ # Point to EnvCP server
122
+ client = openai.OpenAI(
123
+ base_url="http://localhost:3456/v1",
124
+ api_key="your-secret-key"
125
+ )
126
+
127
+ # Get available functions
128
+ functions = client.get("/functions")
129
+
130
+ # Call a function
131
+ result = client.post("/functions/call", json={
132
+ "name": "envcp_get",
133
+ "arguments": {"name": "API_KEY"}
134
+ })
135
+ ```
136
+
137
+ ### Gemini / Google AI
138
+
139
+ Start the server in Gemini mode:
140
+
141
+ ```bash
142
+ envcp serve --mode gemini --port 3456 --api-key your-secret-key
143
+ ```
144
+
145
+ Use with Gemini:
146
+
147
+ ```python
148
+ import requests
149
+
150
+ # Get available tools
151
+ tools = requests.get(
152
+ "http://localhost:3456/v1/tools",
153
+ headers={"X-Goog-Api-Key": "your-secret-key"}
154
+ ).json()
155
+
156
+ # Call a function
157
+ result = requests.post(
158
+ "http://localhost:3456/v1/functions/call",
159
+ headers={"X-Goog-Api-Key": "your-secret-key"},
160
+ json={"name": "envcp_get", "args": {"name": "API_KEY"}}
161
+ ).json()
162
+ ```
163
+
164
+ ### Local LLMs (Ollama, LM Studio)
165
+
166
+ For local LLMs, use REST API mode or OpenAI-compatible mode:
167
+
168
+ ```bash
169
+ # REST API (universal)
170
+ envcp serve --mode rest --port 3456
171
+
172
+ # OpenAI-compatible (works with most local LLM tools)
173
+ envcp serve --mode openai --port 3456
174
+ ```
175
+
176
+ Then configure your LLM tool to use `http://localhost:3456` as the tool server.
177
+
178
+ ### REST API (Universal)
179
+
180
+ Start the server:
181
+
182
+ ```bash
183
+ envcp serve --mode rest --port 3456 --api-key your-secret-key
184
+ ```
185
+
186
+ Endpoints:
187
+
188
+ ```
189
+ GET /api/health - Health check
190
+ GET /api/variables - List variables
191
+ GET /api/variables/:name - Get variable
192
+ POST /api/variables - Create variable
193
+ PUT /api/variables/:name - Update variable
194
+ DELETE /api/variables/:name - Delete variable
195
+ POST /api/sync - Sync to .env
196
+ POST /api/run - Run command with env vars
197
+ GET /api/tools - List available tools
198
+ POST /api/tools/:name - Call tool by name
199
+ ```
200
+
201
+ Example:
202
+
203
+ ```bash
204
+ # List variables
205
+ curl -H "X-API-Key: your-secret-key" http://localhost:3456/api/variables
206
+
207
+ # Get a variable
208
+ curl -H "X-API-Key: your-secret-key" http://localhost:3456/api/variables/API_KEY
209
+
210
+ # Create a variable
211
+ curl -X POST -H "X-API-Key: your-secret-key" \
212
+ -H "Content-Type: application/json" \
213
+ -d '{"name": "NEW_VAR", "value": "secret123"}' \
214
+ http://localhost:3456/api/variables
215
+ ```
216
+
217
+ ## Server Modes
218
+
219
+ | Mode | Description | Use Case |
220
+ |------|-------------|----------|
221
+ | `mcp` | Model Context Protocol (stdio) | Claude Desktop, Cursor, Cline |
222
+ | `rest` | REST API (HTTP) | Any HTTP client, custom integrations |
223
+ | `openai` | OpenAI function calling format | ChatGPT, GPT-4 API, OpenAI-compatible tools |
224
+ | `gemini` | Google function calling format | Gemini, Google AI |
225
+ | `all` | All HTTP protocols on same port | Multiple clients |
226
+ | `auto` | Auto-detect client from headers | Universal (recommended for HTTP) |
227
+
228
+ ## CLI Commands
229
+
230
+ ```bash
231
+ # Initialize
232
+ envcp init [options]
233
+
234
+ # Session Management
235
+ envcp unlock # Unlock session with password
236
+ envcp lock # Lock session immediately
237
+ envcp status # Check session status
238
+ envcp extend [minutes] # Extend session duration
239
+
240
+ # Variable Management
241
+ envcp add <name> [options]
242
+ envcp list [--show-values]
243
+ envcp get <name>
244
+ envcp remove <name>
245
+
246
+ # Sync and Export
247
+ envcp sync # Sync to .env file
248
+ envcp export [--format env|json|yaml]
249
+
250
+ # Server
251
+ envcp serve [options]
252
+ --mode, -m Server mode: mcp, rest, openai, gemini, all, auto
253
+ --port HTTP port (default: 3456)
254
+ --host HTTP host (default: 127.0.0.1)
255
+ --api-key, -k API key for authentication
256
+ --password, -p Encryption password
257
+ ```
258
+
259
+ ## Configuration
260
+
261
+ ### envcp.yaml
262
+
263
+ ```yaml
264
+ version: "1.0"
265
+ project: my-project
266
+
267
+ storage:
268
+ path: .envcp/store.enc
269
+ encrypted: true
270
+ algorithm: aes-256-gcm
271
+
272
+ session:
273
+ enabled: true
274
+ timeout: 1800 # 30 minutes
275
+
276
+ access:
277
+ allow_ai_read: true
278
+ allow_ai_write: false
279
+ allow_ai_active_check: false # Prevent AI from proactively listing
280
+ require_confirmation: true
281
+ blacklist:
282
+ - "*_SECRET"
283
+ - "*_PRIVATE"
284
+ - "ADMIN_*"
285
+
286
+ password:
287
+ min_length: 1 # No requirements by default
288
+ require_uppercase: false
289
+ require_lowercase: false
290
+ require_numbers: false
291
+ require_special: false
292
+
293
+ sync:
294
+ enabled: true
295
+ target: .env
296
+ exclude:
297
+ - "*_PRIVATE"
298
+ - "*_SECRET"
299
+ ```
300
+
301
+ ## Available Tools
302
+
303
+ All protocols expose the same tools:
304
+
305
+ | Tool | Description |
306
+ |------|-------------|
307
+ | `envcp_list` | List variable names (not values) |
308
+ | `envcp_get` | Get a variable (masked by default) |
309
+ | `envcp_set` | Create/update a variable |
310
+ | `envcp_delete` | Delete a variable |
311
+ | `envcp_sync` | Sync to .env file |
312
+ | `envcp_run` | Run command with env vars injected |
313
+ | `envcp_check_access` | Check if variable is accessible |
314
+
315
+ ## AI Access Control
316
+
317
+ ### Disable Active Checking
318
+
319
+ Prevent AI from proactively listing your variables:
320
+
321
+ ```yaml
322
+ access:
323
+ allow_ai_active_check: false
324
+ ```
325
+
326
+ ### Blacklist Patterns
327
+
328
+ Block AI from accessing sensitive variables:
329
+
330
+ ```yaml
331
+ access:
332
+ blacklist:
333
+ - "*_SECRET"
334
+ - "*_PRIVATE"
335
+ - "ADMIN_*"
336
+ - "ROOT_*"
337
+ ```
338
+
339
+ ## Security
340
+
341
+ ### Encryption
342
+
343
+ - **Cipher**: AES-256-GCM
344
+ - **Key Derivation**: PBKDF2-SHA512 (100,000 iterations)
345
+ - **Salt**: 64 bytes per encryption
346
+ - **IV**: 16 bytes per encryption
347
+ - **Auth Tag**: 16 bytes for integrity
348
+
349
+ ### API Authentication
350
+
351
+ When using HTTP modes, always set an API key:
352
+
353
+ ```bash
354
+ envcp serve --mode rest --api-key your-secret-key
355
+ ```
356
+
357
+ Clients must include the key in requests:
358
+
359
+ ```
360
+ X-API-Key: your-secret-key
361
+ # or
362
+ Authorization: Bearer your-secret-key
363
+ ```
364
+
365
+ ## Best Practices
366
+
367
+ 1. **Never commit `.envcp/`** - Add to `.gitignore`
368
+ 2. **Use API keys for HTTP modes** - Protect your server endpoints
369
+ 3. **Disable `allow_ai_active_check`** - Prevent AI from probing for variables
370
+ 4. **Use blacklist patterns** - Block sensitive variable patterns
371
+ 5. **Use `auto` mode for HTTP** - Let EnvCP detect the client type
372
+ 6. **Review access logs** - Check `.envcp/logs/` regularly
373
+
374
+ ## License
375
+
376
+ MIT License - See LICENSE file for details.
377
+
378
+ ## Support
379
+
380
+ - GitHub Issues: https://github.com/fentz26/EnvCP/issues
381
+ - Documentation: https://github.com/fentz26/EnvCP/wiki
@@ -0,0 +1,79 @@
1
+ import { StorageManager, LogManager } from '../storage/index.js';
2
+ import { EnvCPConfig, ToolDefinition } from '../types.js';
3
+ import { SessionManager } from '../utils/session.js';
4
+ export declare abstract class BaseAdapter {
5
+ protected storage: StorageManager;
6
+ protected logs: LogManager;
7
+ protected sessionManager: SessionManager;
8
+ protected config: EnvCPConfig;
9
+ protected projectPath: string;
10
+ protected tools: Map<string, ToolDefinition>;
11
+ constructor(config: EnvCPConfig, projectPath: string, password?: string);
12
+ protected abstract registerTools(): void;
13
+ init(): Promise<void>;
14
+ protected ensurePassword(): Promise<void>;
15
+ getToolDefinitions(): ToolDefinition[];
16
+ callTool(name: string, params: Record<string, unknown>): Promise<unknown>;
17
+ protected listVariables(args: {
18
+ tags?: string[];
19
+ }): Promise<{
20
+ variables: string[];
21
+ count: number;
22
+ }>;
23
+ protected getVariable(args: {
24
+ name: string;
25
+ show_value?: boolean;
26
+ }): Promise<{
27
+ name: string;
28
+ value: string;
29
+ tags?: string[];
30
+ description?: string;
31
+ encrypted: boolean;
32
+ }>;
33
+ protected setVariable(args: {
34
+ name: string;
35
+ value: string;
36
+ tags?: string[];
37
+ description?: string;
38
+ }): Promise<{
39
+ success: boolean;
40
+ message: string;
41
+ }>;
42
+ protected deleteVariable(args: {
43
+ name: string;
44
+ }): Promise<{
45
+ success: boolean;
46
+ message: string;
47
+ }>;
48
+ protected syncToEnv(): Promise<{
49
+ success: boolean;
50
+ message: string;
51
+ }>;
52
+ protected addToEnv(args: {
53
+ name: string;
54
+ env_file?: string;
55
+ }): Promise<{
56
+ success: boolean;
57
+ message: string;
58
+ }>;
59
+ protected checkAccess(args: {
60
+ name: string;
61
+ }): Promise<{
62
+ name: string;
63
+ exists: boolean;
64
+ accessible: boolean;
65
+ blacklisted: boolean;
66
+ message: string;
67
+ }>;
68
+ private parseCommand;
69
+ private validateCommand;
70
+ protected runCommand(args: {
71
+ command: string;
72
+ variables: string[];
73
+ }): Promise<{
74
+ exitCode: number | null;
75
+ stdout: string;
76
+ stderr: string;
77
+ }>;
78
+ }
79
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"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"}