@impetik/xeer-mcp 0.2.9 → 0.2.12

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
@@ -74,7 +74,7 @@ The generated registry is the complete MCP tool and exclusion surface:
74
74
  | `xeer_dev_start` | `dev.start` | `author` / `operator` | Start a local development session. | `directory?`: `string`<br>`host?`: `string`<br>`port?`: `integer` [0..65535]<br>`timeoutMilliseconds?`: `integer` [1000..600000] | `read-source`<br>`write-generated`<br>`run-local`<br>`write-state` | writes; non-idempotent; reversible; non-destructive | `project-relative` | `xeer.dev.v0` | none |
75
75
  | `xeer_dev_status` | `dev.status` | `author` / `operator` | Read new events from a local development session. | `sessionId?`: `string`<br>`cursor?`: `integer` [0..9007199254740991]; default `0`<br>`waitMilliseconds?`: `integer` [0..600000]; default `0`<br>`limit?`: `integer` [1..1000]; default `200` | none | read-only; idempotent; reversible; non-destructive | `none` | `xeer.dev.v0` | none |
76
76
  | `xeer_dev_stop` | `dev.stop` | `author` / `operator` | Stop a local development session and release its lease. | `sessionId?`: `string`<br>`cursor?`: `integer` [0..9007199254740991]; default `0` | `run-local` | writes; idempotent; reversible; non-destructive | `none` | `xeer.dev.v0` | none |
77
- | `xeer_diagnostics` | `diagnostics` | `author` / `operator` | Read the generated diagnostic catalogue. | `code?`: `string` | none | read-only; idempotent; reversible; non-destructive | `none` | `unversioned` | none |
77
+ | `xeer_diagnostics` | `diagnostics` | `author` / `operator` | Explain one emitted diagnostic code. | `code`: `string` | none | read-only; idempotent; reversible; non-destructive | `none` | `xeer.command.v0` | none |
78
78
 
79
79
  **CLI actions intentionally excluded from MCP (34).**
80
80
 
package/dist/server.js CHANGED
@@ -3,7 +3,7 @@ import { isAbsolute, relative, sep } from 'node:path';
3
3
  import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
4
4
  import { z } from 'zod';
5
5
  import { createAgentContext, readDocsIndex, readDocsPage, searchDocs } from '@impetik/xeer/agent-context';
6
- import { DIAGNOSTICS, DIAGNOSTIC_CODES, DIAGNOSTIC_FAMILIES, diagnosticDefinition, renderDiagnosticsReference, } from '../vendor/spec/diagnostics.js';
6
+ import { DIAGNOSTIC_FAMILIES, diagnosticDefinition, } from '../vendor/spec/diagnostics.js';
7
7
  import { actionDefinition, mcpAnnotations, } from '../vendor/spec/actions.js';
8
8
  import { isReviewReceiptId } from '../vendor/spec/review.js';
9
9
  import { DevSessionRegistry } from './dev-session.js';
@@ -541,18 +541,12 @@ export function createXeerMcpServer(options = {}) {
541
541
  means: z.string().optional(),
542
542
  repair: z.string().optional(),
543
543
  surfaces: z.array(z.string()).optional(),
544
- codes: z.array(z.string()).optional(),
545
- reference: z.string().optional(),
546
544
  }).loose()),
547
545
  }, async ({ code }) => {
548
- if (!code) {
549
- return structured('diagnostics', { codes: [...DIAGNOSTIC_CODES], reference: renderDiagnosticsReference() });
550
- }
551
546
  const normalized = code.trim().toUpperCase();
552
547
  const definition = diagnosticDefinition(normalized);
553
548
  if (!definition) {
554
- const known = Object.keys(DIAGNOSTICS).sort().join(', ');
555
- return failure('diagnostics', 'unknown_diagnostic', `Unknown diagnostic code: ${normalized}. Known codes: ${known}`);
549
+ return failure('diagnostics', 'unknown_diagnostic', `Unknown diagnostic code: ${normalized}. Pass the exact XE#### emitted by Xeer.`);
556
550
  }
557
551
  const family = DIAGNOSTIC_FAMILIES.find((candidate) => candidate.prefix === definition.prefix);
558
552
  return structured('diagnostics', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impetik/xeer-mcp",
3
- "version": "0.2.9",
3
+ "version": "0.2.12",
4
4
  "type": "module",
5
5
  "description": "Model Context Protocol server for Xeer: the scaffold, check, dev, build, and deploy loop as agent tools.",
6
6
  "license": "MIT",
@@ -47,7 +47,7 @@
47
47
  "dependencies": {
48
48
  "@modelcontextprotocol/sdk": "^1.29.0",
49
49
  "zod": "^4.0.10",
50
- "@impetik/xeer": "0.2.9"
50
+ "@impetik/xeer": "0.2.12"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node": "^24.1.0"
@@ -627,10 +627,11 @@ declare const actions: readonly [{
627
627
  };
628
628
  }, {
629
629
  readonly id: "diagnostics";
630
- readonly command: readonly [];
631
- readonly summary: "Read the generated diagnostic catalogue.";
632
- readonly usage: readonly [];
633
- readonly outputProtocol: "unversioned";
630
+ readonly command: readonly ["diagnostics"];
631
+ readonly summary: "Explain one emitted diagnostic code.";
632
+ readonly usage: readonly ["diagnostics <XE####> [--json]"];
633
+ readonly helpOrder: 37;
634
+ readonly outputProtocol: "xeer.command.v0";
634
635
  readonly effects: readonly [];
635
636
  readonly idempotent: true;
636
637
  readonly reversible: true;
@@ -646,10 +647,11 @@ declare const actions: readonly [{
646
647
  readonly type: "string";
647
648
  };
648
649
  };
650
+ readonly required: readonly ["code"];
649
651
  };
650
652
  readonly mcpTitle: "Look up Xeer diagnostic codes";
651
653
  readonly mcpDescription: string;
652
- readonly cli: false;
654
+ readonly cli: true;
653
655
  readonly mcpTool: "xeer_diagnostics";
654
656
  readonly mcpProfiles: readonly ["author", "operator"];
655
657
  };
@@ -1244,7 +1246,7 @@ export declare function mcpAnnotations(action: XeerActionDefinition): McpActionA
1244
1246
  export declare function mcpInputJsonSchema(action: XeerActionDefinition): McpInputJsonSchema | undefined;
1245
1247
  export declare const ACTION_REFERENCE_START = "<!-- xeer-action-reference:start -->";
1246
1248
  export declare const ACTION_REFERENCE_END = "<!-- xeer-action-reference:end -->";
1247
- export declare const ACTION_REFERENCE_TARGETS: readonly ["docs/AGENTS.md", "packages/website/content/guides/agents.md", ".agents/skills/xeer/SKILL.md", "packages/mcp/README.md", "packages/website/content/reference/cli.md"];
1249
+ export declare const ACTION_REFERENCE_TARGETS: readonly ["docs/AGENTS.md", "packages/website/content/guides/agents.md", ".agents/skills/xeer/references/mcp-actions.md", "packages/mcp/README.md", "packages/website/content/reference/cli.md"];
1248
1250
  /** One generated block is embedded in every agent-facing action-policy surface. */
1249
1251
  export declare function renderActionReference(): string;
1250
1252
  export {};
@@ -136,9 +136,8 @@ const MCP_PRESENTATION = {
136
136
  },
137
137
  diagnostics: {
138
138
  mcpTitle: 'Look up Xeer diagnostic codes',
139
- mcpDescription: 'Explain a diagnostic code: what the platform observed and which edit closes it. '
140
- + 'Omit `code` for the whole generated reference. This is the same catalogue the compiler emits '
141
- + 'from, so it cannot drift from the codes you receive.',
139
+ mcpDescription: 'Explain one diagnostic code: what the platform observed and which edit closes it. '
140
+ + 'Pass the exact XE#### emitted by the command; this lookup intentionally never returns the whole catalogue.',
142
141
  },
143
142
  };
144
143
  const actions = [
@@ -387,15 +386,16 @@ const actions = [
387
386
  },
388
387
  },
389
388
  {
390
- id: 'diagnostics', command: [], summary: 'Read the generated diagnostic catalogue.',
391
- usage: [], outputProtocol: 'unversioned', effects: [], idempotent: true, reversible: true,
389
+ id: 'diagnostics', command: ['diagnostics'], summary: 'Explain one emitted diagnostic code.',
390
+ usage: ['diagnostics <XE####> [--json]'], helpOrder: 37,
391
+ outputProtocol: 'xeer.command.v0', effects: [], idempotent: true, reversible: true,
392
392
  destructive: false, humanPrerequisites: [], pathPolicy: 'none',
393
393
  surfaces: {
394
- cli: false, mcpTool: 'xeer_diagnostics', mcpProfiles: XEER_MCP_PROFILES,
394
+ cli: true, mcpTool: 'xeer_diagnostics', mcpProfiles: XEER_MCP_PROFILES,
395
395
  ...MCP_PRESENTATION.diagnostics,
396
396
  mcpInputSchema: { type: 'object', properties: {
397
397
  code: { description: 'An XE#### code, e.g. XE1202.', type: 'string' },
398
- } },
398
+ }, required: ['code'] },
399
399
  },
400
400
  },
401
401
  {
@@ -732,7 +732,7 @@ export const ACTION_REFERENCE_END = '<!-- xeer-action-reference:end -->';
732
732
  export const ACTION_REFERENCE_TARGETS = [
733
733
  'docs/AGENTS.md',
734
734
  'packages/website/content/guides/agents.md',
735
- '.agents/skills/xeer/SKILL.md',
735
+ '.agents/skills/xeer/references/mcp-actions.md',
736
736
  'packages/mcp/README.md',
737
737
  'packages/website/content/reference/cli.md',
738
738
  ];
@@ -18,3 +18,4 @@ export * from './admin.js';
18
18
  export * from './admin-sql.js';
19
19
  export * from './network-policy.js';
20
20
  export * from './review.js';
21
+ export * from './template.js';
@@ -18,3 +18,4 @@ export * from './admin.js';
18
18
  export * from './admin-sql.js';
19
19
  export * from './network-policy.js';
20
20
  export * from './review.js';
21
+ export * from './template.js';
@@ -0,0 +1,32 @@
1
+ import { z } from 'zod';
2
+ export declare const TEMPLATE_FORMAT: "xeer.template.v0";
3
+ export declare const TEMPLATE_MANIFEST_SCHEMA_URL: "https://docs.xeer.run/template-v0.schema.json";
4
+ export declare const templateManifestSchema: z.ZodObject<{
5
+ $schema: z.ZodOptional<z.ZodString>;
6
+ format: z.ZodLiteral<"xeer.template.v0">;
7
+ title: z.ZodString;
8
+ description: z.ZodString;
9
+ category: z.ZodString;
10
+ tags: z.ZodArray<z.ZodString>;
11
+ keyHighlights: z.ZodArray<z.ZodString>;
12
+ screenshots: z.ZodArray<z.ZodObject<{
13
+ path: z.ZodString;
14
+ alt: z.ZodString;
15
+ }, z.core.$strict>>;
16
+ author: z.ZodObject<{
17
+ name: z.ZodString;
18
+ url: z.ZodOptional<z.ZodString>;
19
+ }, z.core.$strict>;
20
+ capabilities: z.ZodArray<z.ZodEnum<{
21
+ database: "database";
22
+ storage: "storage";
23
+ }>>;
24
+ requiredSecrets: z.ZodArray<z.ZodObject<{
25
+ name: z.ZodString;
26
+ description: z.ZodString;
27
+ }, z.core.$strict>>;
28
+ previewAppId: z.ZodString;
29
+ }, z.core.$strict>;
30
+ export type TemplateManifestV0 = z.infer<typeof templateManifestSchema>;
31
+ export declare const templateManifestJsonSchema: Readonly<Record<string, unknown>>;
32
+ export declare function parseTemplateManifest(value: unknown): TemplateManifestV0;
@@ -0,0 +1,101 @@
1
+ import { z } from 'zod';
2
+ import { CAPABILITIES } from './types.js';
3
+ export const TEMPLATE_FORMAT = 'xeer.template.v0';
4
+ export const TEMPLATE_MANIFEST_SCHEMA_URL = 'https://docs.xeer.run/template-v0.schema.json';
5
+ const trimmed = (maximum) => z.string().min(1).max(maximum)
6
+ .refine((value) => value === value.trim(), 'must not have leading or trailing whitespace')
7
+ .refine((value) => !/[\u0000-\u001f\u007f]/u.test(value), 'must not contain control characters');
8
+ const slug = z.string().regex(/^[a-z][a-z0-9-]{1,62}$/u, 'must be a lowercase slug between 2 and 63 characters');
9
+ const environmentName = z.string().regex(/^[A-Z][A-Z0-9_]{0,63}$/u, 'must be an uppercase environment variable name');
10
+ const appId = z.string().regex(/^app_[A-Za-z0-9_-]{8,96}$/u, 'must be a valid Xeer appId');
11
+ const screenshotPath = z.string().regex(/^screenshots\/(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*[A-Za-z0-9][A-Za-z0-9._-]*\.(?:avif|jpe?g|png|webp)$/u, 'must be a repository-local AVIF, JPEG, PNG, or WebP path under screenshots/');
12
+ const authorSchema = z.strictObject({
13
+ name: trimmed(80),
14
+ url: z.string().url().optional(),
15
+ });
16
+ const requiredSecretSchema = z.strictObject({
17
+ name: environmentName,
18
+ description: trimmed(200),
19
+ });
20
+ const screenshotSchema = z.strictObject({
21
+ path: screenshotPath,
22
+ alt: trimmed(200),
23
+ });
24
+ export const templateManifestSchema = z.strictObject({
25
+ $schema: z.string().url().optional(),
26
+ format: z.literal(TEMPLATE_FORMAT),
27
+ title: trimmed(120),
28
+ description: trimmed(300),
29
+ category: slug,
30
+ tags: z.array(trimmed(40)).min(1).max(16),
31
+ keyHighlights: z.array(trimmed(120)).min(1).max(8),
32
+ screenshots: z.array(screenshotSchema).min(1).max(8),
33
+ author: authorSchema,
34
+ capabilities: z.array(z.enum(CAPABILITIES)).max(CAPABILITIES.length),
35
+ requiredSecrets: z.array(requiredSecretSchema).max(16),
36
+ previewAppId: appId,
37
+ }).superRefine((manifest, ctx) => {
38
+ const unique = (values, path, label) => {
39
+ const seen = new Set();
40
+ for (const [index, value] of values.entries()) {
41
+ const normalized = value.toLocaleLowerCase('en-US');
42
+ if (seen.has(normalized)) {
43
+ ctx.addIssue({ code: 'custom', path: [path, index], message: `${label} is declared twice` });
44
+ }
45
+ seen.add(normalized);
46
+ }
47
+ };
48
+ unique(manifest.tags, 'tags', 'tag');
49
+ unique(manifest.keyHighlights, 'keyHighlights', 'highlight');
50
+ unique(manifest.screenshots.map((screenshot) => screenshot.path), 'screenshots', 'screenshot');
51
+ unique(manifest.capabilities, 'capabilities', 'capability');
52
+ unique(manifest.requiredSecrets.map((secret) => secret.name), 'requiredSecrets', 'secret');
53
+ });
54
+ const generatedTemplateManifestJsonSchema = z.toJSONSchema(templateManifestSchema);
55
+ const generatedProperties = generatedTemplateManifestJsonSchema.properties;
56
+ export const templateManifestJsonSchema = Object.freeze({
57
+ ...generatedTemplateManifestJsonSchema,
58
+ $id: TEMPLATE_MANIFEST_SCHEMA_URL,
59
+ title: 'Xeer template manifest v0',
60
+ description: 'Authored metadata for one application in the Xeer template catalog.',
61
+ properties: {
62
+ ...generatedProperties,
63
+ $schema: {
64
+ ...generatedProperties.$schema,
65
+ description: 'Editor schema hint. Xeer does not fetch this URL during validation.',
66
+ },
67
+ format: {
68
+ ...generatedProperties.format,
69
+ description: `Template metadata protocol discriminator; exactly ${TEMPLATE_FORMAT}.`,
70
+ },
71
+ tags: {
72
+ ...generatedProperties.tags,
73
+ uniqueItems: true,
74
+ },
75
+ keyHighlights: {
76
+ ...generatedProperties.keyHighlights,
77
+ uniqueItems: true,
78
+ },
79
+ screenshots: {
80
+ ...generatedProperties.screenshots,
81
+ description: 'Repository-local raster images used by template galleries.',
82
+ uniqueItems: true,
83
+ },
84
+ capabilities: {
85
+ ...generatedProperties.capabilities,
86
+ description: 'Application capabilities, verified against xeer.app.json when the catalog is generated.',
87
+ uniqueItems: true,
88
+ },
89
+ previewAppId: {
90
+ ...generatedProperties.previewAppId,
91
+ description: 'Stable first-party application identity used only for the public live preview.',
92
+ },
93
+ requiredSecrets: {
94
+ ...generatedProperties.requiredSecrets,
95
+ description: 'Secrets a template copy needs before it is usable.',
96
+ },
97
+ },
98
+ });
99
+ export function parseTemplateManifest(value) {
100
+ return templateManifestSchema.parse(value);
101
+ }