@jaypie/mcp 0.1.0 → 0.1.1

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.
Files changed (48) hide show
  1. package/package.json +4 -3
  2. package/prompts/Branch_Management.md +34 -0
  3. package/prompts/Development_Process.md +67 -0
  4. package/prompts/Jaypie_Agent_Rules.md +110 -0
  5. package/prompts/Jaypie_Auth0_Express_Mongoose.md +736 -0
  6. package/prompts/Jaypie_Browser_and_Frontend_Web_Packages.md +18 -0
  7. package/prompts/Jaypie_CDK_Constructs_and_Patterns.md +156 -0
  8. package/prompts/Jaypie_CICD_with_GitHub_Actions.md +151 -0
  9. package/prompts/Jaypie_Commander_CLI_Package.md +166 -0
  10. package/prompts/Jaypie_Core_Errors_and_Logging.md +39 -0
  11. package/prompts/Jaypie_Eslint_NPM_Package.md +78 -0
  12. package/prompts/Jaypie_Ideal_Project_Structure.md +78 -0
  13. package/prompts/Jaypie_Init_Express_on_Lambda.md +87 -0
  14. package/prompts/Jaypie_Init_Jaypie_CDK_Package.md +35 -0
  15. package/prompts/Jaypie_Init_Lambda_Package.md +245 -0
  16. package/prompts/Jaypie_Init_Monorepo_Project.md +44 -0
  17. package/prompts/Jaypie_Init_Project_Subpackage.md +70 -0
  18. package/prompts/Jaypie_Legacy_Patterns.md +11 -0
  19. package/prompts/Jaypie_Llm_Calls.md +113 -0
  20. package/prompts/Jaypie_Llm_Tools.md +124 -0
  21. package/prompts/Jaypie_Mocks_and_Testkit.md +137 -0
  22. package/prompts/Jaypie_Mongoose_Models_Package.md +231 -0
  23. package/prompts/Jaypie_Mongoose_with_Express_CRUD.md +1000 -0
  24. package/prompts/Jaypie_Scrub.md +177 -0
  25. package/prompts/Write_Efficient_Prompt_Guides.md +48 -0
  26. package/prompts/Write_and_Maintain_Engaging_Readme.md +67 -0
  27. package/prompts/templates/cdk-subpackage/bin/cdk.ts +11 -0
  28. package/prompts/templates/cdk-subpackage/cdk.json +19 -0
  29. package/prompts/templates/cdk-subpackage/lib/cdk-app.ts +41 -0
  30. package/prompts/templates/cdk-subpackage/lib/cdk-infrastructure.ts +15 -0
  31. package/prompts/templates/express-subpackage/index.ts +8 -0
  32. package/prompts/templates/express-subpackage/src/app.ts +18 -0
  33. package/prompts/templates/express-subpackage/src/handler.config.ts +44 -0
  34. package/prompts/templates/express-subpackage/src/routes/resource/__tests__/resourceGet.route.spec.ts +29 -0
  35. package/prompts/templates/express-subpackage/src/routes/resource/resourceGet.route.ts +22 -0
  36. package/prompts/templates/express-subpackage/src/routes/resource.router.ts +11 -0
  37. package/prompts/templates/express-subpackage/src/types/express.ts +9 -0
  38. package/prompts/templates/project-monorepo/.vscode/settings.json +72 -0
  39. package/prompts/templates/project-monorepo/eslint.config.mjs +1 -0
  40. package/prompts/templates/project-monorepo/package.json +20 -0
  41. package/prompts/templates/project-monorepo/tsconfig.base.json +18 -0
  42. package/prompts/templates/project-monorepo/tsconfig.json +6 -0
  43. package/prompts/templates/project-monorepo/vitest.workspace.js +3 -0
  44. package/prompts/templates/project-subpackage/package.json +16 -0
  45. package/prompts/templates/project-subpackage/tsconfig.json +11 -0
  46. package/prompts/templates/project-subpackage/vite.config.ts +21 -0
  47. package/prompts/templates/project-subpackage/vitest.config.ts +7 -0
  48. package/prompts/templates/project-subpackage/vitest.setup.ts +6 -0
@@ -0,0 +1,124 @@
1
+ ---
2
+ trigger: glob
3
+ globs: packages/tools/*
4
+ ---
5
+
6
+ # LLM Tools with Jaypie 🔧
7
+
8
+ Extend LLM capabilities with tools for external actions and data retrieval
9
+
10
+ ## Goal
11
+
12
+ Create and integrate tools that enable LLMs to perform specific functions beyond their training data
13
+
14
+ ## Interface
15
+
16
+ Implement the `LlmTool` interface:
17
+
18
+ ```typescript
19
+ interface LlmTool {
20
+ description: string;
21
+ name: string;
22
+ parameters: JsonObject;
23
+ type: "function" | string;
24
+ call: (args?: JsonObject) => Promise<AnyValue> | AnyValue;
25
+ }
26
+ ```
27
+
28
+ Properties:
29
+ - `description`: Clear explanation of tool functionality
30
+ - `name`: Unique identifier
31
+ - `parameters`: JSON Schema defining input parameters
32
+ - `type`: Usually "function" (OpenAI convention)
33
+ - `call`: Implementation function executed on invocation
34
+
35
+ ## Example: Dice Roller
36
+
37
+ ```typescript
38
+ import { LlmTool } from "../types/LlmTool.interface.js";
39
+ import { log, random, tryParseNumber } from "../util";
40
+
41
+ export const roll: LlmTool = {
42
+ description: "Roll one or more dice with a specified number of sides",
43
+ name: "roll",
44
+ parameters: {
45
+ type: "object",
46
+ properties: {
47
+ number: {
48
+ type: "number",
49
+ description: "Number of dice to roll. Default: 1",
50
+ },
51
+ sides: {
52
+ type: "number",
53
+ description: "Number of sides on each die. Default: 6",
54
+ },
55
+ },
56
+ required: ["number", "sides"],
57
+ },
58
+ type: "function",
59
+ call: ({ number = 1, sides = 6 } = {}): {
60
+ rolls: number[];
61
+ total: number;
62
+ } => {
63
+ const rng = random();
64
+ const rolls: number[] = [];
65
+ let total = 0;
66
+
67
+ const parsedNumber = tryParseNumber(number, {
68
+ defaultValue: 1,
69
+ warnFunction: log.warn,
70
+ }) as number;
71
+ const parsedSides = tryParseNumber(sides, {
72
+ defaultValue: 6,
73
+ warnFunction: log.warn,
74
+ }) as number;
75
+
76
+ for (let i = 0; i < parsedNumber; i++) {
77
+ const rollValue = rng({ min: 1, max: parsedSides, integer: true });
78
+ rolls.push(rollValue);
79
+ total += rollValue;
80
+ }
81
+
82
+ return { rolls, total };
83
+ },
84
+ };
85
+ ```
86
+
87
+ ## Best Practices
88
+
89
+ ### Input Validation
90
+ Validate and sanitize parameters with utilities like `tryParseNumber`.
91
+
92
+ ### Clear Descriptions
93
+ Write precise descriptions for tools and parameters to guide LLM usage.
94
+
95
+ ### Consistent Returns
96
+ Return consistent data structures for predictable LLM interpretation.
97
+
98
+ ### Error Handling
99
+ Implement robust error handling to prevent crashes and provide meaningful messages.
100
+
101
+ ## Integration
102
+
103
+ ```typescript
104
+ import { Llm } from "jaypie";
105
+ import { roll } from "./tools/roll.js";
106
+
107
+ const llm = new Llm({
108
+ provider: "openai",
109
+ model: "gpt-4o"
110
+ });
111
+
112
+ const response = await llm.operate([
113
+ { role: "user", content: "Roll 3d20 and tell me the result" },
114
+ {
115
+ tools: [roll],
116
+ },
117
+ ]);
118
+ ```
119
+
120
+ ## References
121
+
122
+ - [Jaypie Library](https://github.com/finlaysonstudio/jaypie)
123
+ - [OpenAI Function Calling](https://platform.openai.com/docs/guides/function-calling)
124
+ - [Jaypie_Llm_Calls.md](./Jaypie_Llm_Calls.md) to better understand Llm.operate()
@@ -0,0 +1,137 @@
1
+ ---
2
+ description: Jaypie projects rely heavily on mocking the entire jaypie package, often in setup files, as well as manual mocks. Recommended when creating new tests or addressing failures.
3
+ ---
4
+
5
+ # Jaypie Mocks and Testkit
6
+
7
+ Adds unit tests for a JavaScript or TypeScript file.
8
+
9
+ ## Requirements
10
+
11
+ - Use **Vitest** for all test files.
12
+ - Create a new test file as a sibling to the implementation, not a separate directory or tree
13
+ - Use **ECMAScript module syntax** (`import/export`), not CommonJS.
14
+ - Import the function under test using a relative path and include the `.js` extension.
15
+ - Use `describe` blocks for each function and `it` blocks for each behavior.
16
+ - Include tests for:
17
+ - Normal/expected input
18
+ - Edge cases
19
+ - Error handling (if applicable)
20
+ - Ensure all tests are deterministic and do not rely on randomness or network calls unless mocked.
21
+
22
+ ## File Style Rules
23
+
24
+ - Use double quotes.
25
+ - Use ES6+ syntax.
26
+ - Do not modify the original file.
27
+ - Do not include any setup or installation instructions.
28
+
29
+ ## Jaypie Testkit
30
+ `@jaypie/testkit` is the testing library.
31
+ `matchers` are exported and extend expect in the test setup.
32
+ All jaypie functions can be mocked with `vi.mock("jaypie", async () => vi.importActual("@jaypie/testkit/mock"));`
33
+ ### Classes
34
+ Mocked jaypie classes should mocked members for each mocked implementation.
35
+ ```
36
+ Llm.operate.mockResolvedValue("Bueno");
37
+ const llm = new Llm();
38
+ const response = llm.operate();
39
+ expect(response).toBeString("Bueno");
40
+ expect(Llm.operate).toHaveBeenCalled()
41
+ ```
42
+ ### Errors
43
+ Use matchers to test errors.
44
+ `expect(fn).toThrowBadGatewayError();`
45
+ `await expect(async() => fn()).toThrowBadGatewayError();`
46
+ Do not use `.rejects`
47
+ ### Express
48
+ Most express functions are wrapped in `expressHandler` which is mocked.
49
+ Test express functions directly with a `req` object.
50
+ Handle cases where the `req` object is undefined or incomplete.
51
+ supertest is also available to test http responses.
52
+ ### Logging
53
+ `log` is mocked by `@jaypie/testkit/mock` or separately using `spyLog` and `restoreLog` in `@jaypie/testkit`.
54
+ Use matchers on `log` functions and `toBeCalledAboveTrace` on `log` itself.
55
+ `expect(log).not.toBeCalledAboveTrace();`
56
+ `expect(log.warn).toBeCalled();`
57
+ ### Matchers
58
+ toBeCalledAboveTrace, toBeCalledWithInitialParams, toBeClass, toBeJaypieError, toMatchBase64, toMatchJwt, toMatchMongoId, toMatchSchema, toMatchSignedCookie, toMatchUuid4, toMatchUuid5, toMatchUuid, toThrowBadGatewayError, toThrowBadRequestError, toThrowConfigurationError, toThrowForbiddenError, toThrowGatewayTimeoutError, toThrowInternalError, toThrowJaypieError, toThrowNotFoundError, toThrowUnauthorizedError, toThrowUnavailableError,
59
+ ### Order of Tests
60
+ Tests are named `./__tests__/<subject>.spec.<js|ts>`.
61
+ Each file should have one top-level `describe` block.
62
+ Organize tests in one of seven second-level describe block sections in this order:
63
+ 1. Base Cases - it is the type we expect ("It is a Function"). For functions, the simplest possible call works and returns not undefined ("It Works"). For objects, the expected shape.
64
+ 2. Error Conditions - any error handling the code performs
65
+ 3. Security - any security checks the code performs
66
+ 4. Observability - any logging the code performs
67
+ 5. Happy Paths - The most common use case
68
+ 6. Features - Features in addition to the happy path
69
+ 7. Specific Scenarios - Special cases
70
+ Omit describe blocks for sections that are not applicable or empty.
71
+ Whenever possible, especially when refactoring, write the test first so the user can confirm the expected behavior passes/fails.
72
+ ### Test Coverage
73
+ Aim for complete coverage of all happy paths, features, and error conditions.
74
+ Whenever possible, confirm mocked functions are called.
75
+ Confirm calls to log above debug in Observability. Do not confirm calls to debug, var, or trace.
76
+
77
+ ## Configuration
78
+
79
+ ### Typical Package
80
+
81
+ `package.json`
82
+ ```json
83
+ "scripts": {
84
+ "test": "vitest run",
85
+ "test:watch": "vitest watch",
86
+ }
87
+ ```
88
+
89
+ `vitest.config.ts`
90
+ ```typescript
91
+ import { defineConfig } from "vite";
92
+
93
+ export default defineConfig({
94
+ test: {
95
+ setupFiles: ["./vitest.setup.ts"],
96
+ },
97
+ });
98
+ ```
99
+
100
+ `vitest.setup.ts`
101
+ ```typescript
102
+ // This file left intentionally blank
103
+ ```
104
+
105
+ * `vitest.setup.ts` can be used to extend the jest matchers, for example, or setting up other mocks
106
+ ```typescript
107
+ import * as extendedMatchers from "jest-extended";
108
+ import { expect } from "vitest";
109
+
110
+ expect.extend(extendedMatchers);
111
+ ```
112
+ * Before creating a `vitest.setup.ts`, check if `testSetup.js` exists.
113
+
114
+ ## NPM Workspaces (monorepos)
115
+
116
+ * Configure sub-packages following the above
117
+ * Usually only sub-packages have `vitest.config.ts` and `vitest.setup.ts`
118
+ * Configure the root package as follows, iterating for each `<package>` below
119
+
120
+ `package.json`
121
+ ```json
122
+ "scripts": {
123
+ "test": "vitest run",
124
+ "test:watch": "vitest watch",
125
+ "test:<package>": "npm run test --workspace packages/<package>"
126
+ "test:<package>:watch": "npm run test:watch --workspace packages/<package>"
127
+ }
128
+ ```
129
+
130
+ `vitest.workspace.ts`
131
+ ```typescript
132
+ import { defineWorkspace } from "vitest/config";
133
+
134
+ export default defineWorkspace([
135
+ "packages/<package>",
136
+ ]);
137
+ ```
@@ -0,0 +1,231 @@
1
+ ---
2
+ description: Document describes a Jaypie pattern repeated in many projects but not yet offered as a package within Jaypie
3
+ globs: packages/models/**
4
+ status: Work in Progress
5
+ ---
6
+
7
+ # Jaypie Mongoose Models Package
8
+
9
+ Create reusable MongoDB models with rich relationship management using Mongoose and Jaypie.
10
+
11
+ ## Goal
12
+
13
+ Define document schemas with bidirectional relationships and consistent utilities for mongoose models.
14
+
15
+ ## Guidelines
16
+
17
+ - Uses ES modules with `.js` extensions (`"type": "module"`)
18
+ - Requires mongoose and jaypie as dependencies
19
+ - Follows schema organization pattern: definition → hooks → methods → statics → export
20
+ - Every schema should use `projectSchema.plugin.js` for relationship methods
21
+ - Every document has `uuid` field for external references
22
+
23
+ ## Process
24
+
25
+ ### Package Setup
26
+
27
+ 1. Create package structure:
28
+ ```
29
+ models/
30
+ ├── package.json
31
+ ├── src/
32
+ │ ├── constants.js
33
+ │ ├── index.js
34
+ │ ├── user.schema.js
35
+ │ ├── projectSchema.plugin.js
36
+ │ └── __tests__/
37
+ │ ├── constants.spec.js
38
+ │ ├── index.spec.js
39
+ │ ├── user.schema.spec.js
40
+ │ └── projectSchema.plugin.spec.js
41
+ ├── testSetup.js
42
+ └── vite.config.js
43
+ ```
44
+
45
+ 2. Configure package.json:
46
+ ```json
47
+ {
48
+ "name": "@yournamespace/models",
49
+ "type": "module",
50
+ "exports": {
51
+ ".": {
52
+ "default": {
53
+ "require": "./dist/module.cjs.js",
54
+ "default": "./src/index.js"
55
+ }
56
+ }
57
+ },
58
+ "main": "src/index.js",
59
+ "dependencies": {
60
+ "jaypie": "^1.1.0",
61
+ "mongoose": "^7.0.0"
62
+ }
63
+ }
64
+ ```
65
+
66
+ ### Core Files Implementation
67
+
68
+ 1. projectSchema.plugin.js
69
+ - Plugin providing relationship management methods
70
+ - Key functions: allLeanByIds, allLeanByUuids, createWithRelationships, deleteWithRelationships, toJsonWithRelationships, updateWithRelationships
71
+ - Utility functions: idsToUuids, uuidsToIds, oneByUuid, oneByXid
72
+
73
+ 2. constants.ts
74
+ ```typescript
75
+ import { v5 as uuidv5 } from "uuid";
76
+
77
+ const NAMESPACE_ROOT = "your-namespace-uuid";
78
+ export const NAMESPACE = {
79
+ USER: uuidv5("USER", NAMESPACE_ROOT),
80
+ };
81
+
82
+ export const SCHEMA = {
83
+ USER: "user",
84
+ };
85
+
86
+ export default {
87
+ NAMESPACE,
88
+ SCHEMA,
89
+ };
90
+ ```
91
+
92
+ 3. user.schema.ts
93
+ ```typescript
94
+ import { Schema } from "mongoose";
95
+ import projectSchema from "./projectSchema.plugin.js";
96
+
97
+ const schema = new Schema(
98
+ {
99
+ deletedAt: {
100
+ type: Schema.Types.Date,
101
+ },
102
+ name: {
103
+ type: Schema.Types.String,
104
+ },
105
+ uuid: {
106
+ index: true,
107
+ type: Schema.Types.String,
108
+ },
109
+ xid: {
110
+ index: true,
111
+ type: Schema.Types.String,
112
+ },
113
+ },
114
+ { timestamps: true },
115
+ );
116
+
117
+ schema.plugin(projectSchema);
118
+
119
+ export default schema;
120
+ ```
121
+
122
+ 4. index.ts
123
+ ```typescript
124
+ import { connect, disconnect, envsKey, log } from "jaypie";
125
+ import mongoose, { Model, Schema } from "mongoose";
126
+ import { SCHEMA } from "./constants.js";
127
+ import userSchema from "./user.schema.js";
128
+
129
+ let instantiatedModel: Record<string, Model<any>> | null;
130
+ const { model } = mongoose;
131
+
132
+ function getModel(name: string, schema: Schema): Model<any> {
133
+ if (!instantiatedModel) {
134
+ log.warn("[@yournamespace/models] Models have not been instantiated");
135
+ instantiatedModel = {};
136
+ }
137
+ return instantiatedModel[name] || (instantiatedModel[name] = model(name, schema));
138
+ }
139
+
140
+ export default {
141
+ connect: async (uri: string = envsKey("MONGODB_URI")) => {
142
+ if (instantiatedModel) {
143
+ log.warn("[@yournamespace/models] Models already instantiated");
144
+ } else {
145
+ instantiatedModel = {};
146
+ }
147
+ return uri ? mongoose.connect(uri) : connect();
148
+ },
149
+ disconnect: () => {
150
+ instantiatedModel = null;
151
+ return disconnect();
152
+ },
153
+ get User() {
154
+ return getModel(SCHEMA.USER, userSchema);
155
+ },
156
+ };
157
+
158
+ export { default as MODEL } from "./constants.js";
159
+ ```
160
+
161
+ ### Testing
162
+
163
+ 1. vite.config.ts
164
+ ```typescript
165
+ import { defineConfig } from "vite";
166
+
167
+ export default defineConfig({
168
+ test: {
169
+ globals: false,
170
+ setupFiles: ["./testSetup.ts"],
171
+ },
172
+ });
173
+ ```
174
+
175
+ 2. testSetup.ts
176
+ ```typescript
177
+ import { beforeEach, vi } from "vitest";
178
+ import mongoose from "mongoose";
179
+
180
+ // Mock mongoose methods
181
+ vi.mock("mongoose", async () => {
182
+ const actual = await vi.importActual("mongoose");
183
+ return {
184
+ ...actual,
185
+ connect: vi.fn().mockResolvedValue({}),
186
+ disconnect: vi.fn().mockResolvedValue({}),
187
+ };
188
+ });
189
+
190
+ // Reset mocks before each test
191
+ beforeEach(() => {
192
+ vi.clearAllMocks();
193
+ });
194
+ ```
195
+
196
+ ### Usage
197
+
198
+ 1. Connect to database:
199
+ ```typescript
200
+ import Model from "@yournamespace/models";
201
+
202
+ await Model.connect();
203
+ ```
204
+
205
+ 2. Create document:
206
+ ```typescript
207
+ const user = await Model.User.createWithRelationships({
208
+ uuid: "user-uuid",
209
+ values: { name: "Test User" },
210
+ });
211
+ ```
212
+
213
+ 3. Find document:
214
+ ```typescript
215
+ const user = await Model.User.oneByUuid("user-uuid");
216
+ ```
217
+
218
+ 4. Update with relationships:
219
+ ```typescript
220
+ await Model.User.updateWithRelationships({
221
+ uuid: "user-uuid",
222
+ values: { name: "Updated Name" },
223
+ });
224
+ ```
225
+
226
+ 5. Delete with relationships:
227
+ ```typescript
228
+ await Model.User.deleteWithRelationships({
229
+ uuid: "user-uuid",
230
+ });
231
+ ```