@pagopa/dx-mcpserver 0.0.12 → 0.1.2
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 +80 -35
- package/dist/__tests__/__mocks__/handlers.js +48 -0
- package/dist/__tests__/http-endpoints.test.js +246 -0
- package/dist/__tests__/index.test.js +125 -0
- package/dist/__tests__/session.test.js +66 -0
- package/dist/cli.js +12 -0
- package/dist/config/__tests__/aws-config.test.js +15 -0
- package/dist/config/__tests__/constants.test.js +31 -0
- package/dist/config/aws.js +14 -17
- package/dist/config/constants.js +9 -0
- package/dist/config/logging.js +6 -10
- package/dist/config/monitoring.js +13 -5
- package/dist/config.js +67 -0
- package/dist/decorators/{promptUsageMonitoring.js → prompt-usage-monitoring.js} +8 -11
- package/dist/decorators/{toolUsageMonitoring.js → tool-usage-monitoring.js} +16 -16
- package/dist/handlers/ask.js +54 -0
- package/dist/handlers/search.js +60 -0
- package/dist/index.js +17 -59
- package/dist/mcp/server.js +88 -0
- package/dist/server.js +109 -0
- package/dist/services/__tests__/bedrock-retrieve-and-generate.test.js +116 -0
- package/dist/services/__tests__/bedrock.test.js +160 -1
- package/dist/services/bedrock-retrieve-and-generate.js +55 -0
- package/dist/services/bedrock.js +56 -0
- package/dist/session.js +12 -0
- package/dist/tools/__tests__/QueryValidation.test.js +83 -0
- package/dist/tools/__tests__/query-pago-pa-dx-documentation.test.js +47 -0
- package/dist/tools/__tests__/registry.test.js +81 -0
- package/dist/tools/query-pagopa-dx-documentation.js +122 -0
- package/dist/tools/registry.js +20 -0
- package/dist/types.js +1 -0
- package/dist/utils/__tests__/error-handling.test.js +168 -0
- package/dist/utils/error-handling.js +74 -0
- package/dist/utils/errors.js +12 -0
- package/dist/utils/filter-undefined.js +6 -0
- package/dist/utils/http.js +36 -0
- package/dist/utils/normalize-boolean.js +13 -0
- package/package.json +7 -7
- package/dist/auth/__tests__/githubAuth.test.js +0 -65
- package/dist/auth/github.js +0 -38
- package/dist/config/__tests__/awsConfig.test.js +0 -17
- package/dist/tools/QueryPagoPADXDocumentation.js +0 -35
- package/dist/tools/SearchGitHubCode.js +0 -84
- package/dist/tools/__tests__/QueryPagoPADXDocumentation.test.js +0 -22
- /package/dist/services/__tests__/{resolveToWebsiteUrl.test.js → resolve-to-website-url.test.js} +0 -0
package/dist/auth/github.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { getLogger } from "@logtape/logtape";
|
|
2
|
-
import { Octokit } from "@octokit/rest";
|
|
3
|
-
import { z } from "zod/v4";
|
|
4
|
-
const organizationsSchema = z
|
|
5
|
-
.array(z.string().nonempty())
|
|
6
|
-
.nonempty()
|
|
7
|
-
.transform((orgs) => orgs.map((org) => org.trim()))
|
|
8
|
-
.catch(["pagopa"]);
|
|
9
|
-
const REQUIRED_ORGANIZATIONS = organizationsSchema.parse(process.env.REQUIRED_ORGANIZATIONS);
|
|
10
|
-
/**
|
|
11
|
-
* Verifies that a user, identified by a GitHub personal access token, is a member
|
|
12
|
-
* of at least one of the required GitHub organizations.
|
|
13
|
-
* @param token The user's GitHub personal access token.
|
|
14
|
-
* @returns A boolean indicating whether the user is a member of a required organization.
|
|
15
|
-
*/
|
|
16
|
-
export async function verifyGithubUser(token) {
|
|
17
|
-
const logger = getLogger(["mcpserver", "github-auth"]);
|
|
18
|
-
if (!token) {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
const octokit = new Octokit({ auth: token });
|
|
22
|
-
try {
|
|
23
|
-
// Fetches the user's organization memberships using Octokit.
|
|
24
|
-
const { data: organizations } = await octokit.rest.orgs.listForAuthenticatedUser();
|
|
25
|
-
const isMember = organizations.some((org) => REQUIRED_ORGANIZATIONS.includes(org.login));
|
|
26
|
-
if (isMember) {
|
|
27
|
-
logger.debug(`User is a member of one of the required organizations: ${REQUIRED_ORGANIZATIONS.join(", ")}`);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
logger.warn(`User is not a member of any of the required organizations: ${REQUIRED_ORGANIZATIONS.join(", ")}`);
|
|
31
|
-
}
|
|
32
|
-
return isMember;
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
logger.error("Error verifying GitHub organization membership", { error });
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import * as awsConfig from "../aws.js";
|
|
3
|
-
describe("aws config", () => {
|
|
4
|
-
it("should export kbRerankingEnabled as boolean", () => {
|
|
5
|
-
expect(typeof awsConfig.kbRerankingEnabled).toBe("boolean");
|
|
6
|
-
});
|
|
7
|
-
it("should export knowledgeBaseId as string", () => {
|
|
8
|
-
expect(typeof awsConfig.knowledgeBaseId).toBe("string");
|
|
9
|
-
});
|
|
10
|
-
it("should export region as string", () => {
|
|
11
|
-
expect(typeof awsConfig.region).toBe("string");
|
|
12
|
-
});
|
|
13
|
-
it("should export kbRuntimeClient as object", () => {
|
|
14
|
-
expect(typeof awsConfig.kbRuntimeClient).toBe("object");
|
|
15
|
-
expect(awsConfig.kbRuntimeClient).toHaveProperty("send");
|
|
16
|
-
});
|
|
17
|
-
});
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { kbRerankingEnabled, kbRuntimeClient, knowledgeBaseId, } from "../config/aws.js";
|
|
3
|
-
import { queryKnowledgeBase } from "../services/bedrock.js";
|
|
4
|
-
/**
|
|
5
|
-
* A tool that provides access to the complete PagoPA DX documentation.
|
|
6
|
-
* It uses a Bedrock knowledge base to answer queries about DX tools, patterns, and best practices.
|
|
7
|
-
*/
|
|
8
|
-
export const QueryPagoPADXDocumentationTool = {
|
|
9
|
-
annotations: {
|
|
10
|
-
title: "Query PagoPA DX documentation",
|
|
11
|
-
},
|
|
12
|
-
description: `This tool provides access to the complete PagoPA DX documentation covering:
|
|
13
|
-
- Getting started, monorepo setup, dev containers, and GitHub collaboration
|
|
14
|
-
- Git workflows and pull requests
|
|
15
|
-
- DX pipelines setup and management
|
|
16
|
-
- TypeScript development (npm scripts, ESLint, code review)
|
|
17
|
-
- Terraform (folder structure, DX modules, Azure provider, pre-commit hooks, validation, deployment, drift detection)
|
|
18
|
-
- Azure development (naming conventions, policies, IAM, API Management, monitoring, networking, deployments, static websites, Service Bus, data archiving)
|
|
19
|
-
- Container development (Docker images)
|
|
20
|
-
- Contributing to DX (Azure provider, Terraform modules, documentation)
|
|
21
|
-
|
|
22
|
-
All prompts and questions should be written in English.
|
|
23
|
-
For Terraform module details (input/output variables, examples), use the \`searchModules\` tool.
|
|
24
|
-
`,
|
|
25
|
-
execute: async (args) => {
|
|
26
|
-
const result = await queryKnowledgeBase(knowledgeBaseId, args.query, kbRuntimeClient, undefined, kbRerankingEnabled);
|
|
27
|
-
return result;
|
|
28
|
-
},
|
|
29
|
-
name: "QueryPagoPADXTerraformDocumentation",
|
|
30
|
-
parameters: z.object({
|
|
31
|
-
query: z
|
|
32
|
-
.string()
|
|
33
|
-
.describe("A natural language query in English used to search the DX documentation for relevant information."),
|
|
34
|
-
}),
|
|
35
|
-
};
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { getLogger } from "@logtape/logtape";
|
|
2
|
-
import { Octokit } from "@octokit/rest";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
const defaultOrg = process.env.GITHUB_SEARCH_ORG || "pagopa";
|
|
5
|
-
/**
|
|
6
|
-
* A tool that searches for code in a GitHub organization.
|
|
7
|
-
* Useful for finding examples of Terraform module usage or specific code patterns.
|
|
8
|
-
*/
|
|
9
|
-
export const SearchGitHubCodeTool = {
|
|
10
|
-
annotations: {
|
|
11
|
-
title: "Search GitHub organization code",
|
|
12
|
-
},
|
|
13
|
-
description: `Search for code in a GitHub organization (defaults to pagopa).
|
|
14
|
-
Use this to find examples of specific code patterns, such as Terraform module usage.
|
|
15
|
-
For example, search for "pagopa-dx/azure-function-app/azurerm" to find examples of the azure-function-app module usage.
|
|
16
|
-
Returns file contents matching the search query.`,
|
|
17
|
-
execute: async (args, context) => {
|
|
18
|
-
const logger = getLogger(["mcpserver", "github-search"]);
|
|
19
|
-
const org = defaultOrg;
|
|
20
|
-
const token = context.session?.token;
|
|
21
|
-
if (!token) {
|
|
22
|
-
throw new Error("GitHub token not available in session");
|
|
23
|
-
}
|
|
24
|
-
const octokit = new Octokit({ auth: token });
|
|
25
|
-
try {
|
|
26
|
-
const extensionFilter = args.extension
|
|
27
|
-
? ` extension:${args.extension}`
|
|
28
|
-
: "";
|
|
29
|
-
const searchQuery = `${args.query} org:${org}${extensionFilter}`;
|
|
30
|
-
logger.info(`Searching GitHub: ${searchQuery}`);
|
|
31
|
-
const { data } = await octokit.rest.search.code({
|
|
32
|
-
per_page: 10,
|
|
33
|
-
q: searchQuery,
|
|
34
|
-
});
|
|
35
|
-
if (data.items.length === 0) {
|
|
36
|
-
return JSON.stringify({ message: "No results found", results: [] });
|
|
37
|
-
}
|
|
38
|
-
const results = await Promise.all(data.items.map(async (item) => {
|
|
39
|
-
try {
|
|
40
|
-
const { data: fileContent } = await octokit.rest.repos.getContent({
|
|
41
|
-
owner: org,
|
|
42
|
-
path: item.path,
|
|
43
|
-
repo: item.repository.name,
|
|
44
|
-
});
|
|
45
|
-
if ("content" in fileContent) {
|
|
46
|
-
return {
|
|
47
|
-
content: Buffer.from(fileContent.content, "base64").toString("utf-8"),
|
|
48
|
-
path: item.path,
|
|
49
|
-
repository: item.repository.full_name,
|
|
50
|
-
url: item.html_url,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
logger.error(`Error fetching file ${item.path}`, { error });
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
}));
|
|
60
|
-
const validResults = results.filter((r) => r !== null);
|
|
61
|
-
return JSON.stringify({
|
|
62
|
-
organization: org,
|
|
63
|
-
query: args.query,
|
|
64
|
-
results: validResults,
|
|
65
|
-
returned_results: validResults.length,
|
|
66
|
-
total_results: data.total_count,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
logger.error("Error searching GitHub code", { error });
|
|
71
|
-
throw error;
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
name: "SearchGitHubCode",
|
|
75
|
-
parameters: z.object({
|
|
76
|
-
extension: z
|
|
77
|
-
.string()
|
|
78
|
-
.optional()
|
|
79
|
-
.describe('File extension to filter results (e.g., "tf" for Terraform files, "py" for Python files). For example, you can use "tf" to find Terraform module usage examples.'),
|
|
80
|
-
query: z
|
|
81
|
-
.string()
|
|
82
|
-
.describe('Code search query (e.g., "pagopa-dx/azure-function-app/azurerm" to find Terraform module usage examples)'),
|
|
83
|
-
}),
|
|
84
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from "vitest";
|
|
2
|
-
vi.mock("../../services/bedrock", () => ({
|
|
3
|
-
queryKnowledgeBase: vi.fn().mockResolvedValue("mocked result"),
|
|
4
|
-
}));
|
|
5
|
-
vi.mock("../../config/aws", () => ({
|
|
6
|
-
kbRerankingEnabled: false,
|
|
7
|
-
kbRuntimeClient: "mockClient",
|
|
8
|
-
knowledgeBaseId: "mockKbId",
|
|
9
|
-
}));
|
|
10
|
-
import { QueryPagoPADXDocumentationTool } from "../QueryPagoPADXDocumentation.js";
|
|
11
|
-
describe("QueryPagoPADXDocumentationTool", () => {
|
|
12
|
-
it("should return results from the knowledge base", async () => {
|
|
13
|
-
const args = { number_of_results: 3, query: "test query" };
|
|
14
|
-
const result = await QueryPagoPADXDocumentationTool.execute(args);
|
|
15
|
-
expect(result).toBe("mocked result");
|
|
16
|
-
});
|
|
17
|
-
it("should use default number_of_results if not provided", async () => {
|
|
18
|
-
const args = { query: "test query" };
|
|
19
|
-
const result = await QueryPagoPADXDocumentationTool.execute(args);
|
|
20
|
-
expect(result).toBe("mocked result");
|
|
21
|
-
});
|
|
22
|
-
});
|
/package/dist/services/__tests__/{resolveToWebsiteUrl.test.js → resolve-to-website-url.test.js}
RENAMED
|
File without changes
|