@jaypie/mcp 0.8.73 → 0.8.75

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.
@@ -9,7 +9,7 @@ import { gt } from 'semver';
9
9
  /**
10
10
  * Docs Suite - Documentation services (skill, version, release_notes)
11
11
  */
12
- const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.73#8addc2dd"
12
+ const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.75#7dfeb98d"
13
13
  ;
14
14
  const __filename$1 = fileURLToPath(import.meta.url);
15
15
  const __dirname$1 = path.dirname(__filename$1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaypie/mcp",
3
- "version": "0.8.73",
3
+ "version": "0.8.75",
4
4
  "description": "Jaypie MCP",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,14 @@
1
+ ---
2
+ version: 1.2.65
3
+ date: 2026-06-18
4
+ summary: Stabilize JaypieEnvSecret cross-stack export name across both call forms
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - `JaypieEnvSecret` now always derives its CloudFormation cross-stack export name from the construct id, for both the shorthand and explicit `(id, { envKey })` call forms.
10
+ - Previously the explicit form derived the export name from `envKey`, silently renaming the export across a version bump and breaking existing `Fn::ImportValue` consumers (e.g. `env-sandbox-agents-AgentsInternalKey` became `env-sandbox-agents-AGENTSINTERNALKEY`).
11
+
12
+ ## Migration
13
+
14
+ No changes required. Unchanged explicit-form call sites now keep their original id-based export name, restoring compatibility with previously published exports (issues #347, #365).
@@ -0,0 +1,18 @@
1
+ ---
2
+ version: 1.2.3
3
+ date: 2026-06-17
4
+ summary: add loadDatadogApiKey to populate DD_API_KEY from DD_API_KEY_SECRET_ARN when LLM Observability is enabled
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - New `loadDatadogApiKey()` export. When `DD_LLMOBS_ENABLED` is truthy (anything but `false`/`0`), `DD_API_KEY_SECRET_ARN` is set, and neither `DD_API_KEY` nor `DATADOG_API_KEY` is present, it fetches the secret at the ARN and sets `process.env.DD_API_KEY`. Otherwise it is a no-op.
10
+ - `DATADOG.ENV` gains `DD_API_KEY` and `DD_LLMOBS_ENABLED` constants.
11
+
12
+ ## Motivation
13
+
14
+ dd-trace LLM Observability authenticates with `DD_API_KEY`. On Lambda the key is typically only available as a Secrets Manager ARN (`DD_API_KEY_SECRET_ARN`). This helper resolves the secret into the environment so LLM Observability spans can be submitted without manual wiring.
15
+
16
+ ## Migration
17
+
18
+ No changes required. `loadDatadogApiKey()` is invoked automatically by `@jaypie/lambda` (`lambdaHandler`, `lambdaStreamHandler`) and `@jaypie/express` (`expressHandler`) before the handler runs.
@@ -0,0 +1,19 @@
1
+ ---
2
+ version: 1.2.4
3
+ date: 2026-06-18
4
+ summary: Add bundler-safe flushLlmObs(), getLlmObs(), and isLlmObsEnabled()
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - `flushLlmObs()` — flush buffered LLM Observability spans via the runtime `dd-trace` singleton. No-op unless `DD_LLMOBS_ENABLED` is truthy or when `dd-trace` is absent; wrapped so it never throws.
10
+ - `getLlmObs()` — lazy, bundler-safe accessor for the runtime `tracer.llmobs` SDK, or `null` when `dd-trace` cannot be resolved. For manual enclosing spans, annotations, and `submitEvaluation`.
11
+ - `isLlmObsEnabled()` — `true` when `DD_LLMOBS_ENABLED` is truthy (anything but `false`/`0`).
12
+
13
+ ## Notes
14
+
15
+ `dd-trace` is resolved at runtime via a computed module specifier, so bundlers (esbuild/rollup) leave it external and the layer-initialized singleton is used — never a bundled copy whose buffer would never ship.
16
+
17
+ ## Migration
18
+
19
+ No changes required. New exports are additive.
@@ -0,0 +1,17 @@
1
+ ---
2
+ version: 1.2.24
3
+ date: 2026-06-17
4
+ summary: load Datadog LLM Observability API key into the environment before the handler runs
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - `expressHandler` now calls `loadDatadogApiKey()` (from `@jaypie/datadog`) as the first request setup step.
10
+
11
+ ## Motivation
12
+
13
+ When `DD_LLMOBS_ENABLED` is set but only `DD_API_KEY_SECRET_ARN` is available, dd-trace LLM Observability cannot authenticate. Resolving the secret into `DD_API_KEY` before the handler runs lets LLM Observability spans emit without per-handler wiring.
14
+
15
+ ## Migration
16
+
17
+ No changes required. The step is a no-op unless `DD_LLMOBS_ENABLED` is truthy, `DD_API_KEY_SECRET_ARN` is set, and neither `DD_API_KEY` nor `DATADOG_API_KEY` is already present.
@@ -0,0 +1,18 @@
1
+ ---
2
+ version: 1.2.25
3
+ date: 2026-06-18
4
+ summary: Auto-flush LLM Observability spans in the Lambda adapters
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - `createLambdaHandler` and `createLambdaStreamHandler` call `flushLlmObs()` from `@jaypie/datadog` in their `finally` block.
10
+ - Buffered Datadog LLM Obs spans flush before the Lambda freezes — even when the Express app errors.
11
+
12
+ ## Notes
13
+
14
+ No-op unless `DD_LLMOBS_ENABLED` is truthy; never affects the response. No per-handler flush code is required.
15
+
16
+ ## Migration
17
+
18
+ No changes required.
@@ -0,0 +1,14 @@
1
+ ---
2
+ version: 1.2.53
3
+ date: 2026-06-18
4
+ summary: pull in @jaypie/datadog, @jaypie/express, and @jaypie/lambda with Datadog LLM Observability API key loading
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - Bumps `@jaypie/datadog` (1.2.3), `@jaypie/express` (1.2.24), and `@jaypie/lambda` (1.2.9).
10
+ - Handlers now resolve `DD_API_KEY` from `DD_API_KEY_SECRET_ARN` before running when LLM Observability is enabled.
11
+
12
+ ## Migration
13
+
14
+ No changes required. The new step is a no-op unless `DD_LLMOBS_ENABLED` is truthy, `DD_API_KEY_SECRET_ARN` is set, and neither `DD_API_KEY` nor `DATADOG_API_KEY` is already present.
@@ -0,0 +1,14 @@
1
+ ---
2
+ version: 1.2.54
3
+ date: 2026-06-18
4
+ summary: Pull updated datadog, express, lambda, and logger subpackages
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - Bumps `@jaypie/datadog` (`^1.2.4`), `@jaypie/express` (`^1.2.25`), `@jaypie/lambda` (`^1.2.10`), and `@jaypie/logger` (`^1.2.17`).
10
+ - Surfaces the new `flushLlmObs`, `getLlmObs`, and `isLlmObsEnabled` exports (re-exported from `@jaypie/datadog`) and LLM Observability auto-flush in the Lambda/Express handlers.
11
+
12
+ ## Migration
13
+
14
+ No changes required.
@@ -0,0 +1,18 @@
1
+ ---
2
+ version: 1.2.10
3
+ date: 2026-06-18
4
+ summary: Auto-flush LLM Observability spans in handler teardown
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - `lambdaHandler` and `lambdaStreamHandler` append a final teardown step that calls `flushLlmObs()` from `@jaypie/datadog`.
10
+ - Runs after user teardown and always (jaypieHandler runs teardown in a `finally`), so buffered LLM Obs spans flush before the Lambda freezes — even when the handler throws.
11
+
12
+ ## Notes
13
+
14
+ No-op unless `DD_LLMOBS_ENABLED` is truthy; a flush failure never affects the handler response. No per-handler flush code is required.
15
+
16
+ ## Migration
17
+
18
+ No changes required.
@@ -0,0 +1,18 @@
1
+ ---
2
+ version: 1.2.9
3
+ date: 2026-06-17
4
+ summary: load Datadog LLM Observability API key into the environment before the handler runs
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - `lambdaHandler` and `lambdaStreamHandler` now call `loadDatadogApiKey()` (from `@jaypie/datadog`) as the first setup step.
10
+ - Adds `@jaypie/datadog` as a peer dependency.
11
+
12
+ ## Motivation
13
+
14
+ When `DD_LLMOBS_ENABLED` is set but only `DD_API_KEY_SECRET_ARN` is available, dd-trace LLM Observability cannot authenticate. Resolving the secret into `DD_API_KEY` before the handler runs lets LLM Observability spans emit without per-handler wiring.
15
+
16
+ ## Migration
17
+
18
+ No changes required. The step is a no-op unless `DD_LLMOBS_ENABLED` is truthy, `DD_API_KEY_SECRET_ARN` is set, and neither `DD_API_KEY` nor `DATADOG_API_KEY` is already present.
@@ -0,0 +1,18 @@
1
+ ---
2
+ version: 1.2.41
3
+ date: 2026-06-18
4
+ summary: operate() backfills declared array fields in structured output
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - A declared `format` is treated as a schema contract: every array field declared in `format` is now present in `content` as an array. An empty list surfaces as `[]` rather than being dropped (`undefined`/absent), so `content.someArray.length` is safe across all providers.
10
+ - New util `fillFormatArrays` walks the schema (NaturalSchema, Zod, or JSON Schema) and recurses into nested objects and arrays of objects.
11
+
12
+ ## Notes
13
+
14
+ The shipped npm `1.3.0` predates the Datadog LLM Observability emission feature and contains no `dd-trace` code — a `^1.2` range resolves to `1.3.0` and silently loses emission. Pin to a feature-bearing `latest` 1.2.x until a release above `1.3.0` ships.
15
+
16
+ ## Migration
17
+
18
+ No changes required. Consumers that defensively normalized missing array fields to `[]` can drop that workaround.
@@ -0,0 +1,13 @@
1
+ ---
2
+ version: 1.3.1
3
+ date: 2026-06-18
4
+ summary: Version step to 1.3.1 to avoid conflict with an accidental 1.3.0
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - No functional changes. Version advances directly from `1.2.41` to `1.3.1` to step over an accidental `1.3.0` and prevent ongoing version conflicts.
10
+
11
+ ## Migration
12
+
13
+ No changes required.
@@ -0,0 +1,18 @@
1
+ ---
2
+ version: 1.2.17
3
+ date: 2026-06-18
4
+ summary: Add log.flag() for conditional child loggers tagged with a flag
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - Added `log.flag(flag?)` to `JaypieLogger`
10
+ - For a non-empty string, returns a child logger tagged `{ flag }` (via `with`)
11
+ - For `undefined`, a non-string, or an empty string, returns the same logger unchanged
12
+
13
+ ## Usage
14
+
15
+ ```typescript
16
+ log.flag("beta").info("Behind a flag"); // tags { flag: "beta" }
17
+ log.flag(maybeFlag).info("Always logs"); // no-op tag when maybeFlag is falsy/non-string
18
+ ```
@@ -0,0 +1,15 @@
1
+ ---
2
+ version: 0.8.74
3
+ date: 2026-06-18
4
+ summary: Document LLM Observability flush primitives and handler auto-flush
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - `datadog` skill: document `flushLlmObs()`, `getLlmObs()`, and `isLlmObsEnabled()`.
10
+ - `lambda` and `express` skills: document automatic LLM Obs flush in handler teardown.
11
+ - `llm` skill: add an Availability note (npm `1.3.0` predates LLM Obs emission) and Lambda flush guidance.
12
+
13
+ ## Migration
14
+
15
+ No changes required.
@@ -0,0 +1,13 @@
1
+ ---
2
+ version: 0.8.75
3
+ date: 2026-06-18
4
+ summary: Document JaypieMigration in the cdk skill
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - `cdk` skill: add a Database Migrations section covering `JaypieMigration` and link to `skill("migrations")`.
10
+
11
+ ## Migration
12
+
13
+ No changes required.
@@ -0,0 +1,17 @@
1
+ ---
2
+ version: 1.2.43
3
+ date: 2026-06-17
4
+ summary: mock loadDatadogApiKey from @jaypie/datadog
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - Adds a mock for `loadDatadogApiKey` (resolves to `false`) to the Datadog mock module.
10
+
11
+ ## Motivation
12
+
13
+ Keeps testkit's mock surface in sync with the new `@jaypie/datadog` export so tests that mock `jaypie`/`@jaypie/datadog` resolve `loadDatadogApiKey`.
14
+
15
+ ## Migration
16
+
17
+ No changes required.
@@ -0,0 +1,18 @@
1
+ ---
2
+ version: 1.2.44
3
+ date: 2026-06-18
4
+ summary: Add flag to the log mock surface
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - Adds `flag` to the log mock (`mockLogFactory`), returning the mock for chaining like `with`/`lib`.
10
+ - Adds `flag` to the spy/restore method list and the `LogMock` type.
11
+
12
+ ## Motivation
13
+
14
+ Keeps testkit's log mock in sync with the new `log.flag()` method in `@jaypie/logger`.
15
+
16
+ ## Migration
17
+
18
+ No changes required.
package/skills/cdk.md CHANGED
@@ -237,6 +237,27 @@ new JaypieLambda(this, "Handler", {
237
237
 
238
238
  See `skill("dynamodb")` for table key conventions and query patterns.
239
239
 
240
+ ## Database Migrations
241
+
242
+ `JaypieMigration` runs DynamoDB migrations as a CloudFormation custom resource on every `cdk deploy`. It wraps a `JaypieLambda` in a `cr.Provider` and re-fires on the deploy nonce, so newly added migrations run on code-only deploys instead of being skipped:
243
+
244
+ ```typescript
245
+ import { JaypieDynamoDb, JaypieMigration } from "@jaypie/constructs";
246
+
247
+ const table = new JaypieDynamoDb(this, "myApp");
248
+
249
+ new JaypieMigration(this, "SeedData", {
250
+ code: "dist/migrations/seed",
251
+ handler: "index.handler",
252
+ tables: [table],
253
+ dependencies: [table], // Ensures the table exists first
254
+ });
255
+ ```
256
+
257
+ Use `migrationHandler` from `jaypie` in the migration Lambda so errors propagate as CloudFormation failures. Prefer this construct over a hand-rolled `cr.Provider` + `cdk.CustomResource`, which is easy to key on the table name alone and thereby skip the deploy-nonce re-fire.
258
+
259
+ See `skill("migrations")` for the full props table, behavior, and handler pattern.
260
+
240
261
  ## Lambda with Secrets
241
262
 
242
263
  Pass secrets as strings (auto-creates `JaypieEnvSecret`) or as construct instances:
@@ -390,6 +411,7 @@ new JaypieOrganizationTrail(this, "OrgTrail", {
390
411
  - **`skill("dynamodb")`** - DynamoDB key design and query patterns
391
412
  - **`skill("express")`** - Express handler and Lambda adapter
392
413
  - **`skill("lambda")`** - Lambda handler wrappers and lifecycle
414
+ - **`skill("migrations")`** - JaypieMigration DynamoDB migration custom resources
393
415
  - **`skill("secrets")`** - Secret management with JaypieEnvSecret
394
416
  - **`skill("streaming")`** - JaypieDistribution and JaypieNextJs streaming configuration
395
417
  - **`skill("variables")`** - Environment variables reference
package/skills/datadog.md CHANGED
@@ -101,6 +101,30 @@ await datadogEvent({
101
101
  });
102
102
  ```
103
103
 
104
+ ### LLM Observability primitives
105
+
106
+ Bundler-safe access to the runtime `dd-trace` LLM Obs singleton. `dd-trace` is resolved at runtime via a computed module specifier (never bundled), so on Lambda these reach the layer-initialized singleton — a bundled copy would be a different instance whose buffer never ships.
107
+
108
+ ```typescript
109
+ import { flushLlmObs, getLlmObs, isLlmObsEnabled } from "@jaypie/datadog";
110
+
111
+ isLlmObsEnabled(); // true when DD_LLMOBS_ENABLED is truthy (not "false"/"0")
112
+
113
+ // Manual span / annotation / submitEvaluation against the runtime SDK
114
+ getLlmObs()?.trace({ kind: "workflow", name: "my-job" }, async () => {
115
+ /* ... */
116
+ });
117
+
118
+ // Flush before the Lambda freezes — no-op unless enabled; never throws
119
+ flushLlmObs();
120
+ ```
121
+
122
+ | Export | Description |
123
+ |--------|-------------|
124
+ | `flushLlmObs()` | Flush buffered LLM Obs spans. No-op when `DD_LLMOBS_ENABLED` is falsy or `dd-trace` is absent; wrapped so it never throws. Called automatically in `@jaypie/lambda`/`@jaypie/express` handler teardown. |
125
+ | `getLlmObs()` | Lazy accessor for the runtime `tracer.llmobs` SDK, or `null` when `dd-trace` cannot be resolved. For manual enclosing spans, annotations, and `submitEvaluation`. |
126
+ | `isLlmObsEnabled()` | `true` when `DD_LLMOBS_ENABLED` is truthy. |
127
+
104
128
  ## Unified Service Tagging
105
129
 
106
130
  Use consistent tags across services:
package/skills/express.md CHANGED
@@ -104,6 +104,10 @@ import { createLambdaStreamHandler } from "@jaypie/express";
104
104
  export const handler = createLambdaStreamHandler(app);
105
105
  ```
106
106
 
107
+ ### LLM Observability auto-flush
108
+
109
+ `createLambdaHandler` and `createLambdaStreamHandler` call `flushLlmObs()` from `@jaypie/datadog` in their `finally` block, so buffered Datadog LLM Obs spans flush before the Lambda freezes — even when the Express app errors. No-op unless `DD_LLMOBS_ENABLED` is truthy; never affects the response. No per-handler flush code is required.
110
+
107
111
  ## Event Format Support
108
112
 
109
113
  The adapter supports both API Gateway formats:
package/skills/lambda.md CHANGED
@@ -93,12 +93,17 @@ lambdaHandler({ name: "test" }, myFunction);
93
93
  ## Lifecycle Flow
94
94
 
95
95
  1. **Logger initialization** - Re-init logger, tag with `invoke` and `handler`
96
- 2. **Secrets loading** - If `secrets` provided, load via `loadEnvSecrets`
97
- 3. **Validate** - Run validation functions
98
- 4. **Setup** - Run setup functions
99
- 5. **Handler** - Execute main handler logic
100
- 6. **Teardown** - Run teardown functions (always runs)
101
- 7. **Response** - Return result or error body
96
+ 2. **Datadog LLM Observability** - `loadDatadogApiKey()` resolves `DD_API_KEY` from the secret ARN when LLM Obs is enabled (no-op otherwise)
97
+ 3. **Secrets loading** - If `secrets` provided, load via `loadEnvSecrets`
98
+ 4. **Validate** - Run validation functions
99
+ 5. **Setup** - Run setup functions
100
+ 6. **Handler** - Execute main handler logic
101
+ 7. **Teardown** - Run teardown functions, then auto-flush LLM Obs spans (always runs)
102
+ 8. **Response** - Return result or error body
103
+
104
+ ### LLM Observability auto-flush
105
+
106
+ `lambdaHandler` and `lambdaStreamHandler` append a final teardown step that calls `flushLlmObs()` from `@jaypie/datadog`. It runs **after** user teardown and **always** (jaypieHandler runs teardown in a `finally`), so buffered LLM Obs spans flush before the Lambda freezes even when the handler throws. No-op unless `DD_LLMOBS_ENABLED` is truthy; never affects the response. No per-handler flush code is required.
102
107
 
103
108
  ## Error Handling
104
109
 
package/skills/llm.md CHANGED
@@ -182,6 +182,22 @@ const result = await Llm.operate("Extract contact info from: John Doe, john@exam
182
182
  // result.content = { name: "John Doe", email: "john@example.com", phone: "555-1234" }
183
183
  ```
184
184
 
185
+ #### Declared arrays always present
186
+
187
+ A declared `format` is a schema contract. `operate()` guarantees every array field declared in `format` is present in `content` as an array — an empty list surfaces as `[]`, never `undefined` or a dropped key. This holds across providers/models, including those that omit empty array fields, so `content.someArray.length` is always safe without defensive normalization. The backfill recurses into nested objects and arrays of objects.
188
+
189
+ ```typescript
190
+ const res = await Llm.operate(message, {
191
+ format: {
192
+ "Merchant Request": String,
193
+ "Merchant Attachments": [String],
194
+ "Recommended Actions": [String],
195
+ },
196
+ });
197
+ // Even when the model returns no recommendations:
198
+ // res.content["Recommended Actions"] === [] (never undefined)
199
+ ```
200
+
185
201
  ### Zod Schema
186
202
 
187
203
  ```typescript
@@ -358,6 +374,28 @@ Behavior:
358
374
 
359
375
  For esbuild-bundled Lambda handlers that also want dd-trace auto-instrumentation, wire the `dd-trace/esbuild` plugin with `keepNames: true`; the spans above do not require it.
360
376
 
377
+ ### Availability
378
+
379
+ Span emission ships in the **`@jaypie/llm` 1.2.x line** (current `latest`). Note that the `1.3.0` build published to npm predates this feature and contains **no** LLM Obs code — a `^1.2` range resolves to `1.3.0` and silently loses emission. Until a release **above** `1.3.0` ships with the feature, pin to a `latest` 1.2.x that includes it (grep the installed dist for `llmobs` to confirm).
380
+
381
+ ### Flushing on Lambda
382
+
383
+ On Lambda the runtime freezes the instant the handler resolves, so buffered LLM Obs spans are dropped unless flushed first. Jaypie handler wrappers flush automatically in teardown — no per-handler code:
384
+
385
+ - `@jaypie/lambda` — `lambdaHandler`, `lambdaStreamHandler`
386
+ - `@jaypie/express` — `createLambdaHandler`, `createLambdaStreamHandler`
387
+
388
+ Outside those wrappers, flush manually before returning with the bundler-safe `flushLlmObs()` from `@jaypie/datadog`; reach the runtime SDK singleton for manual spans/annotations/`submitEvaluation` via `getLlmObs()`.
389
+
390
+ ```typescript
391
+ import { flushLlmObs, getLlmObs } from "@jaypie/datadog";
392
+
393
+ getLlmObs()?.trace({ kind: "workflow", name: "my-job" }, async () => {
394
+ await Llm.operate(input);
395
+ });
396
+ flushLlmObs(); // no-op unless DD_LLMOBS_ENABLED; never throws
397
+ ```
398
+
361
399
  ## Error Handling
362
400
 
363
401
  The package auto-retries rate limits and transient errors: