@esaio/esa-mcp-server 0.2.1 → 0.2.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.
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/bin/index.js +1 -1
- package/package.json +20 -2
- package/.dockerignore +0 -36
- package/.github/dependabot.yml +0 -23
- package/.github/workflows/docker-publish.yml +0 -120
- package/.github/workflows/main.yml +0 -41
- package/CLAUDE.md +0 -94
- package/Dockerfile +0 -34
- package/biome.json +0 -57
- package/src/__tests__/fixtures/mock-comment.ts +0 -90
- package/src/__tests__/fixtures/mock-post.ts +0 -79
- package/src/__tests__/index.test.ts +0 -216
- package/src/api_client/__tests__/index.test.ts +0 -149
- package/src/api_client/__tests__/middleware.test.ts +0 -120
- package/src/api_client/__tests__/with-context.test.ts +0 -98
- package/src/api_client/index.ts +0 -29
- package/src/api_client/middleware.ts +0 -21
- package/src/api_client/with-context.ts +0 -26
- package/src/config/__tests__/index.test.ts +0 -65
- package/src/config/index.ts +0 -20
- package/src/context/mcp-context.ts +0 -1
- package/src/context/stdio-context.ts +0 -6
- package/src/errors/missing-team-name-error.ts +0 -8
- package/src/formatters/__tests__/mcp-response.test.ts +0 -106
- package/src/formatters/mcp-response.ts +0 -95
- package/src/generated/api-types.ts +0 -2968
- package/src/i18n/__tests__/index.test.ts +0 -53
- package/src/i18n/index.ts +0 -39
- package/src/index.ts +0 -47
- package/src/locales/en.json +0 -13
- package/src/locales/ja.json +0 -13
- package/src/prompts/__tests__/index.test.ts +0 -48
- package/src/prompts/__tests__/summarize-post.test.ts +0 -291
- package/src/prompts/index.ts +0 -21
- package/src/prompts/summarize-post.ts +0 -94
- package/src/resources/__tests__/index.test.ts +0 -50
- package/src/resources/__tests__/recent-posts-list.test.ts +0 -92
- package/src/resources/__tests__/recent-posts.test.ts +0 -270
- package/src/resources/index.ts +0 -33
- package/src/resources/recent-posts-list.ts +0 -22
- package/src/resources/recent-posts.ts +0 -45
- package/src/schemas/team-name-schema.ts +0 -19
- package/src/tools/__tests__/attachments.test.ts +0 -460
- package/src/tools/__tests__/categories.test.ts +0 -402
- package/src/tools/__tests__/comments.test.ts +0 -970
- package/src/tools/__tests__/helps.test.ts +0 -222
- package/src/tools/__tests__/index.test.ts +0 -48
- package/src/tools/__tests__/post-actions.test.ts +0 -445
- package/src/tools/__tests__/posts.test.ts +0 -917
- package/src/tools/__tests__/search.test.ts +0 -339
- package/src/tools/__tests__/teams.test.ts +0 -615
- package/src/tools/attachments.ts +0 -167
- package/src/tools/categories.ts +0 -153
- package/src/tools/comments.ts +0 -258
- package/src/tools/helps.ts +0 -50
- package/src/tools/index.ts +0 -351
- package/src/tools/post-actions.ts +0 -132
- package/src/tools/posts.ts +0 -179
- package/src/tools/search.ts +0 -98
- package/src/tools/teams.ts +0 -157
- package/src/transformers/__tests__/category-transformer.test.ts +0 -161
- package/src/transformers/__tests__/comment-transformer.test.ts +0 -129
- package/src/transformers/__tests__/post-name-normalizer.test.ts +0 -53
- package/src/transformers/__tests__/post-transformer.test.ts +0 -70
- package/src/transformers/__tests__/query-normalizer.test.ts +0 -98
- package/src/transformers/__tests__/team-name-normalizer.test.ts +0 -21
- package/src/transformers/category-transformer.ts +0 -36
- package/src/transformers/comment-transformer.ts +0 -34
- package/src/transformers/post-name-normalizer.ts +0 -30
- package/src/transformers/post-transformer.ts +0 -38
- package/src/transformers/query-normalizer.ts +0 -36
- package/src/transformers/team-name-normalizer.ts +0 -7
- package/tsconfig.build.json +0 -4
- package/tsconfig.json +0 -30
- package/tsdown.config.ts +0 -13
- package/vitest.config.ts +0 -24
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import packageJson from "../../../package.json" with { type: "json" };
|
|
3
|
-
|
|
4
|
-
describe("config", () => {
|
|
5
|
-
beforeEach(() => {
|
|
6
|
-
vi.resetModules();
|
|
7
|
-
vi.stubEnv("ESA_ACCESS_TOKEN", undefined);
|
|
8
|
-
vi.stubEnv("ESA_API_BASE_URL", undefined);
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
afterEach(() => {
|
|
12
|
-
vi.unstubAllEnvs();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
describe("config object", () => {
|
|
16
|
-
it("should have correct default values", async () => {
|
|
17
|
-
const { config } = await import("../index.js");
|
|
18
|
-
|
|
19
|
-
expect(config.esa.apiBaseUrl).toBe("https://api.esa.io");
|
|
20
|
-
expect(config.server.name).toBe("esa-mcp-server");
|
|
21
|
-
expect(config.server.version).toBe(packageJson.version);
|
|
22
|
-
expect(config.server.description).toBe("Official MCP server for esa.io");
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("should use environment variables when set", async () => {
|
|
26
|
-
vi.stubEnv("ESA_ACCESS_TOKEN", "test-token");
|
|
27
|
-
vi.stubEnv("ESA_API_BASE_URL", "https://api.esa.localhost");
|
|
28
|
-
|
|
29
|
-
const { config } = await import("../index.js");
|
|
30
|
-
|
|
31
|
-
expect(config.esa.apiAccessToken).toBe("test-token");
|
|
32
|
-
expect(config.esa.apiBaseUrl).toBe("https://api.esa.localhost");
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
describe("validateConfig", () => {
|
|
37
|
-
it("should throw error when ESA_ACCESS_TOKEN is not set", async () => {
|
|
38
|
-
vi.stubEnv("ESA_ACCESS_TOKEN", undefined);
|
|
39
|
-
|
|
40
|
-
const { validateConfig } = await import("../index.js");
|
|
41
|
-
|
|
42
|
-
expect(() => validateConfig()).toThrow(
|
|
43
|
-
"ESA_ACCESS_TOKEN environment variable is required",
|
|
44
|
-
);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("should not throw error when ESA_ACCESS_TOKEN is set", async () => {
|
|
48
|
-
vi.stubEnv("ESA_ACCESS_TOKEN", "valid-token");
|
|
49
|
-
|
|
50
|
-
const { validateConfig } = await import("../index.js");
|
|
51
|
-
|
|
52
|
-
expect(() => validateConfig()).not.toThrow();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should throw error when ESA_ACCESS_TOKEN is empty string", async () => {
|
|
56
|
-
vi.stubEnv("ESA_ACCESS_TOKEN", "");
|
|
57
|
-
|
|
58
|
-
const { validateConfig } = await import("../index.js");
|
|
59
|
-
|
|
60
|
-
expect(() => validateConfig()).toThrow(
|
|
61
|
-
"ESA_ACCESS_TOKEN environment variable is required",
|
|
62
|
-
);
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
});
|
package/src/config/index.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import packageJson from "../../package.json" with { type: "json" };
|
|
2
|
-
import type { StdioContext } from "../context/stdio-context.js";
|
|
3
|
-
|
|
4
|
-
export const config = {
|
|
5
|
-
esa: {
|
|
6
|
-
apiAccessToken: process.env.ESA_ACCESS_TOKEN || "",
|
|
7
|
-
apiBaseUrl: process.env.ESA_API_BASE_URL || "https://api.esa.io",
|
|
8
|
-
} satisfies StdioContext,
|
|
9
|
-
server: {
|
|
10
|
-
name: "esa-mcp-server",
|
|
11
|
-
version: packageJson.version,
|
|
12
|
-
description: "Official MCP server for esa.io",
|
|
13
|
-
},
|
|
14
|
-
} as const;
|
|
15
|
-
|
|
16
|
-
export function validateConfig(): void {
|
|
17
|
-
if (!config.esa.apiAccessToken) {
|
|
18
|
-
throw new Error("ESA_ACCESS_TOKEN environment variable is required");
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type MCPContext = Record<string, unknown>;
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
formatPromptError,
|
|
4
|
-
formatPromptResponse,
|
|
5
|
-
formatResourceError,
|
|
6
|
-
formatResourceResponse,
|
|
7
|
-
formatToolError,
|
|
8
|
-
formatToolResponse,
|
|
9
|
-
} from "../mcp-response.js";
|
|
10
|
-
|
|
11
|
-
describe("response formatters", () => {
|
|
12
|
-
describe("formatToolResponse", () => {
|
|
13
|
-
it("should format data as JSON text content", () => {
|
|
14
|
-
const data = { key: "value", count: 42 };
|
|
15
|
-
const result = formatToolResponse(data);
|
|
16
|
-
|
|
17
|
-
expect(result.content[0].type).toBe("text");
|
|
18
|
-
expect(result.content[0].text).toBe(JSON.stringify(data, null, 2));
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
describe("formatResourceResponse", () => {
|
|
23
|
-
it("should format data as JSON resource with URI and mimeType", () => {
|
|
24
|
-
const data = { resource: "data" };
|
|
25
|
-
const uri = "esa://resource/123";
|
|
26
|
-
const result = formatResourceResponse(data, uri);
|
|
27
|
-
|
|
28
|
-
expect(result.contents[0]).toEqual({
|
|
29
|
-
uri,
|
|
30
|
-
mimeType: "application/json",
|
|
31
|
-
text: JSON.stringify(data, null, 2),
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
describe("formatPromptResponse", () => {
|
|
37
|
-
it("should format message as user role content", () => {
|
|
38
|
-
const message = "This is a prompt message";
|
|
39
|
-
const result = formatPromptResponse(message);
|
|
40
|
-
|
|
41
|
-
expect(result.messages[0]).toEqual({
|
|
42
|
-
role: "user",
|
|
43
|
-
content: {
|
|
44
|
-
type: "text",
|
|
45
|
-
text: message,
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe("error formatters", () => {
|
|
53
|
-
it("should format Error instances consistently", () => {
|
|
54
|
-
const error = new Error("test error");
|
|
55
|
-
|
|
56
|
-
expect(formatToolError(error).content[0].text).toBe("Error: test error");
|
|
57
|
-
expect(formatResourceError(error, "uri").contents[0].text).toBe(
|
|
58
|
-
"Error: test error",
|
|
59
|
-
);
|
|
60
|
-
expect(formatPromptError(error).messages[0].content.text).toBe(
|
|
61
|
-
"Error: test error",
|
|
62
|
-
);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it("should format status codes as API responses", () => {
|
|
66
|
-
const status = 404;
|
|
67
|
-
|
|
68
|
-
expect(formatToolError(status).content[0].text).toBe(
|
|
69
|
-
"Error: API Response(status: 404)",
|
|
70
|
-
);
|
|
71
|
-
expect(formatResourceError(status, "uri").contents[0].text).toBe(
|
|
72
|
-
"Error: API Response(status: 404)",
|
|
73
|
-
);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("should format object errors as JSON strings", () => {
|
|
77
|
-
const error = { code: "NOT_FOUND", message: "Resource not found" };
|
|
78
|
-
const expectedText = `Error: ${JSON.stringify(error, null, 2)}`;
|
|
79
|
-
|
|
80
|
-
expect(formatToolError(error).content[0].text).toBe(expectedText);
|
|
81
|
-
expect(formatResourceError(error, "uri").contents[0].text).toBe(
|
|
82
|
-
expectedText,
|
|
83
|
-
);
|
|
84
|
-
expect(formatPromptError(error).messages[0].content.text).toBe(
|
|
85
|
-
expectedText,
|
|
86
|
-
);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("should maintain correct structure for each error formatter", () => {
|
|
90
|
-
const error = new Error("test");
|
|
91
|
-
const uri = "test://uri";
|
|
92
|
-
|
|
93
|
-
const toolResult = formatToolError(error);
|
|
94
|
-
expect(toolResult).toHaveProperty("content");
|
|
95
|
-
expect(Array.isArray(toolResult.content)).toBe(true);
|
|
96
|
-
|
|
97
|
-
const resourceResult = formatResourceError(error, uri);
|
|
98
|
-
expect(resourceResult).toHaveProperty("contents");
|
|
99
|
-
expect(resourceResult.contents[0].uri).toBe(uri);
|
|
100
|
-
expect(resourceResult.contents[0].mimeType).toBe("application/json");
|
|
101
|
-
|
|
102
|
-
const promptResult = formatPromptError(error);
|
|
103
|
-
expect(promptResult).toHaveProperty("messages");
|
|
104
|
-
expect(promptResult.messages[0].role).toBe("user");
|
|
105
|
-
});
|
|
106
|
-
});
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
CallToolResult,
|
|
3
|
-
GetPromptResult,
|
|
4
|
-
ReadResourceResult,
|
|
5
|
-
} from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
-
|
|
7
|
-
function formatErrorText(error: unknown): string {
|
|
8
|
-
return error instanceof Error
|
|
9
|
-
? `Error: ${error.message}`
|
|
10
|
-
: typeof error === "number" && error !== null
|
|
11
|
-
? `Error: API Response(status: ${error})`
|
|
12
|
-
: typeof error === "object" && error !== null
|
|
13
|
-
? `Error: ${JSON.stringify(error, null, 2)}`
|
|
14
|
-
: `Error: ${String(error)}`;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function formatToolResponse(data: unknown): CallToolResult {
|
|
18
|
-
return {
|
|
19
|
-
content: [
|
|
20
|
-
{
|
|
21
|
-
type: "text",
|
|
22
|
-
text: JSON.stringify(data, null, 2),
|
|
23
|
-
},
|
|
24
|
-
],
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function formatResourceResponse(
|
|
29
|
-
data: unknown,
|
|
30
|
-
uri: string,
|
|
31
|
-
): ReadResourceResult {
|
|
32
|
-
return {
|
|
33
|
-
contents: [
|
|
34
|
-
{
|
|
35
|
-
uri,
|
|
36
|
-
mimeType: "application/json",
|
|
37
|
-
text: JSON.stringify(data, null, 2),
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function formatPromptResponse(message: string): GetPromptResult {
|
|
44
|
-
return {
|
|
45
|
-
messages: [
|
|
46
|
-
{
|
|
47
|
-
role: "user",
|
|
48
|
-
content: {
|
|
49
|
-
type: "text",
|
|
50
|
-
text: message,
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function formatToolError(error: unknown): CallToolResult {
|
|
58
|
-
return {
|
|
59
|
-
content: [
|
|
60
|
-
{
|
|
61
|
-
type: "text",
|
|
62
|
-
text: formatErrorText(error),
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function formatResourceError(
|
|
69
|
-
error: unknown,
|
|
70
|
-
uri: string,
|
|
71
|
-
): ReadResourceResult {
|
|
72
|
-
return {
|
|
73
|
-
contents: [
|
|
74
|
-
{
|
|
75
|
-
uri,
|
|
76
|
-
mimeType: "application/json",
|
|
77
|
-
text: formatErrorText(error),
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function formatPromptError(error: unknown): GetPromptResult {
|
|
84
|
-
return {
|
|
85
|
-
messages: [
|
|
86
|
-
{
|
|
87
|
-
role: "user",
|
|
88
|
-
content: {
|
|
89
|
-
type: "text",
|
|
90
|
-
text: formatErrorText(error),
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
|
-
};
|
|
95
|
-
}
|