Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.

Commit 248eb69

Browse files
mcp-tool-shopclaude
andcommitted
v1.0.1: shipcheck treatment — SECURITY.md, logo, hint field
- Add SECURITY.md with attack surface analysis and reporting policy - Add hint field to ValidationIssue (Tier 1 error shape compliance) - Add hints to key validation issues (MISSING_ID, MISSING_PATH, EMPTY_KEYWORDS) - Expand README security section with threat model table - Add logo, fix broken image reference - Include SECURITY.md and logo.png in npm package Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0c17996 commit 248eb69

7 files changed

Lines changed: 64 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 1.0.1 — 2026-03-06
4+
5+
- Add `hint` field to `ValidationIssue` (Tier 1 error shape compliance)
6+
- Add hints to key validation issues (MISSING_ID, MISSING_PATH, EMPTY_KEYWORDS)
7+
- Add SECURITY.md with threat model
8+
- Expand README security section with threat model table
9+
- Add logo
10+
- Include SECURITY.md and logo.png in npm package
11+
312
## 1.0.0 — 2026-03-06
413

514
Initial release.

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<p align="center">
2-
<img src="https://raw.githubusercontent.com/mcp-tool-shop-org/brand/main/logos/ai-loadout/readme.png" width="400" alt="ai-loadout">
2+
<img src="logo.png" width="400" alt="ai-loadout">
33
</p>
44

55
<p align="center">
@@ -176,6 +176,17 @@ import type {
176176

177177
This package is a pure data library. It does not access the filesystem, make network requests, or collect telemetry. All I/O is the consumer's responsibility.
178178

179+
### Threat Model
180+
181+
| Threat | Mitigation |
182+
|--------|------------|
183+
| Malformed frontmatter input | `parseFrontmatter()` returns `null` on invalid input — no exceptions, no eval |
184+
| Prototype pollution | Hand-rolled parser uses plain object literals, no `JSON.parse` of untrusted nested structures |
185+
| Index with bad data | `validateIndex()` catches structural issues before they propagate |
186+
| Regex DoS | No user-supplied regex — patterns are matched as plain string lookups |
187+
188+
See [SECURITY.md](SECURITY.md) for the full security policy.
189+
179190
---
180191

181192
Built by [MCP Tool Shop](https://mcp-tool-shop.github.io/)

SECURITY.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Security Policy
2+
3+
## Attack Surface
4+
5+
`@mcptoolshop/ai-loadout` is a **pure data library**. It has:
6+
7+
- **No filesystem access** — does not read or write files
8+
- **No network access** — makes no HTTP requests, opens no sockets
9+
- **No code execution** — no `eval`, `Function()`, or dynamic imports
10+
- **No telemetry** — collects and transmits nothing
11+
- **No native dependencies** — pure TypeScript, zero production deps
12+
13+
All I/O is the consumer's responsibility. This package only transforms data structures in memory.
14+
15+
## Input Validation
16+
17+
The `parseFrontmatter()` function processes untrusted text input. It uses simple string splitting — no YAML parser, no regex-based evaluation, no prototype pollution vectors.
18+
19+
The `validateIndex()` function checks structural integrity of index objects. It does not execute or interpret any field values.
20+
21+
## Supported Versions
22+
23+
| Version | Supported |
24+
|---------|-----------|
25+
| 1.x | Yes |
26+
27+
## Reporting a Vulnerability
28+
29+
If you discover a security issue, please email **64996768+mcp-tool-shop@users.noreply.github.com** with:
30+
31+
- Description of the vulnerability
32+
- Steps to reproduce
33+
- Impact assessment
34+
35+
We will respond within 7 days and aim to release a fix within 14 days for confirmed issues.

logo.png

910 KB
Loading

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@mcptoolshop/ai-loadout",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "Context-aware knowledge router for AI agents. Dispatch table, frontmatter spec, keyword matcher, token estimator.",
55
"type": "module",
66
"main": "dist/index.js",
@@ -21,7 +21,9 @@
2121
"dist",
2222
"README.md",
2323
"CHANGELOG.md",
24-
"LICENSE"
24+
"LICENSE",
25+
"SECURITY.md",
26+
"logo.png"
2527
],
2628
"keywords": [
2729
"ai",

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export interface ValidationIssue {
6565
severity: IssueSeverity;
6666
code: string;
6767
message: string;
68+
hint?: string;
6869
entryId?: string;
6970
}
7071

src/validate.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export function validateIndex(index: LoadoutIndex): ValidationIssue[] {
6060
severity: "error",
6161
code: "MISSING_ID",
6262
message: "Entry is missing an id field",
63+
hint: "Every entry needs a unique kebab-case id",
6364
});
6465
continue;
6566
}
@@ -91,6 +92,7 @@ export function validateIndex(index: LoadoutIndex): ValidationIssue[] {
9192
severity: "error",
9293
code: "MISSING_PATH",
9394
message: `Entry "${entry.id}" has no path`,
95+
hint: "Set path to the relative file location (e.g. .claude/rules/my-rule.md)",
9496
entryId: entry.id,
9597
});
9698
}
@@ -128,6 +130,7 @@ export function validateIndex(index: LoadoutIndex): ValidationIssue[] {
128130
severity: "error",
129131
code: "EMPTY_KEYWORDS",
130132
message: `Domain entry "${entry.id}" has no keywords — cannot be routed`,
133+
hint: "Add keywords to frontmatter so the matcher can find this entry",
131134
entryId: entry.id,
132135
});
133136
}

0 commit comments

Comments
 (0)