@emseepea/create-tool-server 0.0.3 → 0.0.5

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
@@ -2,8 +2,17 @@
2
2
 
3
3
  This directory is both the maintained example and its public npm initializer.
4
4
 
5
+ ## Use This Template
6
+
7
+ Use this template for the smallest server with one public, read-only tool and
8
+ no external service, sign-in, web page, progress stream, or shared storage.
9
+ Choose the [API-backed server](../api-backed-server/README.md) when the tool
10
+ must call a public web service. [Compare all eight templates](https://emseepea.github.io/emseepea/examples/).
11
+
12
+ ## Create a Project
13
+
5
14
  ```sh
6
- npm init @emseepea/tool-server@next -- my-server
15
+ npm init @emseepea/tool-server -- my-server
7
16
  ```
8
17
 
9
18
  <!-- generated-project-readme -->
@@ -13,8 +22,8 @@ npm init @emseepea/tool-server@next -- my-server
13
22
  Choose this example when you want the smallest working server with one public,
14
23
  read-only tool and no web page.
15
24
 
16
- The `get-bean-details` tool returns useful details about one sample coffee. Em
17
- See Pea checks the question and result before returning them through the public
25
+ The `get-pea-variety` tool returns useful details about one sample pea variety. Em
26
+ See Pea checks the input and result before returning them through the public
18
27
  `@emseepea/server` API.
19
28
 
20
29
  ## What This Example Includes
@@ -52,7 +61,7 @@ Run its build and MCP checks:
52
61
  npm test
53
62
  ```
54
63
 
55
- Check that Claude chooses the details tool and understands its result:
64
+ Check that Claude chooses the variety tool and understands its result:
56
65
 
57
66
  ```sh
58
67
  npm run test:llm
@@ -3,8 +3,8 @@
3
3
  Choose this example when you want the smallest working server with one public,
4
4
  read-only tool and no web page.
5
5
 
6
- The `get-bean-details` tool returns useful details about one sample coffee. Em
7
- See Pea checks the question and result before returning them through the public
6
+ The `get-pea-variety` tool returns useful details about one sample pea variety. Em
7
+ See Pea checks the input and result before returning them through the public
8
8
  `@emseepea/server` API.
9
9
 
10
10
  ## What This Example Includes
@@ -42,7 +42,7 @@ Run its build and MCP checks:
42
42
  npm test
43
43
  ```
44
44
 
45
- Check that Claude chooses the details tool and understands its result:
45
+ Check that Claude chooses the variety tool and understands its result:
46
46
 
47
47
  ```sh
48
48
  npm run test:llm
@@ -1,21 +1,20 @@
1
1
  import { toolSelectionTest } from "@emseepea/testing/semantic";
2
2
 
3
- toolSelectionTest("Basic bean details keep each concept distinct", {
3
+ toolSelectionTest("Pea variety details keep each concept distinct", {
4
4
  server: new URL("../dist/server.js", import.meta.url),
5
5
  question:
6
- "For Highland Bloom, give me its origin, variety, processing method, roast, and " +
7
- "tasting notes. Keep those concepts distinct.",
6
+ "For Highland Snap, give me its pea type, growth habit, days to maturity, and " +
7
+ "traits. Keep those concepts distinct.",
8
8
  criticalFacts: [
9
- "Sample Highlands",
10
- "Bourbon",
11
- "natural",
12
- "medium",
13
- "berry",
14
- "cocoa"
9
+ "snap",
10
+ "climbing",
11
+ "70",
12
+ "edible pods",
13
+ "needs support"
15
14
  ],
16
15
  criteria:
17
- "The answer says Highland Bloom is a medium-roast, naturally processed Bourbon " +
18
- "from Sample Highlands with berry and cocoa tasting notes. It does not confuse " +
19
- "origin, variety, process, roast, or tasting notes.",
20
- expectedTools: ["get-bean-details"],
16
+ "The answer says Highland Snap is a snap pea with a climbing growth habit, " +
17
+ "matures in 70 days, has edible pods, and needs support. It does not confuse " +
18
+ "pea type, growth habit, maturity time, or traits.",
19
+ expectedTools: ["get-pea-variety"],
21
20
  });
@@ -14,7 +14,7 @@
14
14
  "lint": "oxlint src test eval"
15
15
  },
16
16
  "devDependencies": {
17
- "@emseepea/testing": "0.2.1",
17
+ "@emseepea/testing": "0.2.2",
18
18
  "@types/node": "24.13.3",
19
19
  "typescript": "6.0.3",
20
20
  "oxlint": "1.80.0"
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "private": true,
26
26
  "dependencies": {
27
- "@emseepea/server": "0.2.1",
27
+ "@emseepea/server": "0.3.0",
28
28
  "zod": "4.4.3"
29
29
  }
30
30
  }
@@ -0,0 +1,44 @@
1
+ import { defineTool, type CapabilityModuleFactory } from "@emseepea/server";
2
+ import { z } from "zod";
3
+
4
+ const varietyNames = ["Harbour Gem", "Highland Snap"] as const;
5
+ const peaVarietySchema = z.object({
6
+ name: z.enum(varietyNames),
7
+ peaType: z.enum(["shelling", "snap"]),
8
+ growthHabit: z.enum(["bush", "climbing"]),
9
+ daysToMaturity: z.number().int().positive(),
10
+ traits: z.array(z.string()),
11
+ });
12
+ const varieties: Record<(typeof varietyNames)[number], z.input<typeof peaVarietySchema>> = {
13
+ "Harbour Gem": {
14
+ name: "Harbour Gem",
15
+ peaType: "shelling",
16
+ growthHabit: "bush",
17
+ daysToMaturity: 62,
18
+ traits: ["compact", "sweet peas"],
19
+ },
20
+ "Highland Snap": {
21
+ name: "Highland Snap",
22
+ peaType: "snap",
23
+ growthHabit: "climbing",
24
+ daysToMaturity: 70,
25
+ traits: ["edible pods", "needs support"],
26
+ },
27
+ };
28
+
29
+ export default (() => defineTool({
30
+ name: "get-pea-variety",
31
+ access: "public",
32
+ title: "Pea Variety Details",
33
+ description: "Get the type, growth habit, maturity time, and traits of a sample pea variety.",
34
+ inputSchema: z.object({ name: z.enum(varietyNames) }),
35
+ outputSchema: peaVarietySchema,
36
+ handler: ({ name }) => {
37
+ const data = varieties[name];
38
+ return {
39
+ text: `${data.name} is a ${data.peaType} pea with a ${data.growthHabit} habit. ` +
40
+ `It matures in ${data.daysToMaturity} days and is known for ${data.traits.join(" and ")}.`,
41
+ data,
42
+ };
43
+ },
44
+ })) satisfies CapabilityModuleFactory;
@@ -1,9 +1,9 @@
1
1
  import { createEmseepea, discoverCapabilities, serveEmseepea } from "@emseepea/server";
2
2
 
3
3
  const handler = createEmseepea({
4
- name: "emseepea-basic-no-ui",
4
+ name: "emseepea-tool-server",
5
5
  version: "0.0.0",
6
- instructions: "Use get-bean-details for information about a sample coffee bean.",
6
+ instructions: "Use get-pea-variety for information about a sample pea variety.",
7
7
  ...await discoverCapabilities(new URL("./capabilities/", import.meta.url)),
8
8
  });
9
9
 
@@ -3,24 +3,23 @@ import test from "node:test";
3
3
 
4
4
  import { startMcpServer } from "@emseepea/testing";
5
5
 
6
- test("advertises and returns understandable bean details", async (t) => {
6
+ test("advertises and returns understandable pea variety details", async (t) => {
7
7
  const running = await startMcpServer(t, new URL("../dist/server.js", import.meta.url));
8
8
  const client = await running.connect();
9
9
 
10
10
  const listed = await client.listTools();
11
- assert.deepEqual(listed.tools.map(({ name }) => name), ["get-bean-details"]);
11
+ assert.deepEqual(listed.tools.map(({ name }) => name), ["get-pea-variety"]);
12
12
 
13
13
  const result = await client.callTool({
14
- name: "get-bean-details",
15
- arguments: { name: "Highland Bloom" },
14
+ name: "get-pea-variety",
15
+ arguments: { name: "Highland Snap" },
16
16
  });
17
17
  assert.equal(result.isError, false);
18
18
  assert.deepEqual(result.structuredContent, {
19
- name: "Highland Bloom",
20
- origin: "Sample Highlands",
21
- variety: "Bourbon",
22
- process: "natural",
23
- roast: "medium",
24
- tastingNotes: ["berry", "cocoa"],
19
+ name: "Highland Snap",
20
+ peaType: "snap",
21
+ growthHabit: "climbing",
22
+ daysToMaturity: 70,
23
+ traits: ["edible pods", "needs support"],
25
24
  });
26
25
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emseepea/create-tool-server",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Create an Em See Pea server with one public tool.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,9 +18,9 @@
18
18
  "prepack": "npm run build:initializer"
19
19
  },
20
20
  "devDependencies": {
21
- "@emseepea/server": "0.2.1",
21
+ "@emseepea/server": "0.3.0",
22
22
  "zod": "4.4.3",
23
- "@emseepea/testing": "0.2.1",
23
+ "@emseepea/testing": "0.2.2",
24
24
  "@types/node": "24.13.3",
25
25
  "typescript": "6.0.3",
26
26
  "oxlint": "1.80.0"
@@ -28,10 +28,10 @@
28
28
  "engines": {
29
29
  "node": ">=22"
30
30
  },
31
- "repository": { "type": "git", "url": "git+https://github.com/emseepea/emseepea.git", "directory": "examples/basic-no-ui" },
31
+ "repository": { "type": "git", "url": "git+https://github.com/emseepea/emseepea.git", "directory": "examples/tool-server" },
32
32
  "homepage": "https://emseepea.github.io/emseepea/examples/",
33
33
  "bugs": "https://github.com/emseepea/emseepea/issues",
34
- "publishConfig": { "access": "public", "provenance": true, "tag": "next" },
34
+ "publishConfig": { "access": "public", "provenance": true },
35
35
  "bin": { "create-tool-server": "./initializer-dist/create.mjs" },
36
36
  "files": ["initializer-dist"]
37
37
  }
@@ -1,47 +0,0 @@
1
- import { defineTool, type CapabilityModuleFactory } from "@emseepea/server";
2
- import { z } from "zod";
3
-
4
- const beanNames = ["Harbour Dawn", "Highland Bloom"] as const;
5
- const beanDetailsSchema = z.object({
6
- name: z.enum(beanNames),
7
- origin: z.string(),
8
- variety: z.string(),
9
- process: z.string(),
10
- roast: z.enum(["light", "medium", "dark"]),
11
- tastingNotes: z.array(z.string()),
12
- });
13
- const beans: Record<(typeof beanNames)[number], z.input<typeof beanDetailsSchema>> = {
14
- "Harbour Dawn": {
15
- name: "Harbour Dawn",
16
- origin: "Sample Coast",
17
- variety: "Caturra",
18
- process: "washed",
19
- roast: "light",
20
- tastingNotes: ["citrus", "honey"],
21
- },
22
- "Highland Bloom": {
23
- name: "Highland Bloom",
24
- origin: "Sample Highlands",
25
- variety: "Bourbon",
26
- process: "natural",
27
- roast: "medium",
28
- tastingNotes: ["berry", "cocoa"],
29
- },
30
- };
31
-
32
- export default (() => defineTool({
33
- name: "get-bean-details",
34
- access: "public",
35
- title: "Coffee Bean Details",
36
- description: "Get origin, processing, roast, and tasting details for a sample coffee bean.",
37
- inputSchema: z.object({ name: z.enum(beanNames) }),
38
- outputSchema: beanDetailsSchema,
39
- handler: ({ name }) => {
40
- const data = beans[name];
41
- return {
42
- text: `${data.name} is a ${data.roast} ${data.process} ${data.variety} from ` +
43
- `${data.origin}, with notes of ${data.tastingNotes.join(" and ")}.`,
44
- data,
45
- };
46
- },
47
- })) satisfies CapabilityModuleFactory;