@malloy-publisher/server 0.0.80 → 0.0.82
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/dist/app/assets/{RenderedResult-BAZuT25g-BCBDzvJl.js → RenderedResult-BAZuT25g-IRFKLhAP.js} +2 -2
- package/dist/app/assets/{index-89qYWF11.js → index-B_dNAjy-.js} +1 -1
- package/dist/app/assets/{index-CKfraTxm.js → index-CW_uoJdN.js} +1 -1
- package/dist/app/assets/index-DL8Ov73S.js +432 -0
- package/dist/app/assets/{index.umd-DoxV6txm.js → index.umd-B0FgcoQt.js} +1 -1
- package/dist/app/index.html +1 -1
- package/dist/instrumentation.js +10262 -3
- package/dist/server.js +149448 -150333
- package/package.json +1 -1
- package/src/controller/connection.controller.ts +3 -2
- package/src/data_styles.ts +2 -1
- package/src/instrumentation.ts +5 -5
- package/src/logger.ts +46 -0
- package/src/mcp/handler_utils.ts +7 -6
- package/src/mcp/prompts/prompt_service.ts +12 -12
- package/src/mcp/resources/notebook_resource.ts +11 -10
- package/src/mcp/resources/package_resource.ts +21 -20
- package/src/mcp/resources/project_resource.ts +22 -23
- package/src/mcp/resources/query_resource.ts +12 -11
- package/src/mcp/resources/source_resource.ts +12 -11
- package/src/mcp/resources/view_resource.ts +12 -11
- package/src/mcp/server.ts +22 -21
- package/src/mcp/tools/execute_query_tool.ts +8 -11
- package/src/server.ts +41 -45
- package/src/service/db_utils.ts +17 -17
- package/src/service/model.ts +2 -1
- package/src/service/package.ts +3 -2
- package/src/service/project_store.ts +7 -7
- package/src/service/scheduler.ts +4 -3
- package/dist/app/assets/index-DtRl_5zk.js +0 -432
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import { Connection, PersistSQLResults } from "@malloydata/malloy/connection";
|
|
|
3
3
|
import { TableSourceDef } from "../../../../../malloy/packages/malloy/dist";
|
|
4
4
|
import { components } from "../api";
|
|
5
5
|
import { ConnectionError } from "../errors";
|
|
6
|
+
import { logger } from "../logger";
|
|
6
7
|
import {
|
|
7
8
|
getSchemasForConnection,
|
|
8
9
|
getTablesForSchema,
|
|
@@ -115,7 +116,7 @@ export class ConnectionController {
|
|
|
115
116
|
columns: fields,
|
|
116
117
|
};
|
|
117
118
|
} catch (error) {
|
|
118
|
-
|
|
119
|
+
logger.error("error", { error });
|
|
119
120
|
throw new ConnectionError((error as Error).message);
|
|
120
121
|
}
|
|
121
122
|
}
|
|
@@ -134,7 +135,7 @@ export class ConnectionController {
|
|
|
134
135
|
}
|
|
135
136
|
if (runSQLOptions.abortSignal) {
|
|
136
137
|
// Add support for abortSignal in the future
|
|
137
|
-
|
|
138
|
+
logger.info("Clearing unsupported abortSignal");
|
|
138
139
|
runSQLOptions.abortSignal = undefined;
|
|
139
140
|
}
|
|
140
141
|
|
package/src/data_styles.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { URLReader } from "@malloydata/malloy";
|
|
2
2
|
import { DataStyles } from "@malloydata/render";
|
|
3
|
+
import { logger } from "./logger";
|
|
3
4
|
|
|
4
5
|
export function compileDataStyles(styles: string): DataStyles {
|
|
5
6
|
try {
|
|
@@ -26,7 +27,7 @@ export async function dataStylesForFile(
|
|
|
26
27
|
try {
|
|
27
28
|
stylesText = await urlReader.readURL(new URL(fileName, url));
|
|
28
29
|
} catch (error) {
|
|
29
|
-
|
|
30
|
+
logger.error(`Error loading data style '${fileName}': ${error}`);
|
|
30
31
|
stylesText = "{}";
|
|
31
32
|
}
|
|
32
33
|
styles = { ...styles, ...compileDataStyles(stylesText) };
|
package/src/instrumentation.ts
CHANGED
|
@@ -11,17 +11,17 @@ import {
|
|
|
11
11
|
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
12
12
|
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
13
13
|
import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs";
|
|
14
|
+
import { logger } from "./logger";
|
|
14
15
|
|
|
15
16
|
function instrument() {
|
|
16
17
|
const otelCollectorUrl = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
17
18
|
if (!otelCollectorUrl) {
|
|
18
|
-
|
|
19
|
+
logger.info("No OTLP collector URL found, skipping instrumentation");
|
|
19
20
|
return;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
otelCollectorUrl,
|
|
23
|
+
logger.info(
|
|
24
|
+
`Initializing OpenTelemetry SDK with OTLP collector at ${otelCollectorUrl}`,
|
|
25
25
|
);
|
|
26
26
|
const traceExporter = new OTLPTraceExporter({
|
|
27
27
|
url: `${otelCollectorUrl}/v1/traces`,
|
|
@@ -53,7 +53,7 @@ function instrument() {
|
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
sdk.start();
|
|
56
|
-
|
|
56
|
+
logger.info("Initialized OpenTelemetry SDK");
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
instrument();
|
package/src/logger.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { AxiosError } from "axios";
|
|
2
|
+
import { RequestHandler } from "express";
|
|
3
|
+
import winston from "winston";
|
|
4
|
+
|
|
5
|
+
export const logger = winston.createLogger({
|
|
6
|
+
format: winston.format.combine(
|
|
7
|
+
winston.format.uncolorize(),
|
|
8
|
+
winston.format.timestamp(),
|
|
9
|
+
winston.format.json(),
|
|
10
|
+
),
|
|
11
|
+
transports: [new winston.transports.Console()],
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const loggerMiddleware: RequestHandler = (req, res, next) => {
|
|
15
|
+
const startTime = performance.now();
|
|
16
|
+
res.on("finish", () => {
|
|
17
|
+
const endTime = performance.now();
|
|
18
|
+
logger.info(`${req.method} ${req.url}`, {
|
|
19
|
+
statusCode: res.statusCode,
|
|
20
|
+
duration: endTime - startTime,
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
next();
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const logAxiosError = (error: AxiosError) => {
|
|
27
|
+
if (error.response) {
|
|
28
|
+
// The request was made and the server responded with a status code
|
|
29
|
+
// that falls out of the range of 2xx
|
|
30
|
+
logger.error("Axios error", {
|
|
31
|
+
data: error.response.data,
|
|
32
|
+
status: error.response.status,
|
|
33
|
+
headers: error.response.headers,
|
|
34
|
+
});
|
|
35
|
+
} else if (error.request) {
|
|
36
|
+
// The request was made but no response was received
|
|
37
|
+
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
38
|
+
// http.ClientRequest in node.js
|
|
39
|
+
logger.error("Failed to receive a response from the server", {
|
|
40
|
+
request: error.request,
|
|
41
|
+
});
|
|
42
|
+
} else {
|
|
43
|
+
// Something happened in setting up the request that triggered an Error
|
|
44
|
+
logger.error("Error", { error });
|
|
45
|
+
}
|
|
46
|
+
};
|
package/src/mcp/handler_utils.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
type ErrorDetails,
|
|
16
16
|
} from "./error_messages";
|
|
17
17
|
import type { Model } from "../service/model";
|
|
18
|
+
import { logger } from "../logger";
|
|
18
19
|
|
|
19
20
|
// Custom error to wrap specific GetResource application errors
|
|
20
21
|
export class McpGetResourceError extends Error {
|
|
@@ -71,9 +72,9 @@ export async function handleResourceGet<
|
|
|
71
72
|
],
|
|
72
73
|
};
|
|
73
74
|
} catch (error) {
|
|
74
|
-
|
|
75
|
+
logger.error(
|
|
75
76
|
`[MCP Server Error] Error reading ${resourceType} ${uri.href}:`,
|
|
76
|
-
error,
|
|
77
|
+
{ error },
|
|
77
78
|
);
|
|
78
79
|
|
|
79
80
|
let errorDetails: ErrorDetails;
|
|
@@ -84,9 +85,9 @@ export async function handleResourceGet<
|
|
|
84
85
|
errorDetails = error.details;
|
|
85
86
|
} else {
|
|
86
87
|
// Catch-all for truly unexpected errors not handled by the specific getData logic
|
|
87
|
-
|
|
88
|
+
logger.error(
|
|
88
89
|
"[MCP Server Error] Unexpected error type caught in handleResourceGet:",
|
|
89
|
-
error,
|
|
90
|
+
{ error },
|
|
90
91
|
);
|
|
91
92
|
errorDetails = getInternalError(
|
|
92
93
|
`GetResource (${resourceType})`,
|
|
@@ -163,9 +164,9 @@ export async function getModelForQuery(
|
|
|
163
164
|
// Unexpected error during setup
|
|
164
165
|
errorDetails = getInternalError("executeQuery (Setup)", error);
|
|
165
166
|
}
|
|
166
|
-
|
|
167
|
+
logger.error(
|
|
167
168
|
`[MCP Server Error] Error accessing package/model for query: ${projectName}/${packageName}/${modelPath}`,
|
|
168
|
-
error,
|
|
169
|
+
{ error },
|
|
169
170
|
);
|
|
170
171
|
return { error: errorDetails };
|
|
171
172
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { logger } from "../../logger";
|
|
2
4
|
import { ProjectStore } from "../../service/project_store";
|
|
3
|
-
import { MALLOY_PROMPTS } from "./prompt_definitions";
|
|
4
5
|
import { promptHandlerMap } from "./handlers";
|
|
5
|
-
import {
|
|
6
|
+
import { MALLOY_PROMPTS } from "./prompt_definitions";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Registers all defined Malloy prompts with the MCP server.
|
|
@@ -14,8 +15,8 @@ export function registerPromptCapability(
|
|
|
14
15
|
mcpServer: McpServer,
|
|
15
16
|
projectStore: ProjectStore,
|
|
16
17
|
): void {
|
|
17
|
-
|
|
18
|
-
const startTime =
|
|
18
|
+
logger.info("[MCP Init] Registering prompt capability...");
|
|
19
|
+
const startTime = performance.now();
|
|
19
20
|
let registeredCount = 0;
|
|
20
21
|
|
|
21
22
|
for (const promptKey in MALLOY_PROMPTS) {
|
|
@@ -44,24 +45,23 @@ export function registerPromptCapability(
|
|
|
44
45
|
);
|
|
45
46
|
|
|
46
47
|
registeredCount++;
|
|
47
|
-
|
|
48
|
+
logger.info(
|
|
48
49
|
`[MCP Prompt Reg] Registered prompt: ${promptDefinition.id}`,
|
|
49
50
|
);
|
|
50
51
|
} else if (!handler) {
|
|
51
|
-
|
|
52
|
+
logger.warn(
|
|
52
53
|
`Handler not found for prompt: ${promptDefinition.id}. It will not be registered.`,
|
|
53
54
|
);
|
|
54
55
|
} else if (!(promptDefinition.argsSchema instanceof z.ZodObject)) {
|
|
55
|
-
|
|
56
|
+
logger.warn(
|
|
56
57
|
`Prompt definition for ${promptDefinition.id} does not have a ZodObject schema. It will not be registered.`,
|
|
57
58
|
);
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
const endTime =
|
|
62
|
-
|
|
63
|
-
`[MCP Init] Finished registering prompts. Registered: ${registeredCount}
|
|
64
|
-
|
|
65
|
-
}ms`,
|
|
62
|
+
const endTime = performance.now();
|
|
63
|
+
logger.info(
|
|
64
|
+
`[MCP Init] Finished registering prompts. Registered: ${registeredCount}`,
|
|
65
|
+
{ duration: endTime - startTime },
|
|
66
66
|
);
|
|
67
67
|
}
|
|
@@ -2,21 +2,22 @@ import {
|
|
|
2
2
|
McpServer,
|
|
3
3
|
ResourceTemplate,
|
|
4
4
|
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
-
import {
|
|
5
|
+
import { URL } from "url";
|
|
6
|
+
import type { components } from "../../api"; // Need this for CompiledModel type
|
|
6
7
|
import {
|
|
8
|
+
ModelCompilationError,
|
|
7
9
|
ModelNotFoundError,
|
|
8
10
|
PackageNotFoundError,
|
|
9
|
-
ModelCompilationError,
|
|
10
11
|
} from "../../errors";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
12
|
+
import { logger } from "../../logger";
|
|
13
|
+
import { ProjectStore } from "../../service/project_store";
|
|
13
14
|
import {
|
|
14
|
-
getNotFoundError,
|
|
15
|
-
getMalloyErrorDetails,
|
|
16
15
|
getInternalError,
|
|
16
|
+
getMalloyErrorDetails,
|
|
17
|
+
getNotFoundError,
|
|
17
18
|
} from "../error_messages";
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
19
|
+
import { handleResourceGet, McpGetResourceError } from "../handler_utils";
|
|
20
|
+
import { RESOURCE_METADATA } from "../resource_metadata";
|
|
20
21
|
|
|
21
22
|
// Define the expected parameter types
|
|
22
23
|
type NotebookParams = {
|
|
@@ -119,9 +120,9 @@ export function registerNotebookResource(
|
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
// Handle other unexpected errors
|
|
122
|
-
|
|
123
|
+
logger.error(
|
|
123
124
|
`[MCP Server Error] Error fetching notebook '${notebookName}' from ${uri.href}:`,
|
|
124
|
-
error,
|
|
125
|
+
{ error },
|
|
125
126
|
);
|
|
126
127
|
const fallbackErrorDetails = getInternalError(
|
|
127
128
|
`GetResource (notebook: ${uri.href})`,
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import { URL } from "url";
|
|
2
1
|
import {
|
|
3
2
|
McpServer,
|
|
4
3
|
ResourceTemplate,
|
|
5
4
|
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
5
|
import { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
|
|
7
|
-
import {
|
|
6
|
+
import { URL } from "url";
|
|
8
7
|
import { PackageNotFoundError } from "../../errors";
|
|
8
|
+
import { logger } from "../../logger";
|
|
9
|
+
import { ProjectStore } from "../../service/project_store";
|
|
10
|
+
import {
|
|
11
|
+
getInternalError,
|
|
12
|
+
getNotFoundError,
|
|
13
|
+
type ErrorDetails,
|
|
14
|
+
} from "../error_messages";
|
|
9
15
|
import {
|
|
16
|
+
buildMalloyUri,
|
|
10
17
|
handleResourceGet,
|
|
11
18
|
McpGetResourceError,
|
|
12
|
-
buildMalloyUri,
|
|
13
19
|
} from "../handler_utils";
|
|
14
20
|
import { RESOURCE_METADATA } from "../resource_metadata";
|
|
15
|
-
import {
|
|
16
|
-
getNotFoundError,
|
|
17
|
-
getInternalError,
|
|
18
|
-
type ErrorDetails,
|
|
19
|
-
} from "../error_messages";
|
|
20
21
|
|
|
21
22
|
// *** Define handleGetPackageContents function ***
|
|
22
23
|
async function handleGetPackageContents(
|
|
@@ -47,7 +48,7 @@ async function handleGetPackageContents(
|
|
|
47
48
|
const entryType = entry.type; // 'source' or 'notebook'
|
|
48
49
|
|
|
49
50
|
if (typeof entryPath !== "string" || entryPath === "") {
|
|
50
|
-
|
|
51
|
+
logger.warn(
|
|
51
52
|
`[MCP Server Warning] Skipping entry in package ${packageName} with invalid path:`,
|
|
52
53
|
entry,
|
|
53
54
|
);
|
|
@@ -64,7 +65,7 @@ async function handleGetPackageContents(
|
|
|
64
65
|
case "notebook": {
|
|
65
66
|
const resourceMetadata = RESOURCE_METADATA.notebook;
|
|
66
67
|
if (!resourceMetadata) {
|
|
67
|
-
|
|
68
|
+
logger.warn(
|
|
68
69
|
`[MCP Server Warning] No metadata found for entry type 'notebook' path ${entryPath} in package ${packageName}`,
|
|
69
70
|
);
|
|
70
71
|
continue;
|
|
@@ -84,7 +85,7 @@ async function handleGetPackageContents(
|
|
|
84
85
|
// 1. Add the source file itself
|
|
85
86
|
const sourceResourceMetadata = RESOURCE_METADATA.source;
|
|
86
87
|
if (!sourceResourceMetadata) {
|
|
87
|
-
|
|
88
|
+
logger.warn(
|
|
88
89
|
`[MCP Server Warning] No metadata found for entry type 'source' path ${entryPath} in package ${packageName}`,
|
|
89
90
|
);
|
|
90
91
|
// Continue processing views even if source metadata is missing
|
|
@@ -114,7 +115,7 @@ async function handleGetPackageContents(
|
|
|
114
115
|
const viewResourceMetadata =
|
|
115
116
|
RESOURCE_METADATA.view;
|
|
116
117
|
if (!viewResourceMetadata) {
|
|
117
|
-
|
|
118
|
+
logger.warn(
|
|
118
119
|
`[MCP Server Warning] No metadata found for entry type 'view' named '${view.name}' in source '${source.name}'`,
|
|
119
120
|
);
|
|
120
121
|
continue;
|
|
@@ -135,25 +136,25 @@ async function handleGetPackageContents(
|
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
138
|
} else {
|
|
138
|
-
|
|
139
|
+
logger.warn(
|
|
139
140
|
`[MCP Server Warning] Could not retrieve sources or sources is not an array for model ${entryPath}`,
|
|
140
141
|
);
|
|
141
142
|
}
|
|
142
143
|
} else {
|
|
143
|
-
|
|
144
|
+
logger.warn(
|
|
144
145
|
`[MCP Server Warning] Could not load model for path ${entryPath} to extract views.`,
|
|
145
146
|
);
|
|
146
147
|
}
|
|
147
148
|
} catch (modelLoadError) {
|
|
148
149
|
// Log error if model loading fails, but continue processing other files
|
|
149
|
-
|
|
150
|
+
logger.warn(
|
|
150
151
|
`[MCP Server Warning] Failed to load model ${entryPath} to extract views: ${modelLoadError instanceof Error ? modelLoadError.message : String(modelLoadError)}`,
|
|
151
152
|
);
|
|
152
153
|
}
|
|
153
154
|
break;
|
|
154
155
|
}
|
|
155
156
|
default:
|
|
156
|
-
|
|
157
|
+
logger.warn(
|
|
157
158
|
`[MCP Server Warning] Unknown entry type '${entryType}' for path ${entryPath} in package ${packageName}`,
|
|
158
159
|
);
|
|
159
160
|
continue; // Skip unknown types
|
|
@@ -176,9 +177,9 @@ async function handleGetPackageContents(
|
|
|
176
177
|
`Invalid project/package identifier in URI '${uri.href}'`,
|
|
177
178
|
);
|
|
178
179
|
} else {
|
|
179
|
-
|
|
180
|
+
logger.error(
|
|
180
181
|
`[MCP Server Error] Error getting package contents for ${uri.href}:`,
|
|
181
|
-
error,
|
|
182
|
+
{ error },
|
|
182
183
|
);
|
|
183
184
|
errorDetails = getInternalError(
|
|
184
185
|
`GetResource (package contents: ${uri.href})`,
|
|
@@ -305,9 +306,9 @@ export function registerPackageResource(
|
|
|
305
306
|
],
|
|
306
307
|
};
|
|
307
308
|
} catch (error) {
|
|
308
|
-
|
|
309
|
+
logger.error(
|
|
309
310
|
`[MCP Server Error] Error reading package contents ${uri.href}:`,
|
|
310
|
-
error,
|
|
311
|
+
{ error },
|
|
311
312
|
);
|
|
312
313
|
|
|
313
314
|
let errorDetails: ErrorDetails;
|
|
@@ -3,10 +3,11 @@ import {
|
|
|
3
3
|
ResourceTemplate,
|
|
4
4
|
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import type { ListResourcesResult } from "@modelcontextprotocol/sdk/types.js"; // Needed for list return type
|
|
6
|
+
import { logger } from "../../logger";
|
|
6
7
|
import { ProjectStore } from "../../service/project_store";
|
|
8
|
+
import { getInternalError, getNotFoundError } from "../error_messages"; // Needed for error handling in list AND get
|
|
7
9
|
import { handleResourceGet, McpGetResourceError } from "../handler_utils";
|
|
8
10
|
import { RESOURCE_METADATA } from "../resource_metadata";
|
|
9
|
-
import { getInternalError, getNotFoundError } from "../error_messages"; // Needed for error handling in list AND get
|
|
10
11
|
|
|
11
12
|
// Define an interface for the package object augmented with project name
|
|
12
13
|
interface PackageWithProject {
|
|
@@ -32,20 +33,20 @@ export function registerProjectResource(
|
|
|
32
33
|
* If projectName is not specified (general ListResources call), lists packages for the default 'home' project.
|
|
33
34
|
*/
|
|
34
35
|
list: async (/* extra: ListProjectExtra - Deleted */): Promise<ListResourcesResult> => {
|
|
35
|
-
|
|
36
|
+
logger.info(
|
|
36
37
|
"[MCP LOG] Entering ListResources (project) handler (listing ALL packages)...",
|
|
37
38
|
);
|
|
38
39
|
// Ignore parameters from 'extra' as URI path params aren't passed to list handlers.
|
|
39
40
|
|
|
40
41
|
try {
|
|
41
42
|
const allProjects = await projectStore.listProjects();
|
|
42
|
-
|
|
43
|
+
logger.info(
|
|
43
44
|
`[MCP LOG] Found ${allProjects.length} projects defined.`,
|
|
44
45
|
);
|
|
45
46
|
|
|
46
47
|
const packagePromises = allProjects.map(async (proj) => {
|
|
47
48
|
try {
|
|
48
|
-
|
|
49
|
+
logger.info(
|
|
49
50
|
`[MCP LOG] Getting project '${proj.name}' to list its packages...`,
|
|
50
51
|
);
|
|
51
52
|
const projectInstance = await projectStore.getProject(
|
|
@@ -53,7 +54,7 @@ export function registerProjectResource(
|
|
|
53
54
|
false,
|
|
54
55
|
); // Use proj.name
|
|
55
56
|
const packages = await projectInstance.listPackages();
|
|
56
|
-
|
|
57
|
+
logger.info(
|
|
57
58
|
`[MCP LOG] Found ${packages.length} packages in project '${proj.name}'.`,
|
|
58
59
|
);
|
|
59
60
|
// Return packages along with their project name for URI construction
|
|
@@ -62,9 +63,9 @@ export function registerProjectResource(
|
|
|
62
63
|
projectName: proj.name,
|
|
63
64
|
}));
|
|
64
65
|
} catch (projectError) {
|
|
65
|
-
|
|
66
|
+
logger.error(
|
|
66
67
|
`[MCP Server Error] Error getting/listing packages for project ${proj.name}:`,
|
|
67
|
-
projectError,
|
|
68
|
+
{ error: projectError },
|
|
68
69
|
);
|
|
69
70
|
return []; // Return empty array for this project on error
|
|
70
71
|
}
|
|
@@ -80,7 +81,7 @@ export function registerProjectResource(
|
|
|
80
81
|
.value,
|
|
81
82
|
);
|
|
82
83
|
|
|
83
|
-
|
|
84
|
+
logger.info(
|
|
84
85
|
`[MCP LOG] Total packages found across all projects: ${allPackagesWithProjectName.length}`,
|
|
85
86
|
);
|
|
86
87
|
|
|
@@ -100,7 +101,7 @@ export function registerProjectResource(
|
|
|
100
101
|
};
|
|
101
102
|
});
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
logger.info(
|
|
104
105
|
`[MCP LOG] ListResources (project): Returning ${mappedResources.length} package resources.`,
|
|
105
106
|
);
|
|
106
107
|
return {
|
|
@@ -108,19 +109,17 @@ export function registerProjectResource(
|
|
|
108
109
|
};
|
|
109
110
|
} catch (error) {
|
|
110
111
|
// Catch errors from projectStore.listProjects() itself
|
|
111
|
-
|
|
112
|
-
`[MCP Server Error] Error listing projects:`,
|
|
112
|
+
logger.error(`[MCP Server Error] Error listing projects:`, {
|
|
113
113
|
error,
|
|
114
|
-
);
|
|
114
|
+
});
|
|
115
115
|
const errorDetails = getInternalError(
|
|
116
116
|
`ListResources (project - initial list)`,
|
|
117
117
|
error,
|
|
118
118
|
);
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
console.log(
|
|
119
|
+
logger.error("MCP ListResources (project) error:", {
|
|
120
|
+
error: errorDetails.message,
|
|
121
|
+
});
|
|
122
|
+
logger.info(
|
|
124
123
|
"[MCP LOG] ListResources (project): Returning empty on error listing projects.",
|
|
125
124
|
);
|
|
126
125
|
return { resources: [] };
|
|
@@ -134,34 +133,34 @@ export function registerProjectResource(
|
|
|
134
133
|
params,
|
|
135
134
|
"project",
|
|
136
135
|
async ({ projectName }: { projectName?: unknown }) => {
|
|
137
|
-
|
|
136
|
+
logger.info(
|
|
138
137
|
`[MCP LOG] Entering GetResource (project) handler for projectName: ${projectName}`,
|
|
139
138
|
);
|
|
140
139
|
// Validate project name parameter
|
|
141
140
|
if (typeof projectName !== "string") {
|
|
142
|
-
|
|
141
|
+
logger.error(
|
|
143
142
|
"[MCP LOG] GetResource (project): Invalid project name param.",
|
|
144
143
|
);
|
|
145
144
|
throw new Error("Invalid project name parameter.");
|
|
146
145
|
}
|
|
147
146
|
|
|
148
147
|
try {
|
|
149
|
-
|
|
148
|
+
logger.info(
|
|
150
149
|
`[MCP LOG] GetResource: Getting project '${projectName}'...`,
|
|
151
150
|
);
|
|
152
151
|
// Get the project instance, but we might not need its metadata directly
|
|
153
152
|
await projectStore.getProject(projectName, false);
|
|
154
153
|
// Construct the definition object expected by the test
|
|
155
154
|
const definition = { name: projectName };
|
|
156
|
-
|
|
155
|
+
logger.info(
|
|
157
156
|
`[MCP LOG] GetResource (project): Returning definition for '${projectName}'.`,
|
|
158
157
|
);
|
|
159
158
|
// Return the explicit definition structure
|
|
160
159
|
return definition;
|
|
161
160
|
} catch (error) {
|
|
162
|
-
|
|
161
|
+
logger.error(
|
|
163
162
|
`[MCP LOG] GetResource (project): Error caught for '${projectName}':`,
|
|
164
|
-
error,
|
|
163
|
+
{ error },
|
|
165
164
|
);
|
|
166
165
|
// Catch expected errors from this specific resource logic
|
|
167
166
|
if (error instanceof Error) {
|
|
@@ -2,21 +2,22 @@ import {
|
|
|
2
2
|
McpServer,
|
|
3
3
|
ResourceTemplate,
|
|
4
4
|
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
-
import {
|
|
5
|
+
import { URL } from "url";
|
|
6
|
+
import type { components } from "../../api"; // Need this for Query definition type
|
|
6
7
|
import { ModelCompilationError } from "../../errors";
|
|
8
|
+
import { logger } from "../../logger";
|
|
9
|
+
import { ProjectStore } from "../../service/project_store";
|
|
10
|
+
import {
|
|
11
|
+
getInternalError,
|
|
12
|
+
getMalloyErrorDetails,
|
|
13
|
+
getNotFoundError,
|
|
14
|
+
} from "../error_messages";
|
|
7
15
|
import {
|
|
16
|
+
getModelForQuery,
|
|
8
17
|
handleResourceGet,
|
|
9
18
|
McpGetResourceError,
|
|
10
|
-
getModelForQuery,
|
|
11
19
|
} from "../handler_utils";
|
|
12
20
|
import { RESOURCE_METADATA } from "../resource_metadata";
|
|
13
|
-
import {
|
|
14
|
-
getNotFoundError,
|
|
15
|
-
getMalloyErrorDetails,
|
|
16
|
-
getInternalError,
|
|
17
|
-
} from "../error_messages";
|
|
18
|
-
import type { components } from "../../api"; // Need this for Query definition type
|
|
19
|
-
import { URL } from "url";
|
|
20
21
|
|
|
21
22
|
// Define the expected parameter types
|
|
22
23
|
type QueryParams = {
|
|
@@ -99,9 +100,9 @@ export function registerQueryResource(
|
|
|
99
100
|
);
|
|
100
101
|
throw new McpGetResourceError(errorDetails);
|
|
101
102
|
}
|
|
102
|
-
|
|
103
|
+
logger.error(
|
|
103
104
|
`[MCP Server Error] Error fetching query '${queryName}' from ${uri.href}:`,
|
|
104
|
-
error,
|
|
105
|
+
{ error },
|
|
105
106
|
);
|
|
106
107
|
const fallbackErrorDetails = getInternalError(
|
|
107
108
|
`GetResource (query: ${uri.href})`,
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import { URL } from "url"; // Import URL
|
|
2
1
|
import {
|
|
3
2
|
McpServer,
|
|
4
3
|
ResourceTemplate,
|
|
5
4
|
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
-
import {
|
|
5
|
+
import { URL } from "url"; // Import URL
|
|
6
|
+
import type { components } from "../../api"; // Need this for Source definition type
|
|
7
7
|
import { ModelCompilationError } from "../../errors";
|
|
8
|
+
import { logger } from "../../logger";
|
|
9
|
+
import { ProjectStore } from "../../service/project_store";
|
|
10
|
+
import {
|
|
11
|
+
getInternalError,
|
|
12
|
+
getMalloyErrorDetails,
|
|
13
|
+
getNotFoundError,
|
|
14
|
+
} from "../error_messages";
|
|
8
15
|
import {
|
|
16
|
+
getModelForQuery,
|
|
9
17
|
handleResourceGet,
|
|
10
18
|
McpGetResourceError,
|
|
11
|
-
getModelForQuery,
|
|
12
19
|
} from "../handler_utils";
|
|
13
20
|
import { RESOURCE_METADATA } from "../resource_metadata";
|
|
14
|
-
import {
|
|
15
|
-
getNotFoundError,
|
|
16
|
-
getMalloyErrorDetails,
|
|
17
|
-
getInternalError,
|
|
18
|
-
} from "../error_messages";
|
|
19
|
-
import type { components } from "../../api"; // Need this for Source definition type
|
|
20
21
|
|
|
21
22
|
// Define the expected parameter types for this resource
|
|
22
23
|
type SourceParams = {
|
|
@@ -119,9 +120,9 @@ export function registerSourceResource(
|
|
|
119
120
|
throw new McpGetResourceError(errorDetails);
|
|
120
121
|
}
|
|
121
122
|
// Handle other potential errors (e.g., invalid params error from initial check)
|
|
122
|
-
|
|
123
|
+
logger.error(
|
|
123
124
|
`[MCP Server Error] Error fetching source '${sourceName}' from ${uri.href}:`,
|
|
124
|
-
error,
|
|
125
|
+
{ error },
|
|
125
126
|
);
|
|
126
127
|
// Fallback: Use getInternalError for unexpected issues
|
|
127
128
|
// Or getNotFoundError if it's likely a resource access issue
|
|
@@ -2,21 +2,22 @@ import {
|
|
|
2
2
|
McpServer,
|
|
3
3
|
ResourceTemplate,
|
|
4
4
|
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
-
import {
|
|
5
|
+
import { URL } from "url";
|
|
6
|
+
import type { components } from "../../api"; // Need this for View definition type
|
|
6
7
|
import { ModelCompilationError } from "../../errors";
|
|
8
|
+
import { logger } from "../../logger";
|
|
9
|
+
import { ProjectStore } from "../../service/project_store";
|
|
10
|
+
import {
|
|
11
|
+
getInternalError,
|
|
12
|
+
getMalloyErrorDetails,
|
|
13
|
+
getNotFoundError,
|
|
14
|
+
} from "../error_messages";
|
|
7
15
|
import {
|
|
16
|
+
getModelForQuery,
|
|
8
17
|
handleResourceGet,
|
|
9
18
|
McpGetResourceError,
|
|
10
|
-
getModelForQuery,
|
|
11
19
|
} from "../handler_utils";
|
|
12
20
|
import { RESOURCE_METADATA } from "../resource_metadata";
|
|
13
|
-
import {
|
|
14
|
-
getNotFoundError,
|
|
15
|
-
getMalloyErrorDetails,
|
|
16
|
-
getInternalError,
|
|
17
|
-
} from "../error_messages";
|
|
18
|
-
import type { components } from "../../api"; // Need this for View definition type
|
|
19
|
-
import { URL } from "url";
|
|
20
21
|
|
|
21
22
|
// Define the expected parameter types
|
|
22
23
|
type ViewParams = {
|
|
@@ -118,9 +119,9 @@ export function registerViewResource(
|
|
|
118
119
|
);
|
|
119
120
|
throw new McpGetResourceError(errorDetails);
|
|
120
121
|
}
|
|
121
|
-
|
|
122
|
+
logger.error(
|
|
122
123
|
`[MCP Server Error] Error fetching view '${viewName}' from ${uri.href}:`,
|
|
123
|
-
error,
|
|
124
|
+
{ error },
|
|
124
125
|
);
|
|
125
126
|
const fallbackErrorDetails = getInternalError(
|
|
126
127
|
`GetResource (view: ${uri.href})`,
|