@likec4/language-server 1.32.2 → 1.34.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 (77) hide show
  1. package/README.md +27 -1
  2. package/dist/Rpc.d.ts +2 -0
  3. package/dist/Rpc.js +24 -6
  4. package/dist/ast.d.ts +6 -5
  5. package/dist/ast.js +3 -0
  6. package/dist/bundled.mjs +3194 -2547
  7. package/dist/formatting/LikeC4Formatter.d.ts +1 -0
  8. package/dist/formatting/LikeC4Formatter.js +25 -1
  9. package/dist/generated/ast.d.ts +21 -12
  10. package/dist/generated/ast.js +21 -9
  11. package/dist/generated/grammar.js +1 -1
  12. package/dist/index.d.ts +0 -1
  13. package/dist/index.js +1 -2
  14. package/dist/lsp/SemanticTokenProvider.js +1 -1
  15. package/dist/mcp/{LikeC4MCPServerFactory.d.ts → NoopLikeC4MCPServer.d.ts} +1 -9
  16. package/dist/mcp/interfaces.d.ts +11 -0
  17. package/dist/mcp/interfaces.js +0 -0
  18. package/dist/mcp/sseserver/MCPServer.d.ts +1 -1
  19. package/dist/mcp/sseserver/MCPServer.js +5 -5
  20. package/dist/mcp/sseserver/MCPServerFactory.js +30 -58
  21. package/dist/mcp/sseserver/{with-mcp-server.d.ts → WithMCPServer.d.ts} +1 -1
  22. package/dist/mcp/tools/_common.d.ts +68 -0
  23. package/dist/mcp/tools/_common.js +14 -0
  24. package/dist/mcp/tools/list-projects.d.ts +6 -0
  25. package/dist/mcp/tools/list-projects.js +31 -0
  26. package/dist/mcp/tools/open-view.d.ts +10 -0
  27. package/dist/mcp/tools/open-view.js +29 -0
  28. package/dist/mcp/tools/read-element.d.ts +10 -0
  29. package/dist/mcp/tools/read-element.js +135 -0
  30. package/dist/mcp/tools/read-project-elements.d.ts +8 -0
  31. package/dist/mcp/tools/read-project-elements.js +93 -0
  32. package/dist/mcp/tools/read-project-summary.d.ts +8 -0
  33. package/dist/mcp/tools/read-project-summary.js +68 -0
  34. package/dist/mcp/tools/read-view.d.ts +10 -0
  35. package/dist/mcp/tools/read-view.js +164 -0
  36. package/dist/mcp/tools/search-element.d.ts +8 -0
  37. package/dist/mcp/tools/search-element.js +105 -0
  38. package/dist/mcp/utils.d.ts +17 -34
  39. package/dist/mcp/utils.js +41 -101
  40. package/dist/model/builder/MergedSpecification.js +8 -4
  41. package/dist/model/index.d.ts +1 -0
  42. package/dist/model/index.js +1 -0
  43. package/dist/model/model-parser-where.d.ts +1 -0
  44. package/dist/model/model-parser-where.js +30 -24
  45. package/dist/model/model-parser.d.ts +140 -0
  46. package/dist/model/parser/Base.d.ts +30 -2
  47. package/dist/model/parser/Base.js +54 -3
  48. package/dist/model/parser/DeploymentModelParser.d.ts +17 -1
  49. package/dist/model/parser/DeploymentModelParser.js +24 -21
  50. package/dist/model/parser/DeploymentViewParser.d.ts +17 -1
  51. package/dist/model/parser/DeploymentViewParser.js +15 -6
  52. package/dist/model/parser/FqnRefParser.d.ts +17 -1
  53. package/dist/model/parser/FqnRefParser.js +42 -16
  54. package/dist/model/parser/GlobalsParser.d.ts +17 -1
  55. package/dist/model/parser/ImportsParser.d.ts +14 -0
  56. package/dist/model/parser/ModelParser.d.ts +17 -1
  57. package/dist/model/parser/ModelParser.js +22 -14
  58. package/dist/model/parser/PredicatesParser.d.ts +17 -1
  59. package/dist/model/parser/SpecificationParser.d.ts +14 -0
  60. package/dist/model/parser/SpecificationParser.js +16 -11
  61. package/dist/model/parser/ValueConverter.d.ts +4 -0
  62. package/dist/model/parser/ValueConverter.js +12 -0
  63. package/dist/model/parser/ViewsParser.d.ts +17 -1
  64. package/dist/model/parser/ViewsParser.js +21 -7
  65. package/dist/module.d.ts +5 -4
  66. package/dist/module.js +6 -7
  67. package/dist/protocol.d.ts +16 -0
  68. package/dist/protocol.js +4 -0
  69. package/dist/validation/property-checks.js +1 -1
  70. package/dist/views/configurable-layouter.js +22 -28
  71. package/dist/views/likec4-views.d.ts +5 -0
  72. package/dist/views/likec4-views.js +6 -1
  73. package/package.json +20 -19
  74. package/dist/mcp/LikeC4MCPTools.d.ts +0 -96
  75. package/dist/mcp/LikeC4MCPTools.js +0 -290
  76. /package/dist/mcp/{LikeC4MCPServerFactory.js → NoopLikeC4MCPServer.js} +0 -0
  77. /package/dist/mcp/sseserver/{with-mcp-server.js → WithMCPServer.js} +0 -0
package/dist/index.d.ts CHANGED
@@ -4,7 +4,6 @@ export { getLspConnectionSink, logger as lspLogger } from './logger';
4
4
  export type { DocumentParser, LikeC4ModelBuilder, LikeC4ModelLocator, LikeC4ModelParser } from './model';
5
5
  export type { LikeC4LanguageServices } from './LikeC4LanguageServices';
6
6
  export { isLikeC4Builtin } from './likec4lib';
7
- export { LikeC4MCPTools } from './mcp/LikeC4MCPTools';
8
7
  export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from './module';
9
8
  export type { LikeC4Services, LikeC4SharedServices } from './module';
10
9
  export type { LikeC4Views } from './views';
package/dist/index.js CHANGED
@@ -3,12 +3,11 @@ import { startLanguageServer as startLanguim } from "langium/lsp";
3
3
  import { createConnection, ProposedFeatures } from "vscode-languageserver/node";
4
4
  import { LikeC4FileSystem } from "./LikeC4FileSystem.js";
5
5
  import { getTelemetrySink, logger } from "./logger.js";
6
- import { WithMCPServer } from "./mcp/sseserver/with-mcp-server.js";
6
+ import { WithMCPServer } from "./mcp/sseserver/WithMCPServer.js";
7
7
  import { createCustomLanguageServices } from "./module.js";
8
8
  import { ConfigurableLayouter } from "./views/configurable-layouter.js";
9
9
  export { getLspConnectionSink, logger as lspLogger } from "./logger.js";
10
10
  export { isLikeC4Builtin } from "./likec4lib.js";
11
- export { LikeC4MCPTools } from "./mcp/LikeC4MCPTools.js";
12
11
  export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from "./module.js";
13
12
  export { LikeC4FileSystem };
14
13
  export function startLanguageServer() {
@@ -272,7 +272,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
272
272
  });
273
273
  return "prune";
274
274
  }
275
- if ("value" in node && node.value) {
275
+ if ("value" in node && node.value && !ast.isStringProperty(node)) {
276
276
  acceptor({
277
277
  node,
278
278
  property: "value",
@@ -1,15 +1,7 @@
1
1
  import type { ServerOptions } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import type { LikeC4Services } from '../module';
4
- export interface LikeC4MCPServer {
5
- readonly isStarted: boolean;
6
- readonly port: number;
7
- start(port: number): Promise<void>;
8
- stop(): Promise<void>;
9
- }
10
- export interface LikeC4MCPServerFactory {
11
- create(options?: ServerOptions): McpServer;
12
- }
4
+ import type { LikeC4MCPServer, LikeC4MCPServerFactory } from './interfaces';
13
5
  export declare class NoopLikeC4MCPServer implements LikeC4MCPServer {
14
6
  get isStarted(): boolean;
15
7
  get port(): number;
@@ -0,0 +1,11 @@
1
+ import type { ServerOptions } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ export interface LikeC4MCPServer {
4
+ readonly isStarted: boolean;
5
+ readonly port: number;
6
+ start(port: number): Promise<void>;
7
+ stop(): Promise<void>;
8
+ }
9
+ export interface LikeC4MCPServerFactory {
10
+ create(options?: ServerOptions): McpServer;
11
+ }
File without changes
@@ -1,6 +1,6 @@
1
1
  import type { AsyncDisposable } from 'langium';
2
2
  import type { LikeC4Services } from '../../module';
3
- import type { LikeC4MCPServer } from '../LikeC4MCPServerFactory';
3
+ import type { LikeC4MCPServer } from '../interfaces';
4
4
  export declare class SSELikeC4MCPServer implements LikeC4MCPServer, AsyncDisposable {
5
5
  private services;
6
6
  private transports;
@@ -1,7 +1,6 @@
1
1
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
2
2
  import express from "express";
3
- import { logger as mainLogger } from "../../logger.js";
4
- const logger = mainLogger.getChild("LikeC4MCPServer");
3
+ import { logger } from "../utils.js";
5
4
  export class SSELikeC4MCPServer {
6
5
  constructor(services) {
7
6
  this.services = services;
@@ -61,18 +60,19 @@ export class SSELikeC4MCPServer {
61
60
  });
62
61
  }
63
62
  async stop() {
63
+ this.transports = {};
64
64
  const server = this.server;
65
65
  if (!server) {
66
66
  return;
67
67
  }
68
- logger.info("Stopping server");
68
+ logger.info("Stopping MCP server");
69
69
  this.server = void 0;
70
- this.transports = {};
71
70
  return new Promise((resolve) => {
72
71
  server.close((err) => {
73
72
  if (err) {
74
- logger.error("Failed to stop SSE server", { err });
73
+ logger.error("Failed to stop MCP server", { err });
75
74
  }
75
+ logger.info("MCP server stopped");
76
76
  resolve();
77
77
  });
78
78
  });
@@ -1,78 +1,50 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import packageJson from "../../../package.json" with { type: "json" };
3
- import { LikeC4MCPTools } from "../LikeC4MCPTools.js";
4
- function toolResponse(text) {
5
- return {
6
- content: [{
7
- type: "text",
8
- text
9
- }]
10
- };
11
- }
3
+ import { listProjects } from "../tools/list-projects.js";
4
+ import { openView } from "../tools/open-view.js";
5
+ import { readElement } from "../tools/read-element.js";
6
+ import { readProjectElements } from "../tools/read-project-elements.js";
7
+ import { readProjectSummary } from "../tools/read-project-summary.js";
8
+ import { readView } from "../tools/read-view.js";
9
+ import { searchElement } from "../tools/search-element.js";
12
10
  export class LikeC4MCPServerFactory {
13
11
  constructor(services) {
14
12
  this.services = services;
15
13
  }
16
14
  create(options) {
17
- const {
18
- instructions,
19
- listProjects,
20
- readProjectSummary,
21
- searchElement,
22
- readElement,
23
- readView
24
- } = LikeC4MCPTools;
15
+ const isInEditor = this.services.shared.lsp.Connection !== void 0;
25
16
  const mcp = new McpServer({
26
17
  name: "LikeC4",
27
18
  version: packageJson.version
28
19
  }, {
29
- instructions,
20
+ instructions: `Provides access to LikeC4 model.
21
+ Available tools:
22
+ - list-projects: List all available LikeC4 projects in the workspace
23
+ - read-project-summary: to understand project specifications (what element kinds, tags, metadata keys are available) and available project views
24
+ - read-project-elements: list all elements in the project
25
+ - search-element: Search for LikeC4 element by partial match of id, title, kind, shape or tags
26
+ - read-element: all information about the element (includes source location)
27
+ - read-view: all information about the view (includes source location)
28
+ ${isInEditor ? "- open-view: opens the panel in the editor with the LikeC4 view" : ""}
29
+
30
+ Documentation for LikeC4 is available at https://likec4.dev/llms-full.txt
31
+ `,
30
32
  ...options,
31
33
  capabilities: {
32
34
  tools: {},
35
+ resources: {},
33
36
  ...options?.capabilities
34
37
  }
35
38
  });
36
- const tools = this.services.mcp.Tools;
37
- mcp.tool(
38
- listProjects.name,
39
- listProjects.description,
40
- async () => {
41
- return toolResponse(await tools.listProjects());
42
- }
43
- );
44
- mcp.tool(
45
- readProjectSummary.name,
46
- readProjectSummary.description,
47
- readProjectSummary.paramsSchema,
48
- async (params) => {
49
- return toolResponse(await tools.readProjectSummary(params.project));
50
- }
51
- );
52
- mcp.tool(
53
- searchElement.name,
54
- searchElement.description,
55
- searchElement.paramsSchema,
56
- async (params) => {
57
- return toolResponse(await tools.searchElement(params));
58
- }
59
- );
60
- mcp.tool(
61
- readElement.name,
62
- readElement.description,
63
- readElement.paramsSchema,
64
- async (params) => {
65
- return toolResponse(await tools.readElement(params));
66
- }
67
- );
68
- mcp.tool(
69
- readView.name,
70
- readView.description,
71
- readView.paramsSchema,
72
- async (params) => {
73
- return toolResponse(await tools.readView(params));
74
- }
75
- );
39
+ mcp.registerTool(...listProjects(this.services.likec4.LanguageServices));
40
+ mcp.registerTool(...readProjectSummary(this.services.likec4.LanguageServices));
41
+ mcp.registerTool(...readProjectElements(this.services.likec4.LanguageServices));
42
+ mcp.registerTool(...readElement(this.services.likec4.LanguageServices));
43
+ mcp.registerTool(...readView(this.services.likec4.LanguageServices));
44
+ mcp.registerTool(...searchElement(this.services.likec4.LanguageServices));
45
+ if (isInEditor) {
46
+ mcp.registerTool(...openView(this.services.likec4.LanguageServices));
47
+ }
76
48
  return mcp;
77
49
  }
78
50
  }
@@ -1,5 +1,5 @@
1
1
  import type { LikeC4Services } from '../../module';
2
- import type { LikeC4MCPServer } from '../LikeC4MCPServerFactory';
2
+ import type { LikeC4MCPServer } from '../interfaces';
3
3
  import { LikeC4MCPServerFactory } from './MCPServerFactory';
4
4
  export declare const WithMCPServer: {
5
5
  mcp: {
@@ -0,0 +1,68 @@
1
+ import z from 'zod';
2
+ export declare const locationSchema: z.ZodObject<{
3
+ uri: z.ZodString;
4
+ range: z.ZodObject<{
5
+ start: z.ZodObject<{
6
+ line: z.ZodNumber;
7
+ character: z.ZodNumber;
8
+ }, "strip", z.ZodTypeAny, {
9
+ line: number;
10
+ character: number;
11
+ }, {
12
+ line: number;
13
+ character: number;
14
+ }>;
15
+ end: z.ZodObject<{
16
+ line: z.ZodNumber;
17
+ character: z.ZodNumber;
18
+ }, "strip", z.ZodTypeAny, {
19
+ line: number;
20
+ character: number;
21
+ }, {
22
+ line: number;
23
+ character: number;
24
+ }>;
25
+ }, "strip", z.ZodTypeAny, {
26
+ start: {
27
+ line: number;
28
+ character: number;
29
+ };
30
+ end: {
31
+ line: number;
32
+ character: number;
33
+ };
34
+ }, {
35
+ start: {
36
+ line: number;
37
+ character: number;
38
+ };
39
+ end: {
40
+ line: number;
41
+ character: number;
42
+ };
43
+ }>;
44
+ }, "strip", z.ZodTypeAny, {
45
+ uri: string;
46
+ range: {
47
+ start: {
48
+ line: number;
49
+ character: number;
50
+ };
51
+ end: {
52
+ line: number;
53
+ character: number;
54
+ };
55
+ };
56
+ }, {
57
+ uri: string;
58
+ range: {
59
+ start: {
60
+ line: number;
61
+ character: number;
62
+ };
63
+ end: {
64
+ line: number;
65
+ character: number;
66
+ };
67
+ };
68
+ }>;
@@ -0,0 +1,14 @@
1
+ import z from "zod";
2
+ export const locationSchema = z.object({
3
+ uri: z.string(),
4
+ range: z.object({
5
+ start: z.object({
6
+ line: z.number(),
7
+ character: z.number()
8
+ }),
9
+ end: z.object({
10
+ line: z.number(),
11
+ character: z.number()
12
+ })
13
+ })
14
+ });
@@ -0,0 +1,6 @@
1
+ import z from 'zod';
2
+ export declare const listProjects: (languageServices: import("../..").LikeC4LanguageServices) => [string, {
3
+ inputSchema?: z.ZodRawShape | undefined;
4
+ }, (args: {
5
+ [x: string]: any;
6
+ }, extra: import("@modelcontextprotocol/sdk/shared/protocol").RequestHandlerExtra<import("@modelcontextprotocol/sdk/types").ServerRequest, import("@modelcontextprotocol/sdk/types").ServerNotification>) => import("@modelcontextprotocol/sdk/types").CallToolResult | Promise<import("@modelcontextprotocol/sdk/types").CallToolResult>];
@@ -0,0 +1,31 @@
1
+ import z from "zod";
2
+ import { likec4Tool } from "../utils.js";
3
+ export const listProjects = likec4Tool({
4
+ name: "list-projects",
5
+ description: `
6
+ Lists all available LikeC4 projects in the workspace.
7
+ Returns array of projects with:
8
+ - name: project name (project id)
9
+ - folder: project folder
10
+ - sources: array of project sources
11
+ `,
12
+ annotations: {
13
+ readOnlyHint: true
14
+ },
15
+ outputSchema: {
16
+ projects: z.array(z.object({
17
+ name: z.string(),
18
+ folder: z.string(),
19
+ sources: z.array(z.string())
20
+ }))
21
+ }
22
+ }, async (languageServices) => {
23
+ const projects = await languageServices.projects();
24
+ return {
25
+ projects: projects.map((p) => ({
26
+ name: p.id,
27
+ folder: p.folder.toString(),
28
+ sources: p.documents?.map((d) => d.toString()) ?? []
29
+ }))
30
+ };
31
+ });
@@ -0,0 +1,10 @@
1
+ import z from 'zod';
2
+ export declare const openView: (languageServices: import("../..").LikeC4LanguageServices) => [string, {
3
+ inputSchema?: {
4
+ viewId: z.ZodString;
5
+ project: z.ZodOptional<z.ZodString>;
6
+ } | undefined;
7
+ }, (args: {
8
+ viewId: string;
9
+ project?: string | undefined;
10
+ }, extra: import("@modelcontextprotocol/sdk/shared/protocol").RequestHandlerExtra<import("@modelcontextprotocol/sdk/types").ServerRequest, import("@modelcontextprotocol/sdk/types").ServerNotification>) => import("@modelcontextprotocol/sdk/types").CallToolResult | Promise<import("@modelcontextprotocol/sdk/types").CallToolResult>];
@@ -0,0 +1,29 @@
1
+ import { invariant } from "@likec4/core";
2
+ import z from "zod";
3
+ import { ProjectsManager } from "../../workspace/index.js";
4
+ import { likec4Tool } from "../utils.js";
5
+ export const openView = likec4Tool({
6
+ name: "open-view",
7
+ description: `
8
+ Opens the panel with the LikeC4 view in the editor.
9
+ Only one view can be opened at a time.
10
+ `.trimStart(),
11
+ annotations: {
12
+ readOnlyHint: true
13
+ },
14
+ inputSchema: {
15
+ viewId: z.string().describe("View id (name)"),
16
+ project: z.string().optional().describe('Project name (optional, will use "default" if not specified)')
17
+ }
18
+ }, async (languageServices, args) => {
19
+ const projectId = args.project ?? ProjectsManager.DefaultProjectId;
20
+ const project = languageServices.projects().find((p) => p.id === projectId);
21
+ invariant(project, `Project "${projectId}" not found`);
22
+ const model = await languageServices.computedModel(project.id);
23
+ const view = model.findView(args.viewId);
24
+ if (!view) {
25
+ throw new Error(`View with ID '${args.viewId}' not found in project ${project.id}`);
26
+ }
27
+ await languageServices.views.openView(view.id, project.id);
28
+ return `Command was sent to the editor to open the view "${view.id}"`;
29
+ });
@@ -0,0 +1,10 @@
1
+ import z from 'zod';
2
+ export declare const readElement: (languageServices: import("../..").LikeC4LanguageServices) => [string, {
3
+ inputSchema?: {
4
+ id: z.ZodString;
5
+ project: z.ZodOptional<z.ZodString>;
6
+ } | undefined;
7
+ }, (args: {
8
+ id: string;
9
+ project?: string | undefined;
10
+ }, extra: import("@modelcontextprotocol/sdk/shared/protocol").RequestHandlerExtra<import("@modelcontextprotocol/sdk/types").ServerRequest, import("@modelcontextprotocol/sdk/types").ServerNotification>) => import("@modelcontextprotocol/sdk/types").CallToolResult | Promise<import("@modelcontextprotocol/sdk/types").CallToolResult>];
@@ -0,0 +1,135 @@
1
+ import { invariant } from "@likec4/core";
2
+ import z from "zod";
3
+ import { safeCall } from "../../utils/index.js";
4
+ import { ProjectsManager } from "../../workspace/index.js";
5
+ import { likec4Tool } from "../utils.js";
6
+ import { locationSchema } from "./_common.js";
7
+ export const readElement = likec4Tool({
8
+ name: "read-element",
9
+ description: `
10
+ Returns information about LikeC4 element, includes:
11
+ - id (FQN)
12
+ - parent id (FQN of the parent element, if this element is a nested)
13
+ - kind (element kind)
14
+ - title, description, technology
15
+ - array of assigned tags
16
+ - project name this element belongs to
17
+ - metadata (key-value pairs)
18
+ - shape
19
+ - children (array of ids of the direct children elements)
20
+ - name of the default view of this element if any
21
+ - array of views that include this element
22
+ - element relationships:
23
+ - incoming and outgoing
24
+ - direct and indirect (relationships with the nested elements)
25
+ (relationships include title, kind, description, technology, tags)
26
+ - array of Deployment FQNs that represent deployed instances of this element
27
+ - source location (where the element is defined, if running in the editor)
28
+ `.trimStart(),
29
+ annotations: {
30
+ readOnlyHint: true
31
+ },
32
+ inputSchema: {
33
+ id: z.string().describe("Element id (FQN)"),
34
+ project: z.string().optional().describe('Project name (optional, will use "default" if not specified)')
35
+ },
36
+ outputSchema: {
37
+ id: z.string().describe("Element id (FQN)"),
38
+ kind: z.string().describe("Element kind"),
39
+ name: z.string().describe("Element name"),
40
+ title: z.string(),
41
+ description: z.string().nullish(),
42
+ technology: z.string().nullish(),
43
+ tags: z.array(z.string()),
44
+ project: z.string(),
45
+ metadata: z.record(z.string()),
46
+ shape: z.string(),
47
+ children: z.array(z.string()).describe("Children of this element (Array of FQNs)"),
48
+ defaultView: z.string().nullish().describe("Name of the default view of this element"),
49
+ includedInViews: z.array(z.string()).describe("Views that include this element (Array of view names)"),
50
+ relationships: z.object({
51
+ incoming: z.array(z.object({
52
+ source: z.object({
53
+ id: z.string(),
54
+ title: z.string(),
55
+ kind: z.string()
56
+ }),
57
+ kind: z.string().nullish().describe("Relationship kind"),
58
+ target: z.string().describe(
59
+ "Target element id (FQN), either this element or nested element, if relationship is indirect"
60
+ ),
61
+ title: z.string().nullish().describe("Relationship title"),
62
+ description: z.string().nullish().describe("Relationship description"),
63
+ technology: z.string().nullish().describe("Relationship technology"),
64
+ tags: z.array(z.string()).describe("Relationship tags")
65
+ })),
66
+ outgoing: z.array(z.object({
67
+ source: z.string().describe("Source element id (FQN), either this element or nested element"),
68
+ target: z.object({
69
+ id: z.string(),
70
+ title: z.string(),
71
+ kind: z.string()
72
+ }),
73
+ kind: z.string().nullish().describe("Relationship kind"),
74
+ title: z.string().nullish().describe("Relationship title"),
75
+ description: z.string().nullish().describe("Relationship description"),
76
+ technology: z.string().nullish().describe("Relationship technology"),
77
+ tags: z.array(z.string()).describe("Relationship tags")
78
+ }))
79
+ }).describe("Relationships of this element (including indirect, incoming/outgoing to/from nested elements)"),
80
+ deployedInstances: z.array(z.string()).describe("Deployed instances of this element (Array of Deployment FQNs)"),
81
+ sourceLocation: locationSchema.nullish()
82
+ }
83
+ }, async (languageServices, args) => {
84
+ const projectId = args.project ?? ProjectsManager.DefaultProjectId;
85
+ const project = languageServices.projects().find((p) => p.id === projectId);
86
+ invariant(project, `Project "${projectId}" not found`);
87
+ const model = await languageServices.computedModel(project.id);
88
+ const element = model.findElement(args.id);
89
+ invariant(element, `Element "${args.id}" not found in project "${projectId}"`);
90
+ return {
91
+ id: element.id,
92
+ name: element.name,
93
+ kind: element.kind,
94
+ title: element.title,
95
+ description: element.description.text,
96
+ technology: element.technology,
97
+ tags: [...element.tags],
98
+ project: project.id,
99
+ metadata: element.getMetadata(),
100
+ shape: element.shape,
101
+ children: [...element.children()].map((c) => c.id),
102
+ defaultView: element.defaultView?.id,
103
+ includedInViews: [...element.views()].map((v) => v.id),
104
+ relationships: {
105
+ incoming: [...element.incoming()].map((r) => ({
106
+ source: {
107
+ id: r.source.id,
108
+ title: r.source.title,
109
+ kind: r.source.kind
110
+ },
111
+ kind: r.kind,
112
+ target: r.target.id,
113
+ title: r.title,
114
+ description: r.description.text,
115
+ technology: r.technology,
116
+ tags: [...r.tags]
117
+ })),
118
+ outgoing: [...element.outgoing()].map((r) => ({
119
+ source: r.source.id,
120
+ target: {
121
+ id: r.target.id,
122
+ title: r.target.title,
123
+ kind: r.target.kind
124
+ },
125
+ kind: r.kind,
126
+ title: r.title,
127
+ description: r.description.text,
128
+ technology: r.technology,
129
+ tags: [...r.tags]
130
+ }))
131
+ },
132
+ deployedInstances: [...element.deployments()].map((i) => i.id),
133
+ sourceLocation: safeCall(() => languageServices.locate({ element: element.id, projectId }))
134
+ };
135
+ });
@@ -0,0 +1,8 @@
1
+ import z from 'zod';
2
+ export declare const readProjectElements: (languageServices: import("../..").LikeC4LanguageServices) => [string, {
3
+ inputSchema?: {
4
+ project: z.ZodOptional<z.ZodString>;
5
+ } | undefined;
6
+ }, (args: {
7
+ project?: string | undefined;
8
+ }, extra: import("@modelcontextprotocol/sdk/shared/protocol").RequestHandlerExtra<import("@modelcontextprotocol/sdk/types").ServerRequest, import("@modelcontextprotocol/sdk/types").ServerNotification>) => import("@modelcontextprotocol/sdk/types").CallToolResult | Promise<import("@modelcontextprotocol/sdk/types").CallToolResult>];
@@ -0,0 +1,93 @@
1
+ import { invariant } from "@likec4/core";
2
+ import z from "zod";
3
+ import { safeCall } from "../../utils/index.js";
4
+ import { ProjectsManager } from "../../workspace/index.js";
5
+ import { likec4Tool } from "../utils.js";
6
+ import { locationSchema } from "./_common.js";
7
+ const elementSchema = z.array(
8
+ z.discriminatedUnion("type", [
9
+ z.object({
10
+ type: z.literal("logical"),
11
+ id: z.string().describe("Element ID (FQN)"),
12
+ kind: z.string(),
13
+ title: z.string(),
14
+ description: z.string().nullish(),
15
+ technology: z.string().nullish(),
16
+ shape: z.string(),
17
+ tags: z.array(z.string()),
18
+ defaultView: z.string().nullish().describe("Name of the default view of this element"),
19
+ sourceLocation: locationSchema.nullish()
20
+ }),
21
+ z.object({
22
+ type: z.literal("deployment-node"),
23
+ id: z.string().describe("Deployment ID (FQN)"),
24
+ kind: z.string(),
25
+ title: z.string(),
26
+ description: z.string().nullish(),
27
+ technology: z.string().nullish(),
28
+ shape: z.string(),
29
+ tags: z.array(z.string()),
30
+ defaultView: z.string().nullish().describe("Name of the default view of this element"),
31
+ sourceLocation: locationSchema.nullish()
32
+ })
33
+ ])
34
+ );
35
+ export const readProjectElements = likec4Tool({
36
+ name: "read-project-elements",
37
+ annotations: {
38
+ readOnlyHint: true
39
+ },
40
+ description: `
41
+ Returns array of all elements in the project:
42
+ - type (logical or deployment-node)
43
+ - id (FQN)
44
+ - kind
45
+ - title, description and technology
46
+ - shape
47
+ - assigned tags
48
+ - name of the default view of this element if any (applies to logical elements only)
49
+ - source location (where the element is defined, if running in the editor)
50
+ `,
51
+ inputSchema: {
52
+ project: z.string().optional().describe('Project name (optional, will use "default" if not specified)')
53
+ },
54
+ outputSchema: {
55
+ elements: elementSchema
56
+ }
57
+ }, async (languageServices, args) => {
58
+ const projectId = args.project ?? ProjectsManager.DefaultProjectId;
59
+ const project = languageServices.projects().find((p) => p.id === projectId);
60
+ invariant(project, `Project "${projectId}" not found`);
61
+ const model = await languageServices.computedModel(project.id);
62
+ const elements = [];
63
+ for (const el of model.elements()) {
64
+ elements.push({
65
+ type: "logical",
66
+ id: el.id,
67
+ title: el.title,
68
+ description: el.description.text,
69
+ technology: el.technology,
70
+ kind: el.kind,
71
+ tags: [...el.tags],
72
+ shape: el.shape,
73
+ defaultView: el.defaultView?.id,
74
+ sourceLocation: safeCall(() => languageServices.locate({ element: el.id, projectId }))
75
+ });
76
+ }
77
+ for (const el of model.deployment.nodes()) {
78
+ elements.push({
79
+ type: "deployment-node",
80
+ id: el.id,
81
+ title: el.title,
82
+ description: el.description.text,
83
+ technology: el.technology,
84
+ kind: el.kind,
85
+ tags: [...el.tags],
86
+ shape: el.shape,
87
+ sourceLocation: safeCall(() => languageServices.locate({ deployment: el.id, projectId }))
88
+ });
89
+ }
90
+ return {
91
+ elements
92
+ };
93
+ });
@@ -0,0 +1,8 @@
1
+ import z from 'zod';
2
+ export declare const readProjectSummary: (languageServices: import("../..").LikeC4LanguageServices) => [string, {
3
+ inputSchema?: {
4
+ project: z.ZodOptional<z.ZodString>;
5
+ } | undefined;
6
+ }, (args: {
7
+ project?: string | undefined;
8
+ }, extra: import("@modelcontextprotocol/sdk/shared/protocol").RequestHandlerExtra<import("@modelcontextprotocol/sdk/types").ServerRequest, import("@modelcontextprotocol/sdk/types").ServerNotification>) => import("@modelcontextprotocol/sdk/types").CallToolResult | Promise<import("@modelcontextprotocol/sdk/types").CallToolResult>];