@jaypie/mcp 0.8.1 → 0.8.3
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/dist/suites/docs/index.js +1 -1
- package/package.json +1 -1
- package/release-notes/express/1.2.17.md +12 -0
- package/release-notes/jaypie/1.2.25.md +10 -0
- package/release-notes/logger/1.2.6.md +10 -0
- package/release-notes/mcp/0.8.2.md +11 -0
- package/release-notes/testkit/1.2.27.md +9 -0
- package/skills/JaypieDatadogForwarder.md +99 -0
- package/skills/express.md +1 -1
- package/skills/logs.md +48 -111
- package/skills/practice.md +35 -2
|
@@ -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.
|
|
12
|
+
const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.3#6f36ab62"
|
|
13
13
|
;
|
|
14
14
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
15
15
|
const __dirname$1 = path.dirname(__filename$1);
|
package/package.json
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.17
|
|
3
|
+
date: 2026-03-26
|
|
4
|
+
summary: Pre-parse request body in LambdaRequest — express.json() no longer required
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- LambdaRequest now eagerly pre-parses the body in the constructor: JSON bodies are parsed automatically, non-JSON bodies are set as strings
|
|
10
|
+
- Sets `_body` flag so body-parser middleware (express.json()) skips if present, preserving the raw stream for consumers like MCP transport
|
|
11
|
+
- `express.json()` middleware is no longer required for JSON body parsing on Lambda
|
|
12
|
+
- Closes #246
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.25
|
|
3
|
+
date: 2026-03-26
|
|
4
|
+
summary: Bump @jaypie/express to 1.2.17 for automatic body parsing
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- Updated `@jaypie/express` dependency to ^1.2.17
|
|
10
|
+
- JSON request bodies are now automatically parsed in Lambda handlers without requiring `express.json()` middleware
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.6
|
|
3
|
+
date: 2026-03-26
|
|
4
|
+
summary: Export getDatadogTransport for clean shutdown in production
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- Export `getDatadogTransport` from `@jaypie/logger` for production use cases like flushing the transport before `process.exit()` in ECS Fargate containers
|
|
10
|
+
- Closes #248
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.8.2
|
|
3
|
+
date: 2026-03-26
|
|
4
|
+
summary: Updated skills documentation for logs, practice, and new JaypieDatadogForwarder
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- Updated `logs` skill with Jaypie logging best practices, log.var usage, and level guidance
|
|
10
|
+
- Updated `practice` skill with scrub documentation and style audit workflows
|
|
11
|
+
- Added `JaypieDatadogForwarder` skill documenting the CDK construct for Datadog log forwarding
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: JaypieDatadogForwarder CDK construct for deploying and importing the Datadog log forwarder
|
|
3
|
+
related: cdk, datadog, aws
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# JaypieDatadogForwarder
|
|
7
|
+
|
|
8
|
+
CDK construct that wraps Datadog's official CloudFormation forwarder template. Deploys a Lambda that forwards logs to Datadog.
|
|
9
|
+
|
|
10
|
+
## Import
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { JaypieDatadogForwarder, resolveDatadogForwarderFunction } from "@jaypie/constructs";
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Creating the Forwarder (Provider Stack)
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
const forwarder = new JaypieDatadogForwarder(this);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Uses environment variables for defaults and automatically exports the Lambda ARN as a CloudFormation output.
|
|
23
|
+
|
|
24
|
+
### Constructor Signatures
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
new JaypieDatadogForwarder(scope);
|
|
28
|
+
new JaypieDatadogForwarder(scope, props);
|
|
29
|
+
new JaypieDatadogForwarder(scope, id, props);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Props
|
|
33
|
+
|
|
34
|
+
| Parameter | Type | Default | Description |
|
|
35
|
+
|-----------|------|---------|-------------|
|
|
36
|
+
| `id` | string | `"DatadogForwarder"` | Construct ID |
|
|
37
|
+
| `datadogApiKey` | string | `CDK_ENV_DATADOG_API_KEY` | Datadog API key |
|
|
38
|
+
| `account` | string | `CDK_ENV_ACCOUNT` | Account identifier for tags |
|
|
39
|
+
| `reservedConcurrency` | string | `"10"` | Lambda reserved concurrency (must be string) |
|
|
40
|
+
| `additionalTags` | string | undefined | Extra Datadog tags (comma-separated) |
|
|
41
|
+
| `service` | string | `"datadog"` | Service tag value |
|
|
42
|
+
| `project` | string | undefined | Project tag value |
|
|
43
|
+
| `enableCloudFormationEvents` | boolean | `true` | EventBridge rule for CF events |
|
|
44
|
+
| `enableRoleExtension` | boolean | `true` | Extend Datadog IAM role permissions |
|
|
45
|
+
| `createOutput` | boolean | `true` | Export forwarder ARN as CfnOutput |
|
|
46
|
+
| `exportName` | string | `"account-datadog-forwarder"` | Export name for cross-stack reference |
|
|
47
|
+
|
|
48
|
+
### Resources Created
|
|
49
|
+
|
|
50
|
+
1. **Nested CloudFormation Stack** — deploys Datadog's official forwarder template
|
|
51
|
+
2. **EventBridge Rule** — forwards CloudFormation events to Datadog (on by default)
|
|
52
|
+
3. **CfnOutput** — exports forwarder Lambda ARN with name `"account-datadog-forwarder"`
|
|
53
|
+
4. **Extended IAM Permissions** — adds `budgets:ViewBudget`, `logs:DescribeLogGroups` to Datadog role (if `CDK_ENV_DATADOG_ROLE_ARN` is set)
|
|
54
|
+
|
|
55
|
+
### Public Properties
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
forwarder.cfnStack // CfnStack — the nested CloudFormation stack
|
|
59
|
+
forwarder.forwarderFunction // IFunction — the Datadog forwarder Lambda
|
|
60
|
+
forwarder.eventsRule // Rule | undefined — EventBridge rule (if enabled)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Importing from Another Stack
|
|
64
|
+
|
|
65
|
+
Use the `resolveDatadogForwarderFunction` helper:
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { resolveDatadogForwarderFunction } from "@jaypie/constructs";
|
|
69
|
+
|
|
70
|
+
const forwarderFunction = resolveDatadogForwarderFunction(this);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This imports the Lambda via `Fn.importValue("account-datadog-forwarder")` and caches per scope (WeakMap), so multiple calls in the same stack return the same reference.
|
|
74
|
+
|
|
75
|
+
### For Log Subscription Filters
|
|
76
|
+
|
|
77
|
+
Use `resolveDatadogLoggingDestination` to get a `LambdaDestination`:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { resolveDatadogLoggingDestination } from "@jaypie/constructs";
|
|
81
|
+
|
|
82
|
+
new SubscriptionFilter(this, "DatadogSubscription", {
|
|
83
|
+
logGroup,
|
|
84
|
+
destination: resolveDatadogLoggingDestination(this),
|
|
85
|
+
filterPattern: FilterPattern.allEvents(),
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Environment Variables
|
|
90
|
+
|
|
91
|
+
| Variable | Purpose |
|
|
92
|
+
|----------|---------|
|
|
93
|
+
| `CDK_ENV_DATADOG_API_KEY` | Default Datadog API key |
|
|
94
|
+
| `CDK_ENV_ACCOUNT` | Default account identifier for tagging |
|
|
95
|
+
| `CDK_ENV_DATADOG_ROLE_ARN` | Optional: Datadog IAM role ARN to extend permissions |
|
|
96
|
+
|
|
97
|
+
## Tags
|
|
98
|
+
|
|
99
|
+
All resources tagged with: `role=monitoring`, `service=datadog`, `vendor=datadog`, and optionally `project`.
|
package/skills/express.md
CHANGED
|
@@ -128,7 +128,7 @@ The Lambda adapter provides Express-compatible request properties:
|
|
|
128
128
|
| `req.path` | URL path without query string |
|
|
129
129
|
| `req.query` | Parsed query parameters (with array support) |
|
|
130
130
|
| `req.headers` | Normalized headers (lowercase keys) |
|
|
131
|
-
| `req.body` |
|
|
131
|
+
| `req.body` | Pre-parsed body (JSON auto-parsed, text as string; no middleware needed) |
|
|
132
132
|
| `req.params` | Route parameters (set by Express router) |
|
|
133
133
|
| `req._lambdaContext` | Original Lambda context |
|
|
134
134
|
| `req._lambdaEvent` | Original Lambda event |
|
package/skills/logs.md
CHANGED
|
@@ -9,6 +9,14 @@ Jaypie provides structured logging for observability.
|
|
|
9
9
|
|
|
10
10
|
## Basic Usage
|
|
11
11
|
|
|
12
|
+
- All logging should use `log` from `jaypie`, custom functions should be eliminated
|
|
13
|
+
- Logging should tell a story as the process unfolds; a non-developer should be able to read and follow
|
|
14
|
+
- `log.trace` the happy path at major checkpoints or junctures where logic forks or errors may be thrown
|
|
15
|
+
- `log.debug` things that should stand out, anything off the happy path that might impact operations later
|
|
16
|
+
- Avoid `log.info`. Reserve info for values that must be recorded such as metrics
|
|
17
|
+
- Use `log.warn` when the problem is unexpected and warrants attention but is recoverable. Use `log.debug` for unusual things that are part of normal operations
|
|
18
|
+
- Use `log.error` when unrecoverable or "really bad." Do not use `log.error` just because an error occurs that is part of normal operations (e.g., 404)
|
|
19
|
+
|
|
12
20
|
```typescript
|
|
13
21
|
import { log } from "jaypie";
|
|
14
22
|
|
|
@@ -17,129 +25,51 @@ log.debug("Debug information");
|
|
|
17
25
|
log.info("Informational message");
|
|
18
26
|
log.warn("Warning message");
|
|
19
27
|
log.error("Error message");
|
|
20
|
-
log.fatal("Fatal error");
|
|
28
|
+
log.fatal("Fatal error"); // only used internally in jaypie
|
|
21
29
|
```
|
|
22
30
|
|
|
23
|
-
##
|
|
24
|
-
|
|
25
|
-
Always include context as the second argument:
|
|
31
|
+
## Logging Data
|
|
26
32
|
|
|
33
|
+
DO NOT use multiple parameters when logging:
|
|
34
|
+
<BAD>
|
|
27
35
|
```typescript
|
|
28
|
-
log.info("
|
|
29
|
-
userId: user.id,
|
|
30
|
-
email: user.email,
|
|
31
|
-
method: "oauth",
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
log.error("Payment failed", {
|
|
35
|
-
orderId: order.id,
|
|
36
|
-
amount: order.total,
|
|
37
|
-
error: error.message,
|
|
38
|
-
});
|
|
36
|
+
log.info("Processing", { id: "my-id" });
|
|
39
37
|
```
|
|
38
|
+
</BAD>
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
| Level | Use For |
|
|
44
|
-
|-------|---------|
|
|
45
|
-
| trace | Very detailed debugging (loops, iterations) |
|
|
46
|
-
| debug | Development debugging |
|
|
47
|
-
| info | Normal operations, business events |
|
|
48
|
-
| warn | Unexpected but handled situations |
|
|
49
|
-
| error | Errors that need attention |
|
|
50
|
-
| fatal | Application cannot continue |
|
|
51
|
-
|
|
52
|
-
## Setting Log Level
|
|
53
|
-
|
|
54
|
-
Via environment variable:
|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
LOG_LEVEL=debug npm run dev
|
|
58
|
-
LOG_LEVEL=trace npm test
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
In production, typically `info` or `warn`.
|
|
62
|
-
|
|
63
|
-
## Request Context
|
|
64
|
-
|
|
65
|
-
Include request identifiers for tracing:
|
|
66
|
-
|
|
40
|
+
Use `log.var` to log single-key objects that parse in Datadog:
|
|
41
|
+
<GOOD>
|
|
67
42
|
```typescript
|
|
68
|
-
log.
|
|
69
|
-
|
|
70
|
-
path: req.path,
|
|
71
|
-
userId: req.user?.id,
|
|
72
|
-
});
|
|
43
|
+
log.trace("Processing", { id: "my-id" });
|
|
44
|
+
log.var({ id: "my-id" });
|
|
73
45
|
```
|
|
46
|
+
</GOOD>
|
|
74
47
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
Log errors with full context:
|
|
78
|
-
|
|
48
|
+
Or have the variable name tell the story:
|
|
49
|
+
<GOOD>
|
|
79
50
|
```typescript
|
|
80
|
-
|
|
81
|
-
await riskyOperation();
|
|
82
|
-
} catch (error) {
|
|
83
|
-
log.error("Operation failed", {
|
|
84
|
-
error: error.message,
|
|
85
|
-
stack: error.stack,
|
|
86
|
-
input: sanitizedInput,
|
|
87
|
-
});
|
|
88
|
-
throw error;
|
|
89
|
-
}
|
|
51
|
+
log.var({ Processing: id });
|
|
90
52
|
```
|
|
53
|
+
</GOOD>
|
|
91
54
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
Never log sensitive data:
|
|
95
|
-
|
|
55
|
+
Nest multi-key objects under a single key:
|
|
96
56
|
```typescript
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
57
|
+
log.var({ Processing: {
|
|
58
|
+
id,
|
|
59
|
+
amount,
|
|
60
|
+
quantity,
|
|
61
|
+
} });
|
|
102
62
|
```
|
|
103
63
|
|
|
104
|
-
|
|
64
|
+
Log any important, even scalar, data and filter with `var` in Datadog
|
|
105
65
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
# Search by requestId
|
|
110
|
-
datadog_logs --query "@requestId:abc-123"
|
|
111
|
-
|
|
112
|
-
# Search errors
|
|
113
|
-
datadog_logs --query "status:error" --from "now-1h"
|
|
114
|
-
|
|
115
|
-
# Search by user
|
|
116
|
-
datadog_logs --query "@userId:user-456"
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### Via MCP (CloudWatch)
|
|
120
|
-
|
|
121
|
-
```
|
|
122
|
-
aws_logs_filter_log_events \
|
|
123
|
-
--logGroupName "/aws/lambda/my-function" \
|
|
124
|
-
--filterPattern "ERROR"
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Log Format
|
|
66
|
+
## Setting Log Level
|
|
128
67
|
|
|
129
|
-
|
|
68
|
+
Via environment variable:
|
|
130
69
|
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
"message": "User logged in",
|
|
135
|
-
"timestamp": "2024-01-15T10:00:00.000Z",
|
|
136
|
-
"userId": "user-123",
|
|
137
|
-
"method": "oauth",
|
|
138
|
-
"dd": {
|
|
139
|
-
"trace_id": "abc123",
|
|
140
|
-
"span_id": "def456"
|
|
141
|
-
}
|
|
142
|
-
}
|
|
70
|
+
```bash
|
|
71
|
+
LOG_LEVEL=debug npm run dev
|
|
72
|
+
LOG_LEVEL=trace MODULE_LOG_LEVEL=warn npm test
|
|
143
73
|
```
|
|
144
74
|
|
|
145
75
|
## Lambda Logging
|
|
@@ -150,17 +80,24 @@ Lambda handlers automatically add context:
|
|
|
150
80
|
import { lambdaHandler } from "@jaypie/lambda";
|
|
151
81
|
|
|
152
82
|
export const handler = lambdaHandler(async (event) => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
// - cold_start indicator
|
|
157
|
-
log.info("Processing", { customField: "value" });
|
|
83
|
+
log.trace("Begin Processing");
|
|
84
|
+
}, {
|
|
85
|
+
name: "exampleHandler"
|
|
158
86
|
});
|
|
159
87
|
```
|
|
160
88
|
|
|
89
|
+
Logs will include the `env`, `invoke`, and `handler` name. For example:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"env": "sandbox",
|
|
94
|
+
"invoke": "uuid",
|
|
95
|
+
"handler": "exampleHandler"
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
161
99
|
## See Also
|
|
162
100
|
|
|
163
101
|
- **`skill("datadog")`** - Datadog integration and log forwarding
|
|
164
102
|
- **`skill("handlers")`** - Handler lifecycle with automatic log context
|
|
165
103
|
- **`skill("variables")`** - LOG_LEVEL and other environment variables
|
|
166
|
-
|
package/skills/practice.md
CHANGED
|
@@ -4,7 +4,40 @@ description: Updates to Jaypie code, deploy, documentation, and other practices
|
|
|
4
4
|
|
|
5
5
|
# Jaypie Practice
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- These are Jaypie practices
|
|
8
|
+
- Confirm any implementation before taking action
|
|
9
|
+
- Do not assume a reference to this skill means to run it all
|
|
10
|
+
|
|
11
|
+
## GitHub Workflow Dispatch Actions
|
|
8
12
|
|
|
9
13
|
- Prefer workflow dispatch actions over branch names and tagging
|
|
10
|
-
- Most work is agent-driven so "deploy to production" is more natural
|
|
14
|
+
- Most work is agent-driven so "deploy to production" is more natural
|
|
15
|
+
|
|
16
|
+
## Logs
|
|
17
|
+
|
|
18
|
+
- Review ~logs and audit logging in the app
|
|
19
|
+
|
|
20
|
+
## Scrub
|
|
21
|
+
|
|
22
|
+
### Scrub Documentation
|
|
23
|
+
|
|
24
|
+
- Use a subagent to find essential directories that do not contain a CLAUDE.md, if any
|
|
25
|
+
- Use a subagent to write a CLAUDE.md for each essential directory without one
|
|
26
|
+
- Parallelize this work except when one essential directory contains another
|
|
27
|
+
- In that case, complete the descendant CLAUDE first
|
|
28
|
+
- Whenever possible, offer a terse overview in the root or ancestor CLAUDE and reference the descendant for detail
|
|
29
|
+
- Find CLAUDE.md file not impacted by the above
|
|
30
|
+
- Use a subagent to update each CLAUDE.md
|
|
31
|
+
- Also parallelize this work except when dealing with ancestor- descendant chains
|
|
32
|
+
- Resolve descendants as described
|
|
33
|
+
- Find all README.md
|
|
34
|
+
- Use a subagent to update each
|
|
35
|
+
- Optimize both CLAUDE and README for agents
|
|
36
|
+
- Use terse, direct language
|
|
37
|
+
- Avoid superlatives, rationalizing the technology, or anything resembling hype/sales
|
|
38
|
+
|
|
39
|
+
### Scrub Style
|
|
40
|
+
|
|
41
|
+
- Do not allow imports from subpackages that are exported from `jaypie`
|
|
42
|
+
- Importing from `@jaypie/express` is not allowed because `jaypie` exports it
|
|
43
|
+
- Importing from `@jaypie/llm` is allowed because `jaypie` does not export it
|