@pagopa/dx-mcpserver 0.1.1 → 0.1.3

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.
@@ -37,13 +37,14 @@ export async function handleSearchEndpoint(req, res, config, kbRuntimeClient) {
37
37
  }
38
38
  const { number_of_results: numberOfResults, query } = result.data;
39
39
  const results = await queryKnowledgeBaseStructured(config.aws.knowledgeBaseId, query, kbRuntimeClient, numberOfResults, config.aws.rerankingEnabled);
40
- // Format results with content, score, and source URL
40
+ // Format results with content, score, source URL, and source file URL
41
41
  const formattedResults = results.map((result) => ({
42
42
  content: result.content,
43
43
  score: result.score,
44
44
  source: result.location?.type === "WEB"
45
45
  ? result.location.webLocation?.url
46
46
  : undefined,
47
+ source_file_url: result.sourceFileUrl,
47
48
  }));
48
49
  sendJsonResponse(res, 200, {
49
50
  query,
@@ -1,4 +1,6 @@
1
1
  import { RetrieveCommand, } from "@aws-sdk/client-bedrock-agent-runtime";
2
+ import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
3
+ import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
2
4
  import { getLogger } from "@logtape/logtape";
3
5
  import { rerankingSupportedRegions } from "../config/aws.js";
4
6
  /**
@@ -50,16 +52,23 @@ export async function queryKnowledgeBase(knowledgeBaseId, query, kbAgentClient,
50
52
  const response = await kbAgentClient.send(command);
51
53
  const results = response.retrievalResults || [];
52
54
  const documents = [];
55
+ // Create S3 client for pre-signed URLs (reuse region from Bedrock client)
56
+ const s3Client = new S3Client({ region: clientRegion });
53
57
  for (const result of results) {
54
58
  if (result.content?.type === "IMAGE") {
55
59
  logger.warn("Images are not supported at this time. Skipping...");
56
60
  continue;
57
61
  }
58
62
  else if (result.content?.text) {
63
+ // Generate pre-signed URL if S3 location is available
64
+ const preSignedUrl = result.location?.type === "S3" && result.location.s3Location?.uri
65
+ ? await generatePreSignedUrl(result.location.s3Location.uri, s3Client, logger)
66
+ : undefined;
59
67
  documents.push({
60
68
  content: result.content.text,
61
69
  location: resolveToWebsiteUrl(result.location),
62
70
  score: result.score || -1.0,
71
+ sourceFileUrl: preSignedUrl,
63
72
  });
64
73
  }
65
74
  }
@@ -104,16 +113,23 @@ export async function queryKnowledgeBaseStructured(knowledgeBaseId, query, kbAge
104
113
  const response = await kbAgentClient.send(command);
105
114
  const results = response.retrievalResults || [];
106
115
  const documents = [];
116
+ // Create S3 client for pre-signed URLs (reuse region from Bedrock client)
117
+ const s3Client = new S3Client({ region: clientRegion });
107
118
  for (const result of results) {
108
119
  if (result.content?.type === "IMAGE") {
109
120
  logger.warn("Images are not supported at this time. Skipping...");
110
121
  continue;
111
122
  }
112
123
  else if (result.content?.text) {
124
+ // Generate pre-signed URL if S3 location is available
125
+ const preSignedUrl = result.location?.type === "S3" && result.location.s3Location?.uri
126
+ ? await generatePreSignedUrl(result.location.s3Location.uri, s3Client, logger)
127
+ : undefined;
113
128
  documents.push({
114
129
  content: result.content.text,
115
130
  location: resolveToWebsiteUrl(result.location),
116
131
  score: result.score || -1.0,
132
+ sourceFileUrl: preSignedUrl,
117
133
  });
118
134
  }
119
135
  }
@@ -174,6 +190,28 @@ export function resolveToWebsiteUrl(location) {
174
190
  // If unable to determine the URL, return undefined
175
191
  return undefined;
176
192
  }
193
+ /**
194
+ * Generates a pre-signed URL for an S3 object.
195
+ * @param s3Uri The S3 URI in format s3://bucket/key
196
+ * @param s3Client The S3 client to use
197
+ * @param logger Logger instance
198
+ * @returns Pre-signed URL or undefined if generation fails
199
+ */
200
+ async function generatePreSignedUrl(s3Uri, s3Client, logger) {
201
+ const match = s3Uri.match(/^s3:\/\/([^/]+)\/(.+)$/);
202
+ if (!match) {
203
+ return undefined;
204
+ }
205
+ const [, bucket, key] = match;
206
+ try {
207
+ const command = new GetObjectCommand({ Bucket: bucket, Key: key });
208
+ return await getSignedUrl(s3Client, command, { expiresIn: 3600 });
209
+ }
210
+ catch (error) {
211
+ logger.warn(`Failed to generate pre-signed URL for ${s3Uri}: ${error}`);
212
+ return undefined;
213
+ }
214
+ }
177
215
  /**
178
216
  * Serializes an array of knowledge base query results into a formatted string.
179
217
  * This method formats the results for better readability, including content, location, and score.
@@ -211,7 +249,10 @@ function serializeResults(results) {
211
249
  else if (result.location) {
212
250
  locationStr = JSON.stringify(result.location);
213
251
  }
214
- return `Result ${index + 1} (Score: ${result.score.toFixed(4)}):\n${result.content}\nLocation: ${locationStr}\n`;
252
+ const sourceFileStr = result.sourceFileUrl
253
+ ? `\nSource File: ${result.sourceFileUrl}`
254
+ : "";
255
+ return `Result ${index + 1} (Score: ${result.score.toFixed(4)}):\n${result.content}\nLocation: ${locationStr}${sourceFileStr}\n`;
215
256
  })
216
257
  .join("\n\n");
217
258
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagopa/dx-mcpserver",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "description": "An MCP server that supports developers using DX tools.",
6
6
  "repository": {
@@ -20,13 +20,15 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@aws-sdk/client-bedrock-agent-runtime": "^3.583.0",
23
+ "@aws-sdk/client-s3": "^3.583.0",
24
+ "@aws-sdk/s3-request-presigner": "^3.583.0",
23
25
  "@logtape/logtape": "^1.3.4",
24
- "@modelcontextprotocol/sdk": "^1.25.2",
26
+ "@modelcontextprotocol/sdk": "^1.26.0",
25
27
  "@octokit/rest": "^22.0.0",
26
28
  "axios": "^1.12.2",
27
29
  "zod": "^3.25.76",
28
- "@pagopa/dx-mcpprompts": "^0.2.2",
29
- "@pagopa/azure-tracing": "^0.4.11"
30
+ "@pagopa/azure-tracing": "^0.4.11",
31
+ "@pagopa/dx-mcpprompts": "^0.2.2"
30
32
  },
31
33
  "devDependencies": {
32
34
  "@types/node": "^22.19.1",