envibe 0.1.1 → 0.2.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.
package/README.md CHANGED
@@ -215,7 +215,14 @@ envibe setup
215
215
  | `env_list` | List visible variables with access levels |
216
216
  | `env_get` | Get a variable's value (respects permissions) |
217
217
  | `env_set` | Set a variable (only `full` access) |
218
- | `env_describe` | Get detailed info about a variable |
218
+ | `env_describe` | Get detailed info including format and example |
219
+ | `env_check_required` | Check which required variables are missing |
220
+
221
+ ### v0.2.0 Features
222
+
223
+ - **Better error messages** - When access is denied, get helpful guidance
224
+ - **Format hints** - Know what format a variable should be (url, key, number, etc.)
225
+ - **Required var checking** - Use `env_check_required` to guide users through setup
219
226
 
220
227
  ## Why envibe?
221
228
 
package/dist/cli/index.js CHANGED
@@ -15588,193 +15588,245 @@ var CLASSIFICATION_PATTERNS = [
15588
15588
  name: "stripe-secret",
15589
15589
  pattern: /^STRIPE_SECRET/i,
15590
15590
  suggestedAccess: "hidden" /* HIDDEN */,
15591
- description: "Stripe secret key"
15591
+ description: "Stripe secret key",
15592
+ format: "key",
15593
+ example: "sk_live_..."
15592
15594
  },
15593
15595
  {
15594
15596
  name: "private-key",
15595
15597
  pattern: /PRIVATE[_-]?KEY/i,
15596
15598
  suggestedAccess: "hidden" /* HIDDEN */,
15597
- description: "Private key material"
15599
+ description: "Private key material",
15600
+ format: "pem",
15601
+ example: "-----BEGIN PRIVATE KEY-----..."
15598
15602
  },
15599
15603
  {
15600
15604
  name: "signing-secret",
15601
15605
  pattern: /SIGNING[_-]?SECRET/i,
15602
15606
  suggestedAccess: "hidden" /* HIDDEN */,
15603
- description: "Signing secret"
15607
+ description: "Signing secret",
15608
+ format: "key"
15604
15609
  },
15605
15610
  {
15606
15611
  name: "api-key",
15607
15612
  pattern: /API[_-]?KEY/i,
15608
15613
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15609
- description: "API key"
15614
+ description: "API key",
15615
+ format: "key",
15616
+ example: "sk-..."
15610
15617
  },
15611
15618
  {
15612
15619
  name: "secret-key",
15613
15620
  pattern: /SECRET[_-]?KEY/i,
15614
15621
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15615
- description: "Secret key"
15622
+ description: "Secret key",
15623
+ format: "key"
15616
15624
  },
15617
15625
  {
15618
15626
  name: "access-key",
15619
15627
  pattern: /ACCESS[_-]?KEY/i,
15620
15628
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15621
- description: "Access key"
15629
+ description: "Access key",
15630
+ format: "key",
15631
+ example: "AKIA..."
15622
15632
  },
15623
15633
  {
15624
15634
  name: "auth-token",
15625
15635
  pattern: /AUTH[_-]?TOKEN/i,
15626
15636
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15627
- description: "Authentication token"
15637
+ description: "Authentication token",
15638
+ format: "token"
15628
15639
  },
15629
15640
  {
15630
15641
  name: "bearer-token",
15631
15642
  pattern: /BEARER[_-]?TOKEN/i,
15632
15643
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15633
- description: "Bearer token"
15644
+ description: "Bearer token",
15645
+ format: "token"
15634
15646
  },
15635
15647
  {
15636
15648
  name: "jwt-secret",
15637
15649
  pattern: /JWT[_-]?SECRET/i,
15638
15650
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15639
- description: "JWT signing secret"
15651
+ description: "JWT signing secret",
15652
+ format: "key"
15640
15653
  },
15641
15654
  {
15642
15655
  name: "password",
15643
15656
  pattern: /PASSWORD/i,
15644
15657
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15645
- description: "Password credential"
15658
+ description: "Password credential",
15659
+ format: "password"
15646
15660
  },
15647
15661
  {
15648
15662
  name: "credential",
15649
15663
  pattern: /CREDENTIAL/i,
15650
15664
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15651
- description: "Credential"
15665
+ description: "Credential",
15666
+ format: "key"
15652
15667
  },
15653
15668
  {
15654
15669
  name: "secret",
15655
15670
  pattern: /SECRET/i,
15656
15671
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15657
- description: "Secret value"
15672
+ description: "Secret value",
15673
+ format: "key"
15658
15674
  },
15659
15675
  {
15660
15676
  name: "token",
15661
15677
  pattern: /TOKEN$/i,
15662
15678
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15663
- description: "Token"
15679
+ description: "Token",
15680
+ format: "token"
15664
15681
  },
15665
15682
  {
15666
15683
  name: "database-url",
15667
15684
  pattern: /DATABASE[_-]?URL/i,
15668
15685
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15669
- description: "Database connection URL (may contain password)"
15686
+ description: "Database connection URL (may contain password)",
15687
+ format: "url",
15688
+ example: "postgres://user:pass@localhost:5432/dbname"
15670
15689
  },
15671
15690
  {
15672
15691
  name: "redis-url",
15673
15692
  pattern: /REDIS[_-]?URL/i,
15674
15693
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15675
- description: "Redis connection URL (may contain password)"
15694
+ description: "Redis connection URL (may contain password)",
15695
+ format: "url",
15696
+ example: "redis://user:pass@localhost:6379/0"
15676
15697
  },
15677
15698
  {
15678
15699
  name: "mongodb-uri",
15679
15700
  pattern: /MONGO(DB)?[_-]?URI/i,
15680
15701
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15681
- description: "MongoDB connection URI (may contain password)"
15702
+ description: "MongoDB connection URI (may contain password)",
15703
+ format: "url",
15704
+ example: "mongodb://user:pass@localhost:27017/dbname"
15682
15705
  },
15683
15706
  {
15684
15707
  name: "connection-string",
15685
15708
  pattern: /CONNECTION[_-]?STRING/i,
15686
15709
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
15687
- description: "Connection string (may contain password)"
15710
+ description: "Connection string (may contain password)",
15711
+ format: "url"
15688
15712
  },
15689
15713
  {
15690
15714
  name: "url-suffix",
15691
15715
  pattern: /_URL$/i,
15692
15716
  suggestedAccess: "read-only" /* READ_ONLY */,
15693
- description: "URL endpoint"
15717
+ description: "URL endpoint",
15718
+ format: "url",
15719
+ example: "https://api.example.com"
15694
15720
  },
15695
15721
  {
15696
15722
  name: "uri-suffix",
15697
15723
  pattern: /_URI$/i,
15698
15724
  suggestedAccess: "read-only" /* READ_ONLY */,
15699
- description: "URI endpoint"
15725
+ description: "URI endpoint",
15726
+ format: "url"
15700
15727
  },
15701
15728
  {
15702
15729
  name: "host",
15703
15730
  pattern: /_HOST$/i,
15704
15731
  suggestedAccess: "read-only" /* READ_ONLY */,
15705
- description: "Host address"
15732
+ description: "Host address",
15733
+ format: "hostname",
15734
+ example: "localhost"
15706
15735
  },
15707
15736
  {
15708
15737
  name: "node-env",
15709
15738
  pattern: /^NODE_ENV$/i,
15710
15739
  suggestedAccess: "full" /* FULL */,
15711
- description: "Node.js environment mode"
15740
+ description: "Node.js environment mode",
15741
+ format: "enum",
15742
+ example: "development | production | test"
15712
15743
  },
15713
15744
  {
15714
15745
  name: "env-suffix",
15715
15746
  pattern: /_ENV$/i,
15716
15747
  suggestedAccess: "full" /* FULL */,
15717
- description: "Environment setting"
15748
+ description: "Environment setting",
15749
+ format: "string"
15718
15750
  },
15719
15751
  {
15720
15752
  name: "debug",
15721
15753
  pattern: /DEBUG/i,
15722
15754
  suggestedAccess: "full" /* FULL */,
15723
- description: "Debug flag"
15755
+ description: "Debug flag",
15756
+ format: "boolean",
15757
+ example: "true | false"
15724
15758
  },
15725
15759
  {
15726
15760
  name: "log-level",
15727
15761
  pattern: /LOG[_-]?LEVEL/i,
15728
15762
  suggestedAccess: "full" /* FULL */,
15729
- description: "Logging level"
15763
+ description: "Logging level",
15764
+ format: "enum",
15765
+ example: "debug | info | warn | error"
15730
15766
  },
15731
15767
  {
15732
15768
  name: "port",
15733
15769
  pattern: /^PORT$/i,
15734
15770
  suggestedAccess: "full" /* FULL */,
15735
- description: "Server port"
15771
+ description: "Server port",
15772
+ format: "number",
15773
+ example: "3000"
15736
15774
  },
15737
15775
  {
15738
15776
  name: "port-suffix",
15739
15777
  pattern: /_PORT$/i,
15740
15778
  suggestedAccess: "full" /* FULL */,
15741
- description: "Port number"
15779
+ description: "Port number",
15780
+ format: "number",
15781
+ example: "5432"
15742
15782
  },
15743
15783
  {
15744
15784
  name: "timeout",
15745
15785
  pattern: /TIMEOUT/i,
15746
15786
  suggestedAccess: "full" /* FULL */,
15747
- description: "Timeout setting"
15787
+ description: "Timeout setting",
15788
+ format: "number",
15789
+ example: "30000"
15748
15790
  },
15749
15791
  {
15750
15792
  name: "max-size",
15751
15793
  pattern: /MAX[_-]?(SIZE|LENGTH|COUNT)/i,
15752
15794
  suggestedAccess: "full" /* FULL */,
15753
- description: "Size/count limit"
15795
+ description: "Size/count limit",
15796
+ format: "number",
15797
+ example: "100"
15754
15798
  },
15755
15799
  {
15756
15800
  name: "enable-disable",
15757
15801
  pattern: /(ENABLE|DISABLE)[_-]/i,
15758
15802
  suggestedAccess: "full" /* FULL */,
15759
- description: "Feature flag"
15803
+ description: "Feature flag",
15804
+ format: "boolean",
15805
+ example: "true | false"
15760
15806
  },
15761
15807
  {
15762
15808
  name: "feature-flag",
15763
15809
  pattern: /FEATURE[_-]/i,
15764
15810
  suggestedAccess: "full" /* FULL */,
15765
- description: "Feature flag"
15811
+ description: "Feature flag",
15812
+ format: "boolean",
15813
+ example: "true | false"
15766
15814
  },
15767
15815
  {
15768
15816
  name: "region",
15769
15817
  pattern: /_REGION$/i,
15770
15818
  suggestedAccess: "full" /* FULL */,
15771
- description: "Cloud region"
15819
+ description: "Cloud region",
15820
+ format: "string",
15821
+ example: "us-east-1"
15772
15822
  },
15773
15823
  {
15774
15824
  name: "version",
15775
15825
  pattern: /_VERSION$/i,
15776
15826
  suggestedAccess: "full" /* FULL */,
15777
- description: "Version number"
15827
+ description: "Version number",
15828
+ format: "string",
15829
+ example: "1.0.0"
15778
15830
  }
15779
15831
  ];
15780
15832
  function classifyVariable(name) {
@@ -15782,7 +15834,9 @@ function classifyVariable(name) {
15782
15834
  if (pattern.pattern.test(name)) {
15783
15835
  return {
15784
15836
  access: pattern.suggestedAccess,
15785
- description: pattern.description
15837
+ description: pattern.description,
15838
+ format: pattern.format,
15839
+ example: pattern.example
15786
15840
  };
15787
15841
  }
15788
15842
  }
@@ -23000,7 +23054,7 @@ async function startMCPServer() {
23000
23054
  },
23001
23055
  {
23002
23056
  name: "env_describe",
23003
- description: "Get detailed information about a variable including its access level and description.",
23057
+ description: "Get detailed information about a variable including its access level, description, format, and example.",
23004
23058
  inputSchema: {
23005
23059
  type: "object",
23006
23060
  properties: {
@@ -23011,6 +23065,14 @@ async function startMCPServer() {
23011
23065
  },
23012
23066
  required: ["key"]
23013
23067
  }
23068
+ },
23069
+ {
23070
+ name: "env_check_required",
23071
+ description: "Check which required environment variables are missing. Use this to help users set up their environment.",
23072
+ inputSchema: {
23073
+ type: "object",
23074
+ properties: {}
23075
+ }
23014
23076
  }
23015
23077
  ]
23016
23078
  };
@@ -23041,18 +23103,57 @@ async function startMCPServer() {
23041
23103
  }
23042
23104
  case "env_get": {
23043
23105
  const key = args.key;
23106
+ const config2 = manifest2.variables[key];
23044
23107
  const variable = getVariableForAI(key, env, manifest2);
23108
+ if (config2 && config2.access === "hidden" /* HIDDEN */) {
23109
+ return {
23110
+ content: [
23111
+ {
23112
+ type: "text",
23113
+ text: JSON.stringify({
23114
+ error: "ACCESS_DENIED",
23115
+ key,
23116
+ access: "hidden",
23117
+ message: "This variable is hidden from AI. Ask the user to configure it manually.",
23118
+ hint: config2.description
23119
+ }, null, 2)
23120
+ }
23121
+ ],
23122
+ isError: true
23123
+ };
23124
+ }
23045
23125
  if (!variable) {
23046
23126
  return {
23047
23127
  content: [
23048
23128
  {
23049
23129
  type: "text",
23050
- text: `Error: Variable "${key}" is hidden or does not exist`
23130
+ text: JSON.stringify({
23131
+ error: "NOT_FOUND",
23132
+ key,
23133
+ message: `Variable "${key}" does not exist in the manifest.`
23134
+ }, null, 2)
23051
23135
  }
23052
23136
  ],
23053
23137
  isError: true
23054
23138
  };
23055
23139
  }
23140
+ if (variable.access === "placeholder" /* PLACEHOLDER */) {
23141
+ return {
23142
+ content: [
23143
+ {
23144
+ type: "text",
23145
+ text: JSON.stringify({
23146
+ value: variable.displayValue,
23147
+ access: "placeholder",
23148
+ message: "You can reference this variable but cannot see the actual value.",
23149
+ hint: config2?.description,
23150
+ format: config2?.format,
23151
+ example: config2?.example
23152
+ }, null, 2)
23153
+ }
23154
+ ]
23155
+ };
23156
+ }
23056
23157
  return {
23057
23158
  content: [
23058
23159
  {
@@ -23094,25 +23195,50 @@ async function startMCPServer() {
23094
23195
  const key = args.key;
23095
23196
  const variable = getVariableForAI(key, env, manifest2);
23096
23197
  const config2 = manifest2.variables[key];
23097
- if (!variable) {
23198
+ if (config2 && config2.access === "hidden" /* HIDDEN */) {
23098
23199
  return {
23099
23200
  content: [
23100
23201
  {
23101
23202
  type: "text",
23102
- text: `Error: Variable "${key}" is hidden or does not exist`
23203
+ text: JSON.stringify({
23204
+ key,
23205
+ access: "hidden",
23206
+ canModify: false,
23207
+ description: config2.description,
23208
+ message: "This variable is hidden from AI. Ask the user to configure it.",
23209
+ required: config2.required ?? false,
23210
+ format: config2.format,
23211
+ example: config2.example
23212
+ }, null, 2)
23213
+ }
23214
+ ]
23215
+ };
23216
+ }
23217
+ if (!variable && !config2) {
23218
+ return {
23219
+ content: [
23220
+ {
23221
+ type: "text",
23222
+ text: JSON.stringify({
23223
+ error: "NOT_FOUND",
23224
+ key,
23225
+ message: `Variable "${key}" does not exist in the manifest.`
23226
+ }, null, 2)
23103
23227
  }
23104
23228
  ],
23105
23229
  isError: true
23106
23230
  };
23107
23231
  }
23108
23232
  const info = {
23109
- key: variable.key,
23110
- access: variable.access,
23111
- canModify: variable.canModify,
23112
- description: variable.description,
23233
+ key: variable?.key ?? key,
23234
+ access: variable?.access ?? config2?.access,
23235
+ canModify: variable?.canModify ?? false,
23236
+ description: variable?.description ?? config2?.description,
23113
23237
  required: config2?.required ?? false,
23114
23238
  hasDefault: config2?.default !== undefined,
23115
- isSet: env[key] !== undefined
23239
+ isSet: env[key] !== undefined,
23240
+ format: config2?.format,
23241
+ example: config2?.example
23116
23242
  };
23117
23243
  return {
23118
23244
  content: [
@@ -23123,6 +23249,42 @@ async function startMCPServer() {
23123
23249
  ]
23124
23250
  };
23125
23251
  }
23252
+ case "env_check_required": {
23253
+ const missing = [];
23254
+ const set2 = [];
23255
+ for (const [key, config2] of Object.entries(manifest2.variables)) {
23256
+ if (config2.required) {
23257
+ if (env[key] === undefined || env[key] === "") {
23258
+ missing.push({
23259
+ key,
23260
+ description: config2.description,
23261
+ format: config2.format,
23262
+ example: config2.example
23263
+ });
23264
+ } else {
23265
+ const variable = getVariableForAI(key, env, manifest2);
23266
+ if (variable && (variable.access === "full" /* FULL */ || variable.access === "read-only" /* READ_ONLY */)) {
23267
+ set2.push({ key, value: variable.displayValue });
23268
+ } else {
23269
+ set2.push({ key, value: "<set>" });
23270
+ }
23271
+ }
23272
+ }
23273
+ }
23274
+ const result = {
23275
+ missing,
23276
+ set: set2,
23277
+ message: missing.length > 0 ? `${missing.length} required variable(s) are not set. Ask the user to configure them.` : "All required variables are set."
23278
+ };
23279
+ return {
23280
+ content: [
23281
+ {
23282
+ type: "text",
23283
+ text: JSON.stringify(result, null, 2)
23284
+ }
23285
+ ]
23286
+ };
23287
+ }
23126
23288
  default:
23127
23289
  return {
23128
23290
  content: [
package/dist/index.js CHANGED
@@ -13549,193 +13549,245 @@ var CLASSIFICATION_PATTERNS = [
13549
13549
  name: "stripe-secret",
13550
13550
  pattern: /^STRIPE_SECRET/i,
13551
13551
  suggestedAccess: "hidden" /* HIDDEN */,
13552
- description: "Stripe secret key"
13552
+ description: "Stripe secret key",
13553
+ format: "key",
13554
+ example: "sk_live_..."
13553
13555
  },
13554
13556
  {
13555
13557
  name: "private-key",
13556
13558
  pattern: /PRIVATE[_-]?KEY/i,
13557
13559
  suggestedAccess: "hidden" /* HIDDEN */,
13558
- description: "Private key material"
13560
+ description: "Private key material",
13561
+ format: "pem",
13562
+ example: "-----BEGIN PRIVATE KEY-----..."
13559
13563
  },
13560
13564
  {
13561
13565
  name: "signing-secret",
13562
13566
  pattern: /SIGNING[_-]?SECRET/i,
13563
13567
  suggestedAccess: "hidden" /* HIDDEN */,
13564
- description: "Signing secret"
13568
+ description: "Signing secret",
13569
+ format: "key"
13565
13570
  },
13566
13571
  {
13567
13572
  name: "api-key",
13568
13573
  pattern: /API[_-]?KEY/i,
13569
13574
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13570
- description: "API key"
13575
+ description: "API key",
13576
+ format: "key",
13577
+ example: "sk-..."
13571
13578
  },
13572
13579
  {
13573
13580
  name: "secret-key",
13574
13581
  pattern: /SECRET[_-]?KEY/i,
13575
13582
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13576
- description: "Secret key"
13583
+ description: "Secret key",
13584
+ format: "key"
13577
13585
  },
13578
13586
  {
13579
13587
  name: "access-key",
13580
13588
  pattern: /ACCESS[_-]?KEY/i,
13581
13589
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13582
- description: "Access key"
13590
+ description: "Access key",
13591
+ format: "key",
13592
+ example: "AKIA..."
13583
13593
  },
13584
13594
  {
13585
13595
  name: "auth-token",
13586
13596
  pattern: /AUTH[_-]?TOKEN/i,
13587
13597
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13588
- description: "Authentication token"
13598
+ description: "Authentication token",
13599
+ format: "token"
13589
13600
  },
13590
13601
  {
13591
13602
  name: "bearer-token",
13592
13603
  pattern: /BEARER[_-]?TOKEN/i,
13593
13604
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13594
- description: "Bearer token"
13605
+ description: "Bearer token",
13606
+ format: "token"
13595
13607
  },
13596
13608
  {
13597
13609
  name: "jwt-secret",
13598
13610
  pattern: /JWT[_-]?SECRET/i,
13599
13611
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13600
- description: "JWT signing secret"
13612
+ description: "JWT signing secret",
13613
+ format: "key"
13601
13614
  },
13602
13615
  {
13603
13616
  name: "password",
13604
13617
  pattern: /PASSWORD/i,
13605
13618
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13606
- description: "Password credential"
13619
+ description: "Password credential",
13620
+ format: "password"
13607
13621
  },
13608
13622
  {
13609
13623
  name: "credential",
13610
13624
  pattern: /CREDENTIAL/i,
13611
13625
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13612
- description: "Credential"
13626
+ description: "Credential",
13627
+ format: "key"
13613
13628
  },
13614
13629
  {
13615
13630
  name: "secret",
13616
13631
  pattern: /SECRET/i,
13617
13632
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13618
- description: "Secret value"
13633
+ description: "Secret value",
13634
+ format: "key"
13619
13635
  },
13620
13636
  {
13621
13637
  name: "token",
13622
13638
  pattern: /TOKEN$/i,
13623
13639
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13624
- description: "Token"
13640
+ description: "Token",
13641
+ format: "token"
13625
13642
  },
13626
13643
  {
13627
13644
  name: "database-url",
13628
13645
  pattern: /DATABASE[_-]?URL/i,
13629
13646
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13630
- description: "Database connection URL (may contain password)"
13647
+ description: "Database connection URL (may contain password)",
13648
+ format: "url",
13649
+ example: "postgres://user:pass@localhost:5432/dbname"
13631
13650
  },
13632
13651
  {
13633
13652
  name: "redis-url",
13634
13653
  pattern: /REDIS[_-]?URL/i,
13635
13654
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13636
- description: "Redis connection URL (may contain password)"
13655
+ description: "Redis connection URL (may contain password)",
13656
+ format: "url",
13657
+ example: "redis://user:pass@localhost:6379/0"
13637
13658
  },
13638
13659
  {
13639
13660
  name: "mongodb-uri",
13640
13661
  pattern: /MONGO(DB)?[_-]?URI/i,
13641
13662
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13642
- description: "MongoDB connection URI (may contain password)"
13663
+ description: "MongoDB connection URI (may contain password)",
13664
+ format: "url",
13665
+ example: "mongodb://user:pass@localhost:27017/dbname"
13643
13666
  },
13644
13667
  {
13645
13668
  name: "connection-string",
13646
13669
  pattern: /CONNECTION[_-]?STRING/i,
13647
13670
  suggestedAccess: "placeholder" /* PLACEHOLDER */,
13648
- description: "Connection string (may contain password)"
13671
+ description: "Connection string (may contain password)",
13672
+ format: "url"
13649
13673
  },
13650
13674
  {
13651
13675
  name: "url-suffix",
13652
13676
  pattern: /_URL$/i,
13653
13677
  suggestedAccess: "read-only" /* READ_ONLY */,
13654
- description: "URL endpoint"
13678
+ description: "URL endpoint",
13679
+ format: "url",
13680
+ example: "https://api.example.com"
13655
13681
  },
13656
13682
  {
13657
13683
  name: "uri-suffix",
13658
13684
  pattern: /_URI$/i,
13659
13685
  suggestedAccess: "read-only" /* READ_ONLY */,
13660
- description: "URI endpoint"
13686
+ description: "URI endpoint",
13687
+ format: "url"
13661
13688
  },
13662
13689
  {
13663
13690
  name: "host",
13664
13691
  pattern: /_HOST$/i,
13665
13692
  suggestedAccess: "read-only" /* READ_ONLY */,
13666
- description: "Host address"
13693
+ description: "Host address",
13694
+ format: "hostname",
13695
+ example: "localhost"
13667
13696
  },
13668
13697
  {
13669
13698
  name: "node-env",
13670
13699
  pattern: /^NODE_ENV$/i,
13671
13700
  suggestedAccess: "full" /* FULL */,
13672
- description: "Node.js environment mode"
13701
+ description: "Node.js environment mode",
13702
+ format: "enum",
13703
+ example: "development | production | test"
13673
13704
  },
13674
13705
  {
13675
13706
  name: "env-suffix",
13676
13707
  pattern: /_ENV$/i,
13677
13708
  suggestedAccess: "full" /* FULL */,
13678
- description: "Environment setting"
13709
+ description: "Environment setting",
13710
+ format: "string"
13679
13711
  },
13680
13712
  {
13681
13713
  name: "debug",
13682
13714
  pattern: /DEBUG/i,
13683
13715
  suggestedAccess: "full" /* FULL */,
13684
- description: "Debug flag"
13716
+ description: "Debug flag",
13717
+ format: "boolean",
13718
+ example: "true | false"
13685
13719
  },
13686
13720
  {
13687
13721
  name: "log-level",
13688
13722
  pattern: /LOG[_-]?LEVEL/i,
13689
13723
  suggestedAccess: "full" /* FULL */,
13690
- description: "Logging level"
13724
+ description: "Logging level",
13725
+ format: "enum",
13726
+ example: "debug | info | warn | error"
13691
13727
  },
13692
13728
  {
13693
13729
  name: "port",
13694
13730
  pattern: /^PORT$/i,
13695
13731
  suggestedAccess: "full" /* FULL */,
13696
- description: "Server port"
13732
+ description: "Server port",
13733
+ format: "number",
13734
+ example: "3000"
13697
13735
  },
13698
13736
  {
13699
13737
  name: "port-suffix",
13700
13738
  pattern: /_PORT$/i,
13701
13739
  suggestedAccess: "full" /* FULL */,
13702
- description: "Port number"
13740
+ description: "Port number",
13741
+ format: "number",
13742
+ example: "5432"
13703
13743
  },
13704
13744
  {
13705
13745
  name: "timeout",
13706
13746
  pattern: /TIMEOUT/i,
13707
13747
  suggestedAccess: "full" /* FULL */,
13708
- description: "Timeout setting"
13748
+ description: "Timeout setting",
13749
+ format: "number",
13750
+ example: "30000"
13709
13751
  },
13710
13752
  {
13711
13753
  name: "max-size",
13712
13754
  pattern: /MAX[_-]?(SIZE|LENGTH|COUNT)/i,
13713
13755
  suggestedAccess: "full" /* FULL */,
13714
- description: "Size/count limit"
13756
+ description: "Size/count limit",
13757
+ format: "number",
13758
+ example: "100"
13715
13759
  },
13716
13760
  {
13717
13761
  name: "enable-disable",
13718
13762
  pattern: /(ENABLE|DISABLE)[_-]/i,
13719
13763
  suggestedAccess: "full" /* FULL */,
13720
- description: "Feature flag"
13764
+ description: "Feature flag",
13765
+ format: "boolean",
13766
+ example: "true | false"
13721
13767
  },
13722
13768
  {
13723
13769
  name: "feature-flag",
13724
13770
  pattern: /FEATURE[_-]/i,
13725
13771
  suggestedAccess: "full" /* FULL */,
13726
- description: "Feature flag"
13772
+ description: "Feature flag",
13773
+ format: "boolean",
13774
+ example: "true | false"
13727
13775
  },
13728
13776
  {
13729
13777
  name: "region",
13730
13778
  pattern: /_REGION$/i,
13731
13779
  suggestedAccess: "full" /* FULL */,
13732
- description: "Cloud region"
13780
+ description: "Cloud region",
13781
+ format: "string",
13782
+ example: "us-east-1"
13733
13783
  },
13734
13784
  {
13735
13785
  name: "version",
13736
13786
  pattern: /_VERSION$/i,
13737
13787
  suggestedAccess: "full" /* FULL */,
13738
- description: "Version number"
13788
+ description: "Version number",
13789
+ format: "string",
13790
+ example: "1.0.0"
13739
13791
  }
13740
13792
  ];
13741
13793
  function classifyVariable(name) {
@@ -13743,7 +13795,9 @@ function classifyVariable(name) {
13743
13795
  if (pattern.pattern.test(name)) {
13744
13796
  return {
13745
13797
  access: pattern.suggestedAccess,
13746
- description: pattern.description
13798
+ description: pattern.description,
13799
+ format: pattern.format,
13800
+ example: pattern.example
13747
13801
  };
13748
13802
  }
13749
13803
  }
@@ -20509,7 +20563,7 @@ async function startMCPServer() {
20509
20563
  },
20510
20564
  {
20511
20565
  name: "env_describe",
20512
- description: "Get detailed information about a variable including its access level and description.",
20566
+ description: "Get detailed information about a variable including its access level, description, format, and example.",
20513
20567
  inputSchema: {
20514
20568
  type: "object",
20515
20569
  properties: {
@@ -20520,6 +20574,14 @@ async function startMCPServer() {
20520
20574
  },
20521
20575
  required: ["key"]
20522
20576
  }
20577
+ },
20578
+ {
20579
+ name: "env_check_required",
20580
+ description: "Check which required environment variables are missing. Use this to help users set up their environment.",
20581
+ inputSchema: {
20582
+ type: "object",
20583
+ properties: {}
20584
+ }
20523
20585
  }
20524
20586
  ]
20525
20587
  };
@@ -20550,18 +20612,57 @@ async function startMCPServer() {
20550
20612
  }
20551
20613
  case "env_get": {
20552
20614
  const key = args.key;
20615
+ const config2 = manifest2.variables[key];
20553
20616
  const variable = getVariableForAI(key, env, manifest2);
20617
+ if (config2 && config2.access === "hidden" /* HIDDEN */) {
20618
+ return {
20619
+ content: [
20620
+ {
20621
+ type: "text",
20622
+ text: JSON.stringify({
20623
+ error: "ACCESS_DENIED",
20624
+ key,
20625
+ access: "hidden",
20626
+ message: "This variable is hidden from AI. Ask the user to configure it manually.",
20627
+ hint: config2.description
20628
+ }, null, 2)
20629
+ }
20630
+ ],
20631
+ isError: true
20632
+ };
20633
+ }
20554
20634
  if (!variable) {
20555
20635
  return {
20556
20636
  content: [
20557
20637
  {
20558
20638
  type: "text",
20559
- text: `Error: Variable "${key}" is hidden or does not exist`
20639
+ text: JSON.stringify({
20640
+ error: "NOT_FOUND",
20641
+ key,
20642
+ message: `Variable "${key}" does not exist in the manifest.`
20643
+ }, null, 2)
20560
20644
  }
20561
20645
  ],
20562
20646
  isError: true
20563
20647
  };
20564
20648
  }
20649
+ if (variable.access === "placeholder" /* PLACEHOLDER */) {
20650
+ return {
20651
+ content: [
20652
+ {
20653
+ type: "text",
20654
+ text: JSON.stringify({
20655
+ value: variable.displayValue,
20656
+ access: "placeholder",
20657
+ message: "You can reference this variable but cannot see the actual value.",
20658
+ hint: config2?.description,
20659
+ format: config2?.format,
20660
+ example: config2?.example
20661
+ }, null, 2)
20662
+ }
20663
+ ]
20664
+ };
20665
+ }
20565
20666
  return {
20566
20667
  content: [
20567
20668
  {
@@ -20603,25 +20704,50 @@ async function startMCPServer() {
20603
20704
  const key = args.key;
20604
20705
  const variable = getVariableForAI(key, env, manifest2);
20605
20706
  const config2 = manifest2.variables[key];
20606
- if (!variable) {
20707
+ if (config2 && config2.access === "hidden" /* HIDDEN */) {
20607
20708
  return {
20608
20709
  content: [
20609
20710
  {
20610
20711
  type: "text",
20611
- text: `Error: Variable "${key}" is hidden or does not exist`
20712
+ text: JSON.stringify({
20713
+ key,
20714
+ access: "hidden",
20715
+ canModify: false,
20716
+ description: config2.description,
20717
+ message: "This variable is hidden from AI. Ask the user to configure it.",
20718
+ required: config2.required ?? false,
20719
+ format: config2.format,
20720
+ example: config2.example
20721
+ }, null, 2)
20722
+ }
20723
+ ]
20724
+ };
20725
+ }
20726
+ if (!variable && !config2) {
20727
+ return {
20728
+ content: [
20729
+ {
20730
+ type: "text",
20731
+ text: JSON.stringify({
20732
+ error: "NOT_FOUND",
20733
+ key,
20734
+ message: `Variable "${key}" does not exist in the manifest.`
20735
+ }, null, 2)
20612
20736
  }
20613
20737
  ],
20614
20738
  isError: true
20615
20739
  };
20616
20740
  }
20617
20741
  const info = {
20618
- key: variable.key,
20619
- access: variable.access,
20620
- canModify: variable.canModify,
20621
- description: variable.description,
20742
+ key: variable?.key ?? key,
20743
+ access: variable?.access ?? config2?.access,
20744
+ canModify: variable?.canModify ?? false,
20745
+ description: variable?.description ?? config2?.description,
20622
20746
  required: config2?.required ?? false,
20623
20747
  hasDefault: config2?.default !== undefined,
20624
- isSet: env[key] !== undefined
20748
+ isSet: env[key] !== undefined,
20749
+ format: config2?.format,
20750
+ example: config2?.example
20625
20751
  };
20626
20752
  return {
20627
20753
  content: [
@@ -20632,6 +20758,42 @@ async function startMCPServer() {
20632
20758
  ]
20633
20759
  };
20634
20760
  }
20761
+ case "env_check_required": {
20762
+ const missing = [];
20763
+ const set2 = [];
20764
+ for (const [key, config2] of Object.entries(manifest2.variables)) {
20765
+ if (config2.required) {
20766
+ if (env[key] === undefined || env[key] === "") {
20767
+ missing.push({
20768
+ key,
20769
+ description: config2.description,
20770
+ format: config2.format,
20771
+ example: config2.example
20772
+ });
20773
+ } else {
20774
+ const variable = getVariableForAI(key, env, manifest2);
20775
+ if (variable && (variable.access === "full" /* FULL */ || variable.access === "read-only" /* READ_ONLY */)) {
20776
+ set2.push({ key, value: variable.displayValue });
20777
+ } else {
20778
+ set2.push({ key, value: "<set>" });
20779
+ }
20780
+ }
20781
+ }
20782
+ }
20783
+ const result = {
20784
+ missing,
20785
+ set: set2,
20786
+ message: missing.length > 0 ? `${missing.length} required variable(s) are not set. Ask the user to configure them.` : "All required variables are set."
20787
+ };
20788
+ return {
20789
+ content: [
20790
+ {
20791
+ type: "text",
20792
+ text: JSON.stringify(result, null, 2)
20793
+ }
20794
+ ]
20795
+ };
20796
+ }
20635
20797
  default:
20636
20798
  return {
20637
20799
  content: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "envibe",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "The missing permission layer between AI agents and your .env",
5
5
  "type": "module",
6
6
  "bin": {