@pagopa/dx-mcpserver 0.1.2 → 0.1.4
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/handlers/search.js +2 -1
- package/dist/services/bedrock.js +42 -1
- package/package.json +12 -10
package/dist/handlers/search.js
CHANGED
|
@@ -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,
|
package/dist/services/bedrock.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "An MCP server that supports developers using DX tools.",
|
|
6
6
|
"repository": {
|
|
@@ -20,21 +20,23 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@aws-sdk/client-bedrock-agent-runtime": "^3.583.0",
|
|
23
|
-
"@
|
|
23
|
+
"@aws-sdk/client-s3": "^3.583.0",
|
|
24
|
+
"@aws-sdk/s3-request-presigner": "^3.583.0",
|
|
25
|
+
"@logtape/logtape": "^1.3.7",
|
|
24
26
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
25
|
-
"@octokit/rest": "^22.0.
|
|
26
|
-
"axios": "^1.
|
|
27
|
+
"@octokit/rest": "^22.0.1",
|
|
28
|
+
"axios": "^1.13.6",
|
|
27
29
|
"zod": "^3.25.76",
|
|
28
|
-
"@pagopa/azure-tracing": "^0.4.
|
|
29
|
-
"@pagopa/dx-mcpprompts": "^0.2.
|
|
30
|
+
"@pagopa/azure-tracing": "^0.4.13",
|
|
31
|
+
"@pagopa/dx-mcpprompts": "^0.2.4"
|
|
30
32
|
},
|
|
31
33
|
"devDependencies": {
|
|
32
|
-
"@types/node": "^22.19.
|
|
34
|
+
"@types/node": "^22.19.15",
|
|
33
35
|
"@vitest/coverage-v8": "^3.2.4",
|
|
34
36
|
"eslint": "^9.39.2",
|
|
35
|
-
"prettier": "3.
|
|
36
|
-
"tsx": "^4.
|
|
37
|
-
"typescript": "~5.
|
|
37
|
+
"prettier": "3.8.1",
|
|
38
|
+
"tsx": "^4.21.0",
|
|
39
|
+
"typescript": "~5.9.3",
|
|
38
40
|
"vitest": "^3.2.4",
|
|
39
41
|
"@pagopa/eslint-config": "^5.1.2"
|
|
40
42
|
},
|