@emseepea/create-resources-and-prompts-server 0.0.2 → 0.0.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/README.md CHANGED
@@ -1,22 +1,63 @@
1
1
  # `@emseepea/create-resources-and-prompts-server`
2
2
 
3
- Create a private, standalone Em See Pea project with resources and prompts.
4
- The package builds its starter from the maintained
5
- [resources and prompts example](https://github.com/emseepea/emseepea/tree/main/examples/resources-prompts).
3
+ This directory is both the maintained example and its public npm initializer.
6
4
 
7
- ## Create the Project
5
+ ## Use This Template
8
6
 
9
- This initializer is queued for the next pre-alpha release and is not yet
10
- available from npm.
7
+ Use this template to publish readable resources, parameterized resource
8
+ addresses, reusable prompts, and prompt-field suggestions. Choose the
9
+ [tool server](../tool-server/README.md) when the model needs to call an
10
+ operation instead of reading material or rendering a prompt. [Compare all eight templates](https://emseepea.github.io/emseepea/examples/).
11
+
12
+ ## Create a Project
11
13
 
12
14
  ```sh
13
- npm init @emseepea/resources-and-prompts-server@next -- my-server
15
+ npm init @emseepea/resources-and-prompts-server -- my-server
14
16
  ```
15
17
 
18
+ <!-- generated-project-readme -->
19
+
20
+ ## Resources and Prompts Example
21
+
22
+ Choose this example when you want to give an assistant reusable reference
23
+ content and guided starting questions, without adding another tool.
24
+
25
+ It provides:
26
+
27
+ - a fixed resource at one known address
28
+ - a resource pattern for related content at predictable addresses
29
+ - a reusable prompt with one checked argument
30
+ - optional suggestions for the resource and prompt fields
31
+
32
+ ## Run
33
+
34
+ From this directory:
35
+
16
36
  ```sh
17
- cd my-server
18
37
  npm install
19
- npm test
20
- npm run lint
38
+ npm run build
21
39
  npm start
22
40
  ```
41
+
42
+ The server listens on `http://127.0.0.1:3000/mcp` by default. Set `PORT` to
43
+ choose another port.
44
+
45
+ ## Check This Example
46
+
47
+ [Ordinary tests](test/) live in `test/`.
48
+ The [AI understanding test](eval/meaning.test.mjs) lives separately in `eval/`.
49
+ The commands below run each suite independently.
50
+
51
+ Run its build and MCP resource and prompt checks:
52
+
53
+ ```sh
54
+ npm test
55
+ ```
56
+
57
+ Check that Claude keeps sowing depth and plant spacing distinct:
58
+
59
+ ```sh
60
+ npm run test:llm
61
+ ```
62
+
63
+ If Claude is not already signed in, run `claude auth login` first.
@@ -35,7 +35,7 @@ Run its build and MCP resource and prompt checks:
35
35
  npm test
36
36
  ```
37
37
 
38
- Check that Claude keeps coffee strength and extraction distinct:
38
+ Check that Claude keeps sowing depth and plant spacing distinct:
39
39
 
40
40
  ```sh
41
41
  npm run test:llm
@@ -0,0 +1,25 @@
1
+ import assert from "node:assert/strict";
2
+ import { semanticTest } from "@emseepea/testing/semantic";
3
+
4
+ semanticTest("Sowing depth and plant spacing remain separate concepts", {
5
+ server: new URL("../dist/server.js", import.meta.url),
6
+ question:
7
+ "If I sow pea seeds deeper, should I also space the plants farther apart? " +
8
+ "Explain the distinction for a home gardener.",
9
+ criticalFacts: [
10
+ "sowing depth",
11
+ "plant spacing"
12
+ ],
13
+ criteria:
14
+ "The answer says sowing peas deeper does not mean spacing the plants farther " +
15
+ "apart. It explains that sowing depth is how deep a seed goes while plant " +
16
+ "spacing is the gap between plants, and it does not treat the measurements as " +
17
+ "interchangeable.",
18
+ requiredPaths: ["resources/read:guide://peas/getting-started","prompts/get:growing-guide"],
19
+ async exercise(client) {
20
+ const result1 = await client.readResource({"uri":"guide://peas/getting-started"});
21
+ assert.ok(result1);
22
+ const result2 = await client.getPrompt({"name":"growing-guide","arguments":{"topic":"sowing-depth"}});
23
+ assert.ok(result2);
24
+ },
25
+ });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "emseepea-starter",
3
3
  "version": "0.0.0",
4
- "private": true,
4
+ "description": "Create an Em See Pea server with resources and prompts.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "scripts": {
@@ -13,17 +13,18 @@
13
13
  "test:llm:built": "emseepea-test eval",
14
14
  "lint": "oxlint src test eval"
15
15
  },
16
- "dependencies": {
17
- "@emseepea/server": "0.1.0",
18
- "zod": "4.4.3"
19
- },
20
16
  "devDependencies": {
21
- "@emseepea/testing": "0.2.1",
17
+ "@emseepea/testing": "0.2.2",
22
18
  "@types/node": "24.13.3",
23
19
  "typescript": "6.0.3",
24
20
  "oxlint": "1.80.0"
25
21
  },
26
22
  "engines": {
27
23
  "node": ">=22"
24
+ },
25
+ "private": true,
26
+ "dependencies": {
27
+ "@emseepea/server": "0.2.2",
28
+ "zod": "4.4.3"
28
29
  }
29
30
  }
@@ -1,12 +1,12 @@
1
1
  import { definePrompt, type CapabilityModuleFactory } from "@emseepea/server";
2
2
  import { z } from "zod";
3
3
 
4
- const topics = ["brew-ratio", "grind-size", "water-temperature"];
4
+ const topics = ["sowing-depth", "plant-spacing", "trellis-support"];
5
5
 
6
6
  export default (() => definePrompt({
7
- name: "brew-guide",
8
- title: "Brew guide",
9
- description: "Create a prompt for a sample brewing topic.",
7
+ name: "growing-guide",
8
+ title: "Pea growing guide",
9
+ description: "Create a prompt for a sample pea-growing topic.",
10
10
  argsSchema: z.object({ topic: z.string().min(1) }),
11
11
  complete: {
12
12
  topic: (value) => topics.filter((topic) => topic.startsWith(value)),
@@ -17,7 +17,7 @@ export default (() => definePrompt({
17
17
  role: "user",
18
18
  content: {
19
19
  type: "text",
20
- text: `Explain ${topic} for a home brewer. Distinguish any commonly confused concepts.`,
20
+ text: `Explain ${topic} for a home gardener. Distinguish any commonly confused concepts.`,
21
21
  },
22
22
  }],
23
23
  }),
@@ -1,18 +1,18 @@
1
1
  import { defineResource, type CapabilityModuleFactory } from "@emseepea/server";
2
2
 
3
- const guideUri = "guide://coffee/getting-started";
3
+ const guideUri = "guide://peas/getting-started";
4
4
 
5
5
  export default (() => defineResource({
6
6
  name: "getting-started",
7
7
  uri: guideUri,
8
- title: "Coffee getting started",
8
+ title: "Pea growing: getting started",
9
9
  description: "A sample guide exposed as an MCP resource.",
10
10
  mimeType: "text/markdown",
11
11
  handler: () => ({
12
12
  contents: [{
13
13
  uri: guideUri,
14
14
  mimeType: "text/markdown",
15
- text: "# Brew clearly\n\nStrength is concentration; extraction is how much material left the grounds. They are related, but not interchangeable.\n",
15
+ text: "# Plant peas clearly\n\nSowing depth is how deep a seed goes; plant spacing is the gap between plants. They are separate choices, not interchangeable measurements.\n",
16
16
  }],
17
17
  }),
18
18
  })) satisfies CapabilityModuleFactory;
@@ -1,12 +1,12 @@
1
1
  import { defineResourceTemplate, type CapabilityModuleFactory } from "@emseepea/server";
2
2
 
3
- const methods = ["aeropress", "espresso", "pour-over"];
3
+ const methods = ["container", "raised-bed", "row"];
4
4
 
5
5
  export default (() => defineResourceTemplate({
6
- name: "method-guide",
7
- uriTemplate: "guide://coffee/method/{method}",
8
- title: "Coffee method guide",
9
- description: "A sample guide selected by brewing method.",
6
+ name: "planting-guide",
7
+ uriTemplate: "guide://peas/planting/{method}",
8
+ title: "Pea planting guide",
9
+ description: "A sample guide selected by planting method.",
10
10
  mimeType: "text/markdown",
11
11
  complete: {
12
12
  method: (value) => methods.filter((method) => method.startsWith(value)),
@@ -5,7 +5,7 @@ import {
5
5
  } from "@emseepea/server";
6
6
 
7
7
  const running = await serveEmseepea(createEmseepea({
8
- name: "emseepea-resources-prompts",
8
+ name: "emseepea-resources-and-prompts-server",
9
9
  version: "0.0.0",
10
10
  ...await discoverCapabilities(new URL("./capabilities/", import.meta.url)),
11
11
  }), { port: Number.parseInt(process.env.PORT ?? "3000", 10) });
@@ -8,16 +8,16 @@ test("lists and reads the advertised resource and prompt", async (t) => {
8
8
  const client = await running.connect();
9
9
 
10
10
  assert.deepEqual((await client.listResources()).resources.map(({ uri }) => uri), [
11
- "guide://coffee/getting-started",
11
+ "guide://peas/getting-started",
12
12
  ]);
13
- const resource = await client.readResource({ uri: "guide://coffee/getting-started" });
14
- assert.match(resource.contents[0].text, /Strength is concentration/);
15
- assert.match(resource.contents[0].text, /extraction is how much material left the grounds/);
13
+ const resource = await client.readResource({ uri: "guide://peas/getting-started" });
14
+ assert.match(resource.contents[0].text, /Sowing depth is how deep a seed goes/);
15
+ assert.match(resource.contents[0].text, /plant spacing is the gap between plants/);
16
16
 
17
- assert.deepEqual((await client.listPrompts()).prompts.map(({ name }) => name), ["brew-guide"]);
17
+ assert.deepEqual((await client.listPrompts()).prompts.map(({ name }) => name), ["growing-guide"]);
18
18
  const prompt = await client.getPrompt({
19
- name: "brew-guide",
20
- arguments: { topic: "brew-ratio" },
19
+ name: "growing-guide",
20
+ arguments: { topic: "sowing-depth" },
21
21
  });
22
- assert.match(prompt.messages[0].content.text, /Explain brew-ratio/);
22
+ assert.match(prompt.messages[0].content.text, /Explain sowing-depth/);
23
23
  });
package/package.json CHANGED
@@ -1,22 +1,37 @@
1
1
  {
2
2
  "name": "@emseepea/create-resources-and-prompts-server",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Create an Em See Pea server with resources and prompts.",
5
5
  "license": "MIT",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com/emseepea/emseepea.git",
9
- "directory": "packages/create-resources-and-prompts-server"
10
- },
11
- "homepage": "https://emseepea.github.io/emseepea/examples/",
12
- "bugs": "https://github.com/emseepea/emseepea/issues",
13
- "publishConfig": { "access": "public", "provenance": true, "tag": "next" },
14
6
  "type": "module",
15
- "bin": { "create-resources-and-prompts-server": "./dist/create.mjs" },
16
- "files": ["dist"],
7
+ "starterDependencies": ["@emseepea/server", "zod"],
17
8
  "scripts": {
18
- "build": "node ../../scripts/build-initializer.mjs",
19
- "prepack": "npm run build"
9
+ "build": "npm run build:example && npm run build:initializer",
10
+ "build:example": "tsc -p tsconfig.json",
11
+ "build:initializer": "node ../../scripts/build-initializer.mjs",
12
+ "start": "node dist/server.js",
13
+ "test": "npm run build && npm run test:built",
14
+ "test:built": "node --test test/*.test.mjs",
15
+ "test:llm": "npm run build && npm run test:llm:built",
16
+ "test:llm:built": "emseepea-test eval",
17
+ "lint": "oxlint src test eval",
18
+ "prepack": "npm run build:initializer"
19
+ },
20
+ "devDependencies": {
21
+ "@emseepea/server": "0.2.2",
22
+ "zod": "4.4.3",
23
+ "@emseepea/testing": "0.2.2",
24
+ "@types/node": "24.13.3",
25
+ "typescript": "6.0.3",
26
+ "oxlint": "1.80.0"
20
27
  },
21
- "engines": { "node": ">=22" }
28
+ "engines": {
29
+ "node": ">=22"
30
+ },
31
+ "repository": { "type": "git", "url": "git+https://github.com/emseepea/emseepea.git", "directory": "examples/resources-and-prompts-server" },
32
+ "homepage": "https://emseepea.github.io/emseepea/examples/",
33
+ "bugs": "https://github.com/emseepea/emseepea/issues",
34
+ "publishConfig": { "access": "public", "provenance": true },
35
+ "bin": { "create-resources-and-prompts-server": "./initializer-dist/create.mjs" },
36
+ "files": ["initializer-dist"]
22
37
  }
@@ -1,25 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { semanticTest } from "@emseepea/testing/semantic";
3
-
4
- semanticTest("Strength and extraction remain separate concepts", {
5
- server: new URL("../dist/server.js", import.meta.url),
6
- question:
7
- "Does making coffee stronger necessarily mean that extraction is higher? " +
8
- "Explain the distinction for a home brewer.",
9
- criticalFacts: [
10
- "concentration",
11
- "extraction"
12
- ],
13
- criteria:
14
- "The answer says stronger coffee does not necessarily mean higher extraction. " +
15
- "It explains that strength is concentration while extraction is how much " +
16
- "material left the grounds, and it does not describe the concepts as " +
17
- "interchangeable.",
18
- requiredPaths: ["resources/read:guide://coffee/getting-started","prompts/get:brew-guide"],
19
- async exercise(client) {
20
- const result1 = await client.readResource({"uri":"guide://coffee/getting-started"});
21
- assert.ok(result1);
22
- const result2 = await client.getPrompt({"name":"brew-guide","arguments":{"topic":"brew-ratio"}});
23
- assert.ok(result2);
24
- },
25
- });
File without changes
File without changes