@jaypie/mcp 0.4.1 → 0.6.0

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 (73) hide show
  1. package/README.md +3 -2
  2. package/dist/createMcpServer.js +34 -0
  3. package/dist/createMcpServer.js.map +1 -0
  4. package/dist/index.js +3 -92
  5. package/dist/index.js.map +1 -1
  6. package/dist/mcpExpressHandler.js +56 -0
  7. package/dist/mcpExpressHandler.js.map +1 -0
  8. package/dist/suite.d.ts +12 -0
  9. package/dist/suite.js +23 -2426
  10. package/dist/suite.js.map +1 -1
  11. package/dist/suites/aws/aws.js +328 -0
  12. package/dist/suites/aws/aws.js.map +1 -0
  13. package/dist/suites/aws/help.md +42 -0
  14. package/dist/suites/aws/index.d.ts +102 -0
  15. package/dist/suites/aws/index.js +258 -0
  16. package/dist/suites/aws/index.js.map +1 -0
  17. package/dist/suites/datadog/datadog.js +828 -0
  18. package/dist/suites/datadog/datadog.js.map +1 -0
  19. package/dist/suites/datadog/help.md +39 -0
  20. package/dist/suites/datadog/index.d.ts +24 -0
  21. package/dist/suites/datadog/index.js +156 -0
  22. package/dist/suites/datadog/index.js.map +1 -0
  23. package/dist/suites/docs/index.d.ts +14 -0
  24. package/dist/suites/docs/index.js +246 -0
  25. package/dist/suites/docs/index.js.map +1 -0
  26. package/dist/suites/docs/release-notes/help.md +37 -0
  27. package/dist/suites/llm/help.md +39 -0
  28. package/dist/suites/llm/index.d.ts +11 -0
  29. package/dist/suites/llm/index.js +61 -0
  30. package/dist/suites/llm/index.js.map +1 -0
  31. package/dist/{llm.d.ts → suites/llm/llm.d.ts} +0 -11
  32. package/dist/suites/llm/llm.js +61 -0
  33. package/dist/suites/llm/llm.js.map +1 -0
  34. package/package.json +4 -3
  35. package/release-notes/aws/1.2.5.md +18 -0
  36. package/release-notes/constructs/1.2.19.md +35 -0
  37. package/release-notes/dynamodb/0.4.0.md +44 -0
  38. package/release-notes/express/1.2.5.md +33 -0
  39. package/release-notes/fabric/0.2.0.md +77 -0
  40. package/release-notes/fabric/0.2.1.md +36 -0
  41. package/release-notes/jaypie/1.2.4.md +11 -0
  42. package/release-notes/jaypie/1.2.5.md +9 -0
  43. package/release-notes/lambda/1.2.4.md +39 -0
  44. package/release-notes/llm/1.2.7.md +12 -0
  45. package/release-notes/mcp/0.5.0.md +70 -0
  46. package/release-notes/mcp/0.5.1.md +23 -0
  47. package/release-notes/mcp/0.6.0.md +19 -0
  48. package/release-notes/testkit/1.2.17.md +30 -0
  49. package/release-notes/testkit/1.2.18.md +16 -0
  50. package/skills/agents.md +2 -2
  51. package/skills/cdk.md +5 -1
  52. package/skills/contents.md +24 -0
  53. package/skills/development.md +19 -0
  54. package/skills/documentation.md +19 -145
  55. package/skills/express.md +158 -0
  56. package/skills/fabric.md +7 -4
  57. package/skills/handlers.md +172 -0
  58. package/skills/infrastructure.md +22 -0
  59. package/skills/lambda.md +164 -0
  60. package/skills/llm.md +4 -1
  61. package/skills/meta.md +17 -0
  62. package/skills/patterns.md +19 -0
  63. package/skills/skills.md +11 -12
  64. package/skills/streaming.md +120 -0
  65. package/skills/style.md +1 -24
  66. package/skills/tools-aws.md +65 -47
  67. package/skills/tools-datadog.md +53 -44
  68. package/skills/tools-dynamodb.md +72 -44
  69. package/skills/tools.md +55 -42
  70. package/skills/vocabulary.md +143 -8
  71. package/skills/websockets.md +203 -0
  72. /package/dist/{aws.d.ts → suites/aws/aws.d.ts} +0 -0
  73. /package/dist/{datadog.d.ts → suites/datadog/datadog.d.ts} +0 -0
@@ -0,0 +1,246 @@
1
+ import { fabricService } from '@jaypie/fabric';
2
+ import * as fs from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import matter from 'gray-matter';
6
+ import { gt } from 'semver';
7
+
8
+ /**
9
+ * Docs Suite - Documentation services (skill, version, release_notes)
10
+ */
11
+ const BUILD_VERSION_STRING = "@jaypie/mcp@0.6.0#d4227f02"
12
+ ;
13
+ const __filename$1 = fileURLToPath(import.meta.url);
14
+ const __dirname$1 = path.dirname(__filename$1);
15
+ // From dist/suites/docs/, go up 3 levels to package root where skills/ and release-notes/ live
16
+ const RELEASE_NOTES_PATH = path.join(__dirname$1, "..", "..", "..", "release-notes");
17
+ const SKILLS_PATH = path.join(__dirname$1, "..", "..", "..", "skills");
18
+ function isValidSkillAlias(alias) {
19
+ const normalized = alias.toLowerCase().trim();
20
+ if (normalized.includes("/") ||
21
+ normalized.includes("\\") ||
22
+ normalized.includes("..")) {
23
+ return false;
24
+ }
25
+ return /^[a-z0-9_-]+$/.test(normalized);
26
+ }
27
+ async function parseReleaseNoteFile(filePath) {
28
+ try {
29
+ const content = await fs.readFile(filePath, "utf-8");
30
+ const filename = path.basename(filePath, ".md");
31
+ if (content.startsWith("---")) {
32
+ const parsed = matter(content);
33
+ const frontMatter = parsed.data;
34
+ return {
35
+ date: frontMatter.date,
36
+ filename,
37
+ summary: frontMatter.summary,
38
+ version: frontMatter.version || filename,
39
+ };
40
+ }
41
+ return { filename, version: filename };
42
+ }
43
+ catch {
44
+ return { filename: path.basename(filePath, ".md") };
45
+ }
46
+ }
47
+ function formatReleaseNoteListItem(note) {
48
+ const { date, packageName, summary, version } = note;
49
+ const parts = [`* ${packageName}@${version}`];
50
+ if (date) {
51
+ parts.push(`(${date})`);
52
+ }
53
+ if (summary) {
54
+ parts.push(`- ${summary}`);
55
+ }
56
+ return parts.join(" ");
57
+ }
58
+ async function parseSkillFile(filePath) {
59
+ try {
60
+ const content = await fs.readFile(filePath, "utf-8");
61
+ const alias = path.basename(filePath, ".md");
62
+ if (content.startsWith("---")) {
63
+ const parsed = matter(content);
64
+ const frontMatter = parsed.data;
65
+ return {
66
+ alias,
67
+ description: frontMatter.description,
68
+ };
69
+ }
70
+ return { alias };
71
+ }
72
+ catch {
73
+ return { alias: path.basename(filePath, ".md") };
74
+ }
75
+ }
76
+ function formatSkillListItem(skill) {
77
+ const { alias, description } = skill;
78
+ if (description) {
79
+ return `* ${alias} - ${description}`;
80
+ }
81
+ return `* ${alias}`;
82
+ }
83
+ async function getPackageReleaseNotes(packageName) {
84
+ const packageDir = path.join(RELEASE_NOTES_PATH, packageName);
85
+ try {
86
+ const files = await fs.readdir(packageDir);
87
+ const mdFiles = files.filter((file) => file.endsWith(".md"));
88
+ const notes = await Promise.all(mdFiles.map(async (file) => {
89
+ const parsed = await parseReleaseNoteFile(path.join(packageDir, file));
90
+ return { ...parsed, packageName };
91
+ }));
92
+ return notes.sort((a, b) => {
93
+ if (!a.version || !b.version)
94
+ return 0;
95
+ try {
96
+ return gt(a.version, b.version) ? -1 : 1;
97
+ }
98
+ catch {
99
+ return b.version.localeCompare(a.version);
100
+ }
101
+ });
102
+ }
103
+ catch {
104
+ return [];
105
+ }
106
+ }
107
+ function filterReleaseNotesSince(notes, sinceVersion) {
108
+ return notes.filter((note) => {
109
+ if (!note.version)
110
+ return false;
111
+ try {
112
+ return gt(note.version, sinceVersion);
113
+ }
114
+ catch {
115
+ return false;
116
+ }
117
+ });
118
+ }
119
+ // =============================================================================
120
+ // SKILL SERVICE
121
+ // =============================================================================
122
+ const skillService = fabricService({
123
+ alias: "skill",
124
+ description: "Access Jaypie development documentation. Pass a skill alias (e.g., 'aws', 'tests', 'errors') to get that documentation. Pass 'index' or no argument to list all available skills.",
125
+ input: {
126
+ alias: {
127
+ description: "Skill alias (e.g., 'aws', 'tests'). Omit or use 'index' to list all skills.",
128
+ required: false,
129
+ type: String,
130
+ },
131
+ },
132
+ service: async ({ alias: inputAlias }) => {
133
+ const alias = (inputAlias || "index").toLowerCase().trim();
134
+ if (!isValidSkillAlias(alias)) {
135
+ throw new Error(`Invalid skill alias "${alias}". Use alphanumeric characters, hyphens, and underscores only.`);
136
+ }
137
+ if (alias === "index") {
138
+ const indexPath = path.join(SKILLS_PATH, "index.md");
139
+ let indexContent = "";
140
+ try {
141
+ indexContent = await fs.readFile(indexPath, "utf-8");
142
+ if (indexContent.startsWith("---")) {
143
+ const parsed = matter(indexContent);
144
+ indexContent = parsed.content.trim();
145
+ }
146
+ }
147
+ catch {
148
+ // Index file doesn't exist, will just show skill list
149
+ }
150
+ const files = await fs.readdir(SKILLS_PATH);
151
+ const mdFiles = files.filter((file) => file.endsWith(".md") && file !== "index.md");
152
+ const skills = await Promise.all(mdFiles.map((file) => parseSkillFile(path.join(SKILLS_PATH, file))));
153
+ skills.sort((a, b) => a.alias.localeCompare(b.alias));
154
+ const skillList = skills.map(formatSkillListItem).join("\n");
155
+ if (indexContent) {
156
+ return `${indexContent}\n\n## Available Skills\n\n${skillList}`;
157
+ }
158
+ return `# Jaypie Skills\n\n## Available Skills\n\n${skillList}`;
159
+ }
160
+ const skillPath = path.join(SKILLS_PATH, `${alias}.md`);
161
+ try {
162
+ return await fs.readFile(skillPath, "utf-8");
163
+ }
164
+ catch {
165
+ throw new Error(`Skill "${alias}" not found. Use skill("index") to list available skills.`);
166
+ }
167
+ },
168
+ });
169
+ // =============================================================================
170
+ // VERSION SERVICE
171
+ // =============================================================================
172
+ const versionService = fabricService({
173
+ alias: "version",
174
+ description: `Prints the current version and hash, \`${BUILD_VERSION_STRING}\``,
175
+ input: {},
176
+ service: async () => BUILD_VERSION_STRING,
177
+ });
178
+ // =============================================================================
179
+ // RELEASE NOTES SERVICE
180
+ // =============================================================================
181
+ async function getReleaseNotesHelp() {
182
+ return fs.readFile(path.join(__dirname$1, "release-notes", "help.md"), "utf-8");
183
+ }
184
+ const releaseNotesService = fabricService({
185
+ alias: "release_notes",
186
+ description: "Browse Jaypie package release notes. Commands: list, read. Call with no args for help.",
187
+ input: {
188
+ command: {
189
+ description: "Command to execute (omit for help)",
190
+ required: false,
191
+ type: String,
192
+ },
193
+ input: {
194
+ description: "Command parameters",
195
+ required: false,
196
+ type: Object,
197
+ },
198
+ },
199
+ service: async ({ command, input: params, }) => {
200
+ if (!command || command === "help") {
201
+ return getReleaseNotesHelp();
202
+ }
203
+ const p = params || {};
204
+ switch (command) {
205
+ case "list": {
206
+ const entries = await fs.readdir(RELEASE_NOTES_PATH, {
207
+ withFileTypes: true,
208
+ });
209
+ const packageDirs = entries
210
+ .filter((entry) => entry.isDirectory())
211
+ .map((entry) => entry.name);
212
+ const packagesToList = p.package
213
+ ? packageDirs.filter((pkg) => pkg === p.package)
214
+ : packageDirs;
215
+ if (packagesToList.length === 0 && p.package) {
216
+ return `No release notes found for package "${p.package}".`;
217
+ }
218
+ const allNotes = await Promise.all(packagesToList.map((pkg) => getPackageReleaseNotes(pkg)));
219
+ let flatNotes = allNotes.flat();
220
+ if (p.since_version) {
221
+ flatNotes = filterReleaseNotesSince(flatNotes, p.since_version);
222
+ }
223
+ if (flatNotes.length === 0) {
224
+ const filterDesc = p.since_version
225
+ ? ` newer than ${p.since_version}`
226
+ : "";
227
+ return `No release notes found${filterDesc}.`;
228
+ }
229
+ return flatNotes.map(formatReleaseNoteListItem).join("\n");
230
+ }
231
+ case "read": {
232
+ if (!p.package)
233
+ throw new Error("package is required");
234
+ if (!p.version)
235
+ throw new Error("version is required");
236
+ const filePath = path.join(RELEASE_NOTES_PATH, p.package, `${p.version}.md`);
237
+ return fs.readFile(filePath, "utf-8");
238
+ }
239
+ default:
240
+ throw new Error(`Unknown command: ${command}. Use release_notes() for help.`);
241
+ }
242
+ },
243
+ });
244
+
245
+ export { releaseNotesService, skillService, versionService };
246
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../src/suites/docs/index.ts"],"sourcesContent":["/**\n * Docs Suite - Documentation services (skill, version, release_notes)\n */\nimport { fabricService } from \"@jaypie/fabric\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport matter from \"gray-matter\";\nimport { gt } from \"semver\";\n\n// Build-time constants\ndeclare const __BUILD_VERSION_STRING__: string;\nconst BUILD_VERSION_STRING =\n typeof __BUILD_VERSION_STRING__ !== \"undefined\"\n ? __BUILD_VERSION_STRING__\n : \"@jaypie/mcp@0.0.0\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n// From dist/suites/docs/, go up 3 levels to package root where skills/ and release-notes/ live\nconst RELEASE_NOTES_PATH = path.join(\n __dirname,\n \"..\",\n \"..\",\n \"..\",\n \"release-notes\",\n);\nconst SKILLS_PATH = path.join(__dirname, \"..\", \"..\", \"..\", \"skills\");\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\ninterface ReleaseNoteFrontMatter {\n date?: string;\n summary?: string;\n version?: string;\n}\n\ninterface SkillFrontMatter {\n description?: string;\n}\n\nfunction isValidSkillAlias(alias: string): boolean {\n const normalized = alias.toLowerCase().trim();\n if (\n normalized.includes(\"/\") ||\n normalized.includes(\"\\\\\") ||\n normalized.includes(\"..\")\n ) {\n return false;\n }\n return /^[a-z0-9_-]+$/.test(normalized);\n}\n\nasync function parseReleaseNoteFile(filePath: string): Promise<{\n date?: string;\n filename: string;\n summary?: string;\n version?: string;\n}> {\n try {\n const content = await fs.readFile(filePath, \"utf-8\");\n const filename = path.basename(filePath, \".md\");\n\n if (content.startsWith(\"---\")) {\n const parsed = matter(content);\n const frontMatter = parsed.data as ReleaseNoteFrontMatter;\n return {\n date: frontMatter.date,\n filename,\n summary: frontMatter.summary,\n version: frontMatter.version || filename,\n };\n }\n\n return { filename, version: filename };\n } catch {\n return { filename: path.basename(filePath, \".md\") };\n }\n}\n\nfunction formatReleaseNoteListItem(note: {\n date?: string;\n filename: string;\n packageName: string;\n summary?: string;\n version?: string;\n}): string {\n const { date, packageName, summary, version } = note;\n const parts = [`* ${packageName}@${version}`];\n\n if (date) {\n parts.push(`(${date})`);\n }\n\n if (summary) {\n parts.push(`- ${summary}`);\n }\n\n return parts.join(\" \");\n}\n\nasync function parseSkillFile(filePath: string): Promise<{\n alias: string;\n description?: string;\n}> {\n try {\n const content = await fs.readFile(filePath, \"utf-8\");\n const alias = path.basename(filePath, \".md\");\n\n if (content.startsWith(\"---\")) {\n const parsed = matter(content);\n const frontMatter = parsed.data as SkillFrontMatter;\n return {\n alias,\n description: frontMatter.description,\n };\n }\n\n return { alias };\n } catch {\n return { alias: path.basename(filePath, \".md\") };\n }\n}\n\nfunction formatSkillListItem(skill: {\n alias: string;\n description?: string;\n}): string {\n const { alias, description } = skill;\n if (description) {\n return `* ${alias} - ${description}`;\n }\n return `* ${alias}`;\n}\n\nasync function getPackageReleaseNotes(packageName: string): Promise<\n Array<{\n date?: string;\n filename: string;\n packageName: string;\n summary?: string;\n version?: string;\n }>\n> {\n const packageDir = path.join(RELEASE_NOTES_PATH, packageName);\n try {\n const files = await fs.readdir(packageDir);\n const mdFiles = files.filter((file) => file.endsWith(\".md\"));\n\n const notes = await Promise.all(\n mdFiles.map(async (file) => {\n const parsed = await parseReleaseNoteFile(path.join(packageDir, file));\n return { ...parsed, packageName };\n }),\n );\n\n return notes.sort((a, b) => {\n if (!a.version || !b.version) return 0;\n try {\n return gt(a.version, b.version) ? -1 : 1;\n } catch {\n return b.version.localeCompare(a.version);\n }\n });\n } catch {\n return [];\n }\n}\n\nfunction filterReleaseNotesSince(\n notes: Array<{\n date?: string;\n filename: string;\n packageName: string;\n summary?: string;\n version?: string;\n }>,\n sinceVersion: string,\n): Array<{\n date?: string;\n filename: string;\n packageName: string;\n summary?: string;\n version?: string;\n}> {\n return notes.filter((note) => {\n if (!note.version) return false;\n try {\n return gt(note.version, sinceVersion);\n } catch {\n return false;\n }\n });\n}\n\n// =============================================================================\n// SKILL SERVICE\n// =============================================================================\n\nexport const skillService = fabricService({\n alias: \"skill\",\n description:\n \"Access Jaypie development documentation. Pass a skill alias (e.g., 'aws', 'tests', 'errors') to get that documentation. Pass 'index' or no argument to list all available skills.\",\n input: {\n alias: {\n description:\n \"Skill alias (e.g., 'aws', 'tests'). Omit or use 'index' to list all skills.\",\n required: false,\n type: String,\n },\n },\n service: async ({ alias: inputAlias }: { alias?: string }) => {\n const alias = (inputAlias || \"index\").toLowerCase().trim();\n\n if (!isValidSkillAlias(alias)) {\n throw new Error(\n `Invalid skill alias \"${alias}\". Use alphanumeric characters, hyphens, and underscores only.`,\n );\n }\n\n if (alias === \"index\") {\n const indexPath = path.join(SKILLS_PATH, \"index.md\");\n let indexContent = \"\";\n\n try {\n indexContent = await fs.readFile(indexPath, \"utf-8\");\n if (indexContent.startsWith(\"---\")) {\n const parsed = matter(indexContent);\n indexContent = parsed.content.trim();\n }\n } catch {\n // Index file doesn't exist, will just show skill list\n }\n\n const files = await fs.readdir(SKILLS_PATH);\n const mdFiles = files.filter(\n (file) => file.endsWith(\".md\") && file !== \"index.md\",\n );\n\n const skills = await Promise.all(\n mdFiles.map((file) => parseSkillFile(path.join(SKILLS_PATH, file))),\n );\n\n skills.sort((a, b) => a.alias.localeCompare(b.alias));\n\n const skillList = skills.map(formatSkillListItem).join(\"\\n\");\n\n if (indexContent) {\n return `${indexContent}\\n\\n## Available Skills\\n\\n${skillList}`;\n }\n return `# Jaypie Skills\\n\\n## Available Skills\\n\\n${skillList}`;\n }\n\n const skillPath = path.join(SKILLS_PATH, `${alias}.md`);\n try {\n return await fs.readFile(skillPath, \"utf-8\");\n } catch {\n throw new Error(\n `Skill \"${alias}\" not found. Use skill(\"index\") to list available skills.`,\n );\n }\n },\n});\n\n// =============================================================================\n// VERSION SERVICE\n// =============================================================================\n\nexport const versionService = fabricService({\n alias: \"version\",\n description: `Prints the current version and hash, \\`${BUILD_VERSION_STRING}\\``,\n input: {},\n service: async () => BUILD_VERSION_STRING,\n});\n\n// =============================================================================\n// RELEASE NOTES SERVICE\n// =============================================================================\n\nasync function getReleaseNotesHelp(): Promise<string> {\n return fs.readFile(path.join(__dirname, \"release-notes\", \"help.md\"), \"utf-8\");\n}\n\ninterface ReleaseNotesInput {\n package?: string;\n since_version?: string;\n version?: string;\n}\n\nexport const releaseNotesService = fabricService({\n alias: \"release_notes\",\n description:\n \"Browse Jaypie package release notes. Commands: list, read. Call with no args for help.\",\n input: {\n command: {\n description: \"Command to execute (omit for help)\",\n required: false,\n type: String,\n },\n input: {\n description: \"Command parameters\",\n required: false,\n type: Object,\n },\n },\n service: async ({\n command,\n input: params,\n }: {\n command?: string;\n input?: ReleaseNotesInput;\n }) => {\n if (!command || command === \"help\") {\n return getReleaseNotesHelp();\n }\n\n const p = params || {};\n\n switch (command) {\n case \"list\": {\n const entries = await fs.readdir(RELEASE_NOTES_PATH, {\n withFileTypes: true,\n });\n const packageDirs = entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name);\n const packagesToList = p.package\n ? packageDirs.filter((pkg) => pkg === p.package)\n : packageDirs;\n\n if (packagesToList.length === 0 && p.package) {\n return `No release notes found for package \"${p.package}\".`;\n }\n\n const allNotes = await Promise.all(\n packagesToList.map((pkg) => getPackageReleaseNotes(pkg)),\n );\n let flatNotes = allNotes.flat();\n\n if (p.since_version) {\n flatNotes = filterReleaseNotesSince(flatNotes, p.since_version);\n }\n\n if (flatNotes.length === 0) {\n const filterDesc = p.since_version\n ? ` newer than ${p.since_version}`\n : \"\";\n return `No release notes found${filterDesc}.`;\n }\n\n return flatNotes.map(formatReleaseNoteListItem).join(\"\\n\");\n }\n\n case \"read\": {\n if (!p.package) throw new Error(\"package is required\");\n if (!p.version) throw new Error(\"version is required\");\n const filePath = path.join(\n RELEASE_NOTES_PATH,\n p.package,\n `${p.version}.md`,\n );\n return fs.readFile(filePath, \"utf-8\");\n }\n\n default:\n throw new Error(\n `Unknown command: ${command}. Use release_notes() for help.`,\n );\n }\n },\n});\n"],"names":["__filename","__dirname"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ # Release Notes
2
+
3
+ Browse Jaypie package release notes.
4
+
5
+ ## Commands
6
+
7
+ | Command | Description | Required Parameters |
8
+ |---------|-------------|---------------------|
9
+ | `list` | List available release notes | - |
10
+ | `read` | Read a specific release note | `package`, `version` |
11
+
12
+ ## Options for `list`
13
+
14
+ | Option | Description |
15
+ |--------|-------------|
16
+ | `package` | Filter by package name (e.g., "mcp", "jaypie") |
17
+ | `since_version` | Only versions newer than this (e.g., "1.0.0") |
18
+
19
+ ## Examples
20
+
21
+ ```
22
+ release_notes("list")
23
+ release_notes("list", { package: "mcp" })
24
+ release_notes("list", { package: "jaypie", since_version: "2.0.0" })
25
+ release_notes("read", { package: "mcp", version: "0.4.2" })
26
+ ```
27
+
28
+ ## Available Packages
29
+
30
+ Release notes are available for all Jaypie packages including:
31
+ - `jaypie` - Main package
32
+ - `mcp` - MCP server
33
+ - `fabric` - Service handlers and adapters
34
+ - `llm` - LLM provider interface
35
+ - And more...
36
+
37
+ Use `release_notes("list")` to see all available packages and versions.
@@ -0,0 +1,39 @@
1
+ # LLM Tools
2
+
3
+ Debug and inspect LLM provider responses. Useful for understanding how providers format responses.
4
+
5
+ ## Commands
6
+
7
+ | Command | Description | Required Parameters |
8
+ |---------|-------------|---------------------|
9
+ | `debug_call` | Make a debug call and inspect response | `provider`, `message` |
10
+
11
+ ## Providers
12
+
13
+ Supported providers: `openai`, `anthropic`, `gemini`, `openrouter`
14
+
15
+ ## Environment Variables
16
+
17
+ | Variable | Description |
18
+ |----------|-------------|
19
+ | `OPENAI_API_KEY` | OpenAI API key |
20
+ | `ANTHROPIC_API_KEY` | Anthropic API key |
21
+ | `GOOGLE_API_KEY` | Google/Gemini API key |
22
+ | `OPENROUTER_API_KEY` | OpenRouter API key |
23
+
24
+ ## Examples
25
+
26
+ ```
27
+ llm("debug_call", { provider: "openai", message: "Hello, world!" })
28
+ llm("debug_call", { provider: "openai", model: "o3-mini", message: "What is 15 * 17? Think step by step." })
29
+ ```
30
+
31
+ ## Response Fields
32
+
33
+ The `debug_call` command returns:
34
+ - `content` - The response text
35
+ - `reasoning` - Extracted reasoning/thinking content (if available)
36
+ - `reasoningTokens` - Count of reasoning tokens used
37
+ - `history` - Full conversation history
38
+ - `rawResponses` - Raw API responses
39
+ - `usage` - Token usage statistics
@@ -0,0 +1,11 @@
1
+ import { type LlmProvider } from "./llm.js";
2
+ interface LlmInput {
3
+ message?: string;
4
+ model?: string;
5
+ provider?: LlmProvider;
6
+ }
7
+ export declare const llmService: import("@jaypie/fabric").Service<{
8
+ command?: string;
9
+ input?: LlmInput;
10
+ }, string | import("./llm.js").LlmDebugCallResult, string | import("./llm.js").LlmDebugCallResult>;
11
+ export * from "./llm.js";
@@ -0,0 +1,61 @@
1
+ import { fabricService } from '@jaypie/fabric';
2
+ import * as fs from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { debugLlmCall } from './llm.js';
6
+
7
+ /**
8
+ * LLM Suite - Unified LLM debugging and inspection
9
+ */
10
+ const __dirname$1 = path.dirname(fileURLToPath(import.meta.url));
11
+ // Silent logger for direct execution
12
+ const log = {
13
+ error: () => { },
14
+ info: () => { },
15
+ };
16
+ async function getHelp() {
17
+ return fs.readFile(path.join(__dirname$1, "help.md"), "utf-8");
18
+ }
19
+ const llmService = fabricService({
20
+ alias: "llm",
21
+ description: "Debug LLM provider responses. Commands: debug_call. Call with no args for help.",
22
+ input: {
23
+ command: {
24
+ description: "Command to execute (omit for help)",
25
+ required: false,
26
+ type: String,
27
+ },
28
+ input: {
29
+ description: "Command parameters",
30
+ required: false,
31
+ type: Object,
32
+ },
33
+ },
34
+ service: async ({ command, input: params, }) => {
35
+ if (!command || command === "help") {
36
+ return getHelp();
37
+ }
38
+ const p = params || {};
39
+ switch (command) {
40
+ case "debug_call": {
41
+ if (!p.provider)
42
+ throw new Error("provider is required");
43
+ if (!p.message)
44
+ throw new Error("message is required");
45
+ const result = await debugLlmCall({
46
+ message: p.message,
47
+ model: p.model,
48
+ provider: p.provider,
49
+ }, log);
50
+ if (!result.success)
51
+ throw new Error(result.error);
52
+ return result;
53
+ }
54
+ default:
55
+ throw new Error(`Unknown command: ${command}. Use llm() for help.`);
56
+ }
57
+ },
58
+ });
59
+
60
+ export { debugLlmCall, llmService };
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../src/suites/llm/index.ts"],"sourcesContent":["/**\n * LLM Suite - Unified LLM debugging and inspection\n */\nimport { fabricService } from \"@jaypie/fabric\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { debugLlmCall, type LlmProvider } from \"./llm.js\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// Silent logger for direct execution\nconst log = {\n error: () => {},\n info: () => {},\n};\n\nasync function getHelp(): Promise<string> {\n return fs.readFile(path.join(__dirname, \"help.md\"), \"utf-8\");\n}\n\n// Input type for the unified LLM service\ninterface LlmInput {\n message?: string;\n model?: string;\n provider?: LlmProvider;\n}\n\nexport const llmService = fabricService({\n alias: \"llm\",\n description:\n \"Debug LLM provider responses. Commands: debug_call. Call with no args for help.\",\n input: {\n command: {\n description: \"Command to execute (omit for help)\",\n required: false,\n type: String,\n },\n input: {\n description: \"Command parameters\",\n required: false,\n type: Object,\n },\n },\n service: async ({\n command,\n input: params,\n }: {\n command?: string;\n input?: LlmInput;\n }) => {\n if (!command || command === \"help\") {\n return getHelp();\n }\n\n const p = params || {};\n\n switch (command) {\n case \"debug_call\": {\n if (!p.provider) throw new Error(\"provider is required\");\n if (!p.message) throw new Error(\"message is required\");\n const result = await debugLlmCall(\n {\n message: p.message,\n model: p.model,\n provider: p.provider,\n },\n log,\n );\n if (!result.success) throw new Error(result.error);\n return result;\n }\n\n default:\n throw new Error(`Unknown command: ${command}. Use llm() for help.`);\n }\n },\n});\n\n// Re-export types and functions for testing\nexport * from \"./llm.js\";\n"],"names":["__dirname"],"mappings":";;;;;;AAAA;;AAEG;AAQH,MAAMA,WAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE9D;AACA,MAAM,GAAG,GAAG;AACV,IAAA,KAAK,EAAE,MAAK,EAAE,CAAC;AACf,IAAA,IAAI,EAAE,MAAK,EAAE,CAAC;CACf;AAED,eAAe,OAAO,GAAA;AACpB,IAAA,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAACA,WAAS,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC;AAC9D;AASO,MAAM,UAAU,GAAG,aAAa,CAAC;AACtC,IAAA,KAAK,EAAE,KAAK;AACZ,IAAA,WAAW,EACT,iFAAiF;AACnF,IAAA,KAAK,EAAE;AACL,QAAA,OAAO,EAAE;AACP,YAAA,WAAW,EAAE,oCAAoC;AACjD,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACD,QAAA,KAAK,EAAE;AACL,YAAA,WAAW,EAAE,oBAAoB;AACjC,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACF,KAAA;IACD,OAAO,EAAE,OAAO,EACd,OAAO,EACP,KAAK,EAAE,MAAM,GAId,KAAI;AACH,QAAA,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM,EAAE;YAClC,OAAO,OAAO,EAAE;QAClB;AAEA,QAAA,MAAM,CAAC,GAAG,MAAM,IAAI,EAAE;QAEtB,QAAQ,OAAO;YACb,KAAK,YAAY,EAAE;gBACjB,IAAI,CAAC,CAAC,CAAC,QAAQ;AAAE,oBAAA,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC;gBACxD,IAAI,CAAC,CAAC,CAAC,OAAO;AAAE,oBAAA,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC;AACtD,gBAAA,MAAM,MAAM,GAAG,MAAM,YAAY,CAC/B;oBACE,OAAO,EAAE,CAAC,CAAC,OAAO;oBAClB,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;iBACrB,EACD,GAAG,CACJ;gBACD,IAAI,CAAC,MAAM,CAAC,OAAO;AAAE,oBAAA,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;AAClD,gBAAA,OAAO,MAAM;YACf;AAEA,YAAA;AACE,gBAAA,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,CAAA,qBAAA,CAAuB,CAAC;;IAEzE,CAAC;AACF,CAAA;;;;"}
@@ -23,19 +23,8 @@ interface Logger {
23
23
  info: (message: string, ...args: unknown[]) => void;
24
24
  error: (message: string, ...args: unknown[]) => void;
25
25
  }
26
- export declare const REASONING_MODELS: Record<string, string>;
27
26
  /**
28
27
  * Make a debug LLM call and return the raw response data for inspection
29
28
  */
30
29
  export declare function debugLlmCall(params: LlmDebugCallParams, log: Logger): Promise<LlmDebugCallResult>;
31
- /**
32
- * List available providers and their default/reasoning models
33
- */
34
- export declare function listLlmProviders(): {
35
- providers: Array<{
36
- name: LlmProvider;
37
- defaultModel: string;
38
- reasoningModels: string[];
39
- }>;
40
- };
41
30
  export {};
@@ -0,0 +1,61 @@
1
+ import { LLM, Llm } from '@jaypie/llm';
2
+
3
+ /**
4
+ * LLM debugging utilities for inspecting raw provider responses
5
+ */
6
+ // Default models for each provider
7
+ const DEFAULT_MODELS = {
8
+ anthropic: LLM.PROVIDER.ANTHROPIC.MODEL.SMALL,
9
+ gemini: LLM.PROVIDER.GEMINI.MODEL.SMALL,
10
+ openai: LLM.PROVIDER.OPENAI.MODEL.SMALL,
11
+ openrouter: LLM.PROVIDER.OPENROUTER.MODEL.SMALL,
12
+ };
13
+ /**
14
+ * Make a debug LLM call and return the raw response data for inspection
15
+ */
16
+ async function debugLlmCall(params, log) {
17
+ const { provider, message } = params;
18
+ const model = params.model || DEFAULT_MODELS[provider];
19
+ log.info(`Making debug LLM call to ${provider} with model ${model}`);
20
+ try {
21
+ const llm = new Llm(provider, { model });
22
+ const result = await llm.operate(message, {
23
+ user: "[jaypie-mcp] Debug LLM Call",
24
+ });
25
+ if (result.error) {
26
+ return {
27
+ success: false,
28
+ provider,
29
+ model,
30
+ error: `${result.error.title}: ${result.error.detail || "Unknown error"}`,
31
+ };
32
+ }
33
+ // Calculate total reasoning tokens
34
+ const reasoningTokens = result.usage.reduce((sum, u) => sum + (u.reasoning || 0), 0);
35
+ return {
36
+ success: true,
37
+ provider,
38
+ model,
39
+ content: typeof result.content === "string"
40
+ ? result.content
41
+ : JSON.stringify(result.content),
42
+ reasoning: result.reasoning,
43
+ reasoningTokens,
44
+ history: result.history,
45
+ rawResponses: result.responses,
46
+ usage: result.usage,
47
+ };
48
+ }
49
+ catch (error) {
50
+ log.error(`Error calling ${provider}:`, error);
51
+ return {
52
+ success: false,
53
+ provider,
54
+ model,
55
+ error: error instanceof Error ? error.message : String(error),
56
+ };
57
+ }
58
+ }
59
+
60
+ export { debugLlmCall };
61
+ //# sourceMappingURL=llm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.js","sources":["../../../src/suites/llm/llm.ts"],"sourcesContent":["/**\n * LLM debugging utilities for inspecting raw provider responses\n */\n\nimport { LLM, Llm } from \"@jaypie/llm\";\n\nexport type LlmProvider = \"anthropic\" | \"gemini\" | \"openai\" | \"openrouter\";\n\nexport interface LlmDebugCallParams {\n provider: LlmProvider;\n model?: string;\n message: string;\n}\n\nexport interface LlmDebugCallResult {\n success: boolean;\n provider: string;\n model: string;\n content?: string;\n reasoning?: string[];\n reasoningTokens?: number;\n history?: unknown[];\n rawResponses?: unknown[];\n usage?: unknown[];\n error?: string;\n}\n\ninterface Logger {\n info: (message: string, ...args: unknown[]) => void;\n error: (message: string, ...args: unknown[]) => void;\n}\n\n// Default models for each provider\nconst DEFAULT_MODELS: Record<LlmProvider, string> = {\n anthropic: LLM.PROVIDER.ANTHROPIC.MODEL.SMALL,\n gemini: LLM.PROVIDER.GEMINI.MODEL.SMALL,\n openai: LLM.PROVIDER.OPENAI.MODEL.SMALL,\n openrouter: LLM.PROVIDER.OPENROUTER.MODEL.SMALL,\n};\n\n/**\n * Make a debug LLM call and return the raw response data for inspection\n */\nexport async function debugLlmCall(\n params: LlmDebugCallParams,\n log: Logger,\n): Promise<LlmDebugCallResult> {\n const { provider, message } = params;\n const model = params.model || DEFAULT_MODELS[provider];\n\n log.info(`Making debug LLM call to ${provider} with model ${model}`);\n\n try {\n const llm = new Llm(provider, { model });\n\n const result = await llm.operate(message, {\n user: \"[jaypie-mcp] Debug LLM Call\",\n });\n\n if (result.error) {\n return {\n success: false,\n provider,\n model,\n error: `${result.error.title}: ${result.error.detail || \"Unknown error\"}`,\n };\n }\n\n // Calculate total reasoning tokens\n const reasoningTokens = result.usage.reduce(\n (sum, u) => sum + (u.reasoning || 0),\n 0,\n );\n\n return {\n success: true,\n provider,\n model,\n content:\n typeof result.content === \"string\"\n ? result.content\n : JSON.stringify(result.content),\n reasoning: result.reasoning,\n reasoningTokens,\n history: result.history,\n rawResponses: result.responses,\n usage: result.usage,\n };\n } catch (error) {\n log.error(`Error calling ${provider}:`, error);\n return {\n success: false,\n provider,\n model,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n"],"names":[],"mappings":";;AAAA;;AAEG;AA8BH;AACA,MAAM,cAAc,GAAgC;IAClD,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK;IAC7C,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK;IACvC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK;IACvC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK;CAChD;AAED;;AAEG;AACI,eAAe,YAAY,CAChC,MAA0B,EAC1B,GAAW,EAAA;AAEX,IAAA,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,cAAc,CAAC,QAAQ,CAAC;IAEtD,GAAG,CAAC,IAAI,CAAC,CAAA,yBAAA,EAA4B,QAAQ,CAAA,YAAA,EAAe,KAAK,CAAA,CAAE,CAAC;AAEpE,IAAA,IAAI;QACF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE;AACxC,YAAA,IAAI,EAAE,6BAA6B;AACpC,SAAA,CAAC;AAEF,QAAA,IAAI,MAAM,CAAC,KAAK,EAAE;YAChB,OAAO;AACL,gBAAA,OAAO,EAAE,KAAK;gBACd,QAAQ;gBACR,KAAK;AACL,gBAAA,KAAK,EAAE,CAAA,EAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAA,EAAA,EAAK,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,eAAe,CAAA,CAAE;aAC1E;QACH;;QAGA,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CACzC,CAAC,GAAG,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,EACpC,CAAC,CACF;QAED,OAAO;AACL,YAAA,OAAO,EAAE,IAAI;YACb,QAAQ;YACR,KAAK;AACL,YAAA,OAAO,EACL,OAAO,MAAM,CAAC,OAAO,KAAK;kBACtB,MAAM,CAAC;kBACP,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;YACpC,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,eAAe;YACf,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,YAAY,EAAE,MAAM,CAAC,SAAS;YAC9B,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB;IACH;IAAE,OAAO,KAAK,EAAE;QACd,GAAG,CAAC,KAAK,CAAC,CAAA,cAAA,EAAiB,QAAQ,CAAA,CAAA,CAAG,EAAE,KAAK,CAAC;QAC9C,OAAO;AACL,YAAA,OAAO,EAAE,KAAK;YACd,QAAQ;YACR,KAAK;AACL,YAAA,KAAK,EAAE,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;SAC9D;IACH;AACF;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaypie/mcp",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "Jaypie MCP",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,8 +39,8 @@
39
39
  "typecheck": "tsc --noEmit"
40
40
  },
41
41
  "dependencies": {
42
- "@jaypie/fabric": "^0.1.0",
43
- "@jaypie/llm": "^1.2.2",
42
+ "@jaypie/fabric": "*",
43
+ "@jaypie/llm": "*",
44
44
  "@modelcontextprotocol/sdk": "^1.17.0",
45
45
  "commander": "^14.0.0",
46
46
  "gray-matter": "^4.0.3",
@@ -54,6 +54,7 @@
54
54
  "@types/semver": "^7.7.1",
55
55
  "express": "^5.1.0",
56
56
  "rollup": "^4.53.3",
57
+ "rollup-plugin-copy": "^3.5.0",
57
58
  "typescript": "^5.9.3"
58
59
  },
59
60
  "publishConfig": {
@@ -0,0 +1,18 @@
1
+ ---
2
+ version: 1.2.5
3
+ date: 2025-01-23
4
+ summary: Add WebSocket connection management utilities
5
+ ---
6
+
7
+ ## New Features
8
+
9
+ ### WebSocket Utilities
10
+
11
+ - **`sendToConnection(data, { connectionId, domainName, stage })`** - Send data to a WebSocket connection
12
+ - **`broadcastToConnections(data, { connectionIds, domainName, stage })`** - Broadcast data to multiple connections
13
+
14
+ Both functions use the ApiGatewayManagementApi client and handle stale connection errors gracefully.
15
+
16
+ ## Dependencies
17
+
18
+ - Added `@aws-sdk/client-apigatewaymanagementapi`
@@ -0,0 +1,35 @@
1
+ ---
2
+ version: 1.2.19
3
+ date: 2025-01-23
4
+ summary: Add WebSocket API Gateway constructs
5
+ ---
6
+
7
+ ## New Constructs
8
+
9
+ ### JaypieWebSocket
10
+
11
+ WebSocket API using AWS API Gateway v2 with custom domain support:
12
+
13
+ ```typescript
14
+ const ws = new JaypieWebSocket(this, "Chat", {
15
+ host: "ws.example.com",
16
+ connect: connectLambda,
17
+ disconnect: disconnectLambda,
18
+ default: messageLambda,
19
+ routes: { sendMessage: sendMessageLambda },
20
+ });
21
+ ```
22
+
23
+ ### JaypieWebSocketLambda
24
+
25
+ Convenience Lambda construct for WebSocket handlers with appropriate defaults.
26
+
27
+ ### JaypieWebSocketTable
28
+
29
+ Optional DynamoDB table for connection tracking with TTL support:
30
+
31
+ ```typescript
32
+ const table = new JaypieWebSocketTable(this, "Connections", {
33
+ ttl: Duration.hours(24),
34
+ });
35
+ ```
@@ -0,0 +1,44 @@
1
+ ---
2
+ version: 0.4.0
3
+ date: 2026-01-22
4
+ summary: Rename class to category for consistency with @jaypie/fabric
5
+ ---
6
+
7
+ # @jaypie/dynamodb 0.4.0
8
+
9
+ ## Breaking Changes
10
+
11
+ Renamed `class` to `category` throughout the package to align with `@jaypie/fabric` vocabulary:
12
+
13
+ ### Constants
14
+ - `INDEX_CLASS` → `INDEX_CATEGORY`
15
+
16
+ ### Functions
17
+ - `buildIndexClass()` → `buildIndexCategory()`
18
+ - `queryByClass()` → `queryByCategory()`
19
+
20
+ ### Types
21
+ - `QueryByClassParams` → `QueryByCategoryParams`
22
+ - `recordClass` parameter → `category` parameter
23
+ - `indexClass` field → `indexCategory` field on `StorableEntity`
24
+
25
+ ### MCP Tools
26
+ - `dynamodb_query_class` tool → `dynamodb_query_category` tool
27
+
28
+ ## Migration
29
+
30
+ Update your code to use the new names:
31
+
32
+ ```typescript
33
+ // Before
34
+ import { INDEX_CLASS, buildIndexClass, queryByClass } from "@jaypie/dynamodb";
35
+
36
+ const key = buildIndexClass(scope, model, recordClass);
37
+ const result = await queryByClass({ model, scope, recordClass: "memory" });
38
+
39
+ // After
40
+ import { INDEX_CATEGORY, buildIndexCategory, queryByCategory } from "@jaypie/dynamodb";
41
+
42
+ const key = buildIndexCategory(scope, model, category);
43
+ const result = await queryByCategory({ model, scope, category: "memory" });
44
+ ```