@emseepea/create-tool-server 0.0.16 → 0.0.21
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
CHANGED
|
@@ -74,6 +74,13 @@ npm start
|
|
|
74
74
|
The endpoint is `http://127.0.0.1:3000/mcp` and the health check is
|
|
75
75
|
`http://127.0.0.1:3000/healthz`.
|
|
76
76
|
|
|
77
|
+
## Add Feedback
|
|
78
|
+
|
|
79
|
+
Install `@emseepea/feedback` when this server needs a detailed one-way
|
|
80
|
+
observation or a durable support conversation. Pass its tools through the
|
|
81
|
+
application factory's `additionalTools` option. Choose PostgreSQL, Firestore,
|
|
82
|
+
GitHub Issues, or Zendesk in the [feedback guide](../../packages/feedback/README.md).
|
|
83
|
+
|
|
77
84
|
## Check This Example
|
|
78
85
|
|
|
79
86
|
[Ordinary tests](test/) live in `test/`.
|
|
@@ -55,6 +55,13 @@ npm start
|
|
|
55
55
|
The endpoint is `http://127.0.0.1:3000/mcp` and the health check is
|
|
56
56
|
`http://127.0.0.1:3000/healthz`.
|
|
57
57
|
|
|
58
|
+
## Add Feedback
|
|
59
|
+
|
|
60
|
+
Install `@emseepea/feedback` when this server needs a detailed one-way
|
|
61
|
+
observation or a durable support conversation. Pass its tools through the
|
|
62
|
+
application factory's `additionalTools` option. Choose PostgreSQL, Firestore,
|
|
63
|
+
GitHub Issues, or Zendesk in the [feedback guide](../../packages/feedback/README.md).
|
|
64
|
+
|
|
58
65
|
## Check This Example
|
|
59
66
|
|
|
60
67
|
[Ordinary tests](test/) live in `test/`.
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import {
|
|
3
3
|
assertNoToolCalls,
|
|
4
|
+
assertNoNegativeFeedback,
|
|
4
5
|
assertResponseContains,
|
|
5
6
|
assertResponseMeaning,
|
|
6
|
-
|
|
7
|
+
assertToolCallsWithOptionalFeedback,
|
|
7
8
|
createConversation,
|
|
8
9
|
} from "@emseepea/testing/semantic";
|
|
9
10
|
|
|
10
11
|
const protectedServer = new URL("./protected-server.mjs", import.meta.url);
|
|
12
|
+
const server = new URL(import.meta.resolve("@emseepea/feedback/testing-server"));
|
|
13
|
+
const environment = {
|
|
14
|
+
EMSEEPEA_EVAL_APP_MODULE: new URL("../dist/app.js", import.meta.url).href,
|
|
15
|
+
EMSEEPEA_EVAL_APP_FACTORY: "createToolServer",
|
|
16
|
+
};
|
|
11
17
|
|
|
12
18
|
test("looks up pea varieties and compares a follow-up", async (t) => {
|
|
13
19
|
const chat = await createConversation(t, {
|
|
14
|
-
server
|
|
20
|
+
server,
|
|
21
|
+
environment,
|
|
15
22
|
});
|
|
16
23
|
|
|
17
24
|
// The first turn's flexible prose needs the one model judge. The follow-up's
|
|
@@ -20,7 +27,7 @@ test("looks up pea varieties and compares a follow-up", async (t) => {
|
|
|
20
27
|
"Describe the pea type, growth habit, maturity time, and traits of Highland Snap.",
|
|
21
28
|
);
|
|
22
29
|
|
|
23
|
-
|
|
30
|
+
await assertToolCallsWithOptionalFeedback(highland, [{
|
|
24
31
|
name: "get-pea-variety",
|
|
25
32
|
arguments: { name: "Highland Snap" },
|
|
26
33
|
}]);
|
|
@@ -35,30 +42,32 @@ test("looks up pea varieties and compares a follow-up", async (t) => {
|
|
|
35
42
|
const comparison = await chat.send(
|
|
36
43
|
"Compare that with Harbour Gem. Include its pea type, growth habit, and maturity time.",
|
|
37
44
|
);
|
|
38
|
-
|
|
45
|
+
await assertToolCallsWithOptionalFeedback(comparison, [{
|
|
39
46
|
name: "get-pea-variety",
|
|
40
47
|
arguments: { name: "Harbour Gem" },
|
|
41
48
|
}]);
|
|
42
49
|
assertResponseContains(comparison, "Harbour Gem");
|
|
50
|
+
assertNoNegativeFeedback(highland, comparison);
|
|
43
51
|
});
|
|
44
52
|
|
|
45
53
|
test("protected discovery offers a permitted tool", async (t) => {
|
|
46
54
|
const chat = await createConversation(t, {
|
|
47
55
|
server: protectedServer,
|
|
48
56
|
authToken: "test-token",
|
|
49
|
-
environment: { TEST_PERMISSIONS: "varieties:read" },
|
|
57
|
+
environment: { TEST_PERMISSIONS: "varieties:read,feedback:write" },
|
|
50
58
|
});
|
|
51
59
|
|
|
52
60
|
// This one answer check confirms that protected discovery still supports a
|
|
53
61
|
// useful answer, while keeping the authorization case to one short turn.
|
|
54
62
|
const answer = await chat.send("What type of pea is Highland Snap?");
|
|
55
|
-
|
|
63
|
+
await assertToolCallsWithOptionalFeedback(answer, [{
|
|
56
64
|
name: "get-pea-variety",
|
|
57
65
|
arguments: { name: "Highland Snap" },
|
|
58
66
|
}]);
|
|
59
67
|
await assertResponseMeaning(answer, {
|
|
60
68
|
expected: "The response says that Highland Snap is a snap pea.",
|
|
61
69
|
});
|
|
70
|
+
assertNoNegativeFeedback(answer);
|
|
62
71
|
});
|
|
63
72
|
|
|
64
73
|
test("protected discovery does not offer a hidden tool", async (t) => {
|
|
@@ -78,4 +87,5 @@ test("protected discovery does not offer a hidden tool", async (t) => {
|
|
|
78
87
|
expected:
|
|
79
88
|
"The response explains that it has no available tool for looking up Highland Snap.",
|
|
80
89
|
});
|
|
90
|
+
assertNoNegativeFeedback(answer);
|
|
81
91
|
});
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { serveEmseepea } from "@emseepea/server";
|
|
2
2
|
import { insecureTestAuthentication } from "@emseepea/testing";
|
|
3
|
+
import { defineFeedbackSubmission } from "@emseepea/feedback";
|
|
3
4
|
import { createToolServer } from "../dist/app.js";
|
|
4
5
|
|
|
5
6
|
const permissions = process.env.TEST_PERMISSIONS?.split(",").filter(Boolean) ?? [];
|
|
7
|
+
const feedback = defineFeedbackSubmission({
|
|
8
|
+
access: "protected",
|
|
9
|
+
requiredScopes: ["feedback:write"],
|
|
10
|
+
backend: { submit: () => ({ id: crypto.randomUUID(), recordedAt: new Date().toISOString() }) },
|
|
11
|
+
});
|
|
6
12
|
const app = await createToolServer({
|
|
7
13
|
access: { access: "protected", requiredScopes: ["varieties:read"] },
|
|
8
14
|
authentication: insecureTestAuthentication(permissions),
|
|
15
|
+
additionalTools: [feedback],
|
|
9
16
|
});
|
|
10
17
|
const running = await serveEmseepea(app, {
|
|
11
18
|
port: Number.parseInt(process.env.PORT ?? "3000", 10),
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"lint": "oxlint src test eval"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@emseepea/
|
|
17
|
+
"@emseepea/feedback": "0.2.1",
|
|
18
|
+
"@emseepea/testing": "0.9.4",
|
|
18
19
|
"@types/node": "24.13.3",
|
|
19
20
|
"typescript": "6.0.3",
|
|
20
21
|
"oxlint": "1.80.0"
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
},
|
|
25
26
|
"private": true,
|
|
26
27
|
"dependencies": {
|
|
27
|
-
"@emseepea/server": "0.
|
|
28
|
+
"@emseepea/server": "0.7.0",
|
|
28
29
|
"zod": "4.4.3"
|
|
29
30
|
}
|
|
30
31
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emseepea/create-tool-server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.21",
|
|
4
4
|
"description": "Create an Em See Pea server with one public tool.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -18,9 +18,10 @@
|
|
|
18
18
|
"prepack": "npm run build:initializer"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"@emseepea/
|
|
21
|
+
"@emseepea/feedback": "0.2.1",
|
|
22
|
+
"@emseepea/server": "0.7.0",
|
|
22
23
|
"zod": "4.4.3",
|
|
23
|
-
"@emseepea/testing": "0.
|
|
24
|
+
"@emseepea/testing": "0.9.4",
|
|
24
25
|
"@types/node": "24.13.3",
|
|
25
26
|
"typescript": "6.0.3",
|
|
26
27
|
"oxlint": "1.80.0"
|