@ian-pascoe/pi-mcp 0.1.0 → 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.
@@ -16,6 +16,10 @@ export const MCP_SHUTDOWN_TIMEOUT_MS = 5_000;
16
16
 
17
17
  const JsonValueSchema = Type.Any();
18
18
  const NonEmptyStringSchema = Type.String({ minLength: 1 });
19
+ const McpServerIdSchema = Type.String({
20
+ minLength: 1,
21
+ pattern: "^[^\\u0000-\\u001F\\u007F-\\u009F]+$",
22
+ });
19
23
  const PositiveSafeIntegerSchema = Type.Integer({ minimum: 1, maximum: Number.MAX_SAFE_INTEGER });
20
24
  const RetryCountSchema = Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER });
21
25
  const BackoffFactorSchema = Type.Number({ minimum: 1, maximum: Number.MAX_SAFE_INTEGER });
@@ -60,7 +64,7 @@ const McpLayerWireSchema = Type.Object(
60
64
  requestTimeoutMs: Type.Optional(PositiveSafeIntegerSchema),
61
65
  retry: Type.Optional(McpRetryWireSchema),
62
66
  servers: Type.Optional(
63
- Type.Record(Type.String(), Type.Union([McpServerDefinitionWireSchema, Type.Null()])),
67
+ Type.Record(McpServerIdSchema, Type.Union([McpServerDefinitionWireSchema, Type.Null()])),
64
68
  ),
65
69
  },
66
70
  { additionalProperties: false },
@@ -332,6 +336,22 @@ function parseMcpLayer(
332
336
  value: {},
333
337
  };
334
338
  }
339
+ if (
340
+ Object.keys(document.mcp.servers ?? {}).some(
341
+ (serverId) => !Value.Check(McpServerIdSchema, serverId),
342
+ )
343
+ ) {
344
+ return {
345
+ errors: [
346
+ new McpSettingsError(
347
+ `${scope} mcp.servers`,
348
+ "Server Definition names must be non-empty and contain no terminal controls",
349
+ ),
350
+ ],
351
+ scope,
352
+ value: {},
353
+ };
354
+ }
335
355
  return { errors: [], scope, value: document.mcp };
336
356
  }
337
357
 
@@ -527,9 +547,7 @@ function mergeServerDefinitions(
527
547
  const masks = new Map<string, McpServerMask>();
528
548
  const errors: McpSettingsError[] = [];
529
549
  for (const [id, wire] of Object.entries(globalLayer.value.servers ?? {})) {
530
- if (id.length === 0) {
531
- errors.push(new McpSettingsError("global mcp.servers", "Server Definition ID is empty"));
532
- } else if (wire === null || (wire.enabled === false && Object.keys(wire).length === 1)) {
550
+ if (wire === null || (wire.enabled === false && Object.keys(wire).length === 1)) {
533
551
  errors.push(
534
552
  new McpSettingsError(
535
553
  `global mcp.servers.${id}`,
@@ -544,9 +562,7 @@ function mergeServerDefinitions(
544
562
  const inherited = definitions.has(id);
545
563
  definitions.delete(id);
546
564
  masks.delete(id);
547
- if (id.length === 0) {
548
- errors.push(new McpSettingsError("project mcp.servers", "Server Definition ID is empty"));
549
- } else if (wire === null || (wire.enabled === false && Object.keys(wire).length === 1)) {
565
+ if (wire === null || (wire.enabled === false && Object.keys(wire).length === 1)) {
550
566
  masks.set(id, { id, inherited, provenance: "project" });
551
567
  } else {
552
568
  definitions.set(id, { scope: "project", wire });