aipatterns-mcp-server 1.0.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.
- package/README.md +82 -0
- package/index.d.ts +8 -0
- package/index.js +589 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# aipatterns.com.au MCP Server
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server that exposes the [aipatterns.com.au](https://aipatterns.com.au) pattern library, AU AI incidents, sector benchmarks, and regulatory changes as tools callable by Claude, Cursor, GitHub Copilot, and other MCP-compatible AI assistants.
|
|
4
|
+
|
|
5
|
+
## What it provides
|
|
6
|
+
|
|
7
|
+
| Tool | Description |
|
|
8
|
+
|------|-------------|
|
|
9
|
+
| `search_patterns` | Full-text search across the pattern library (title, description, content) |
|
|
10
|
+
| `get_pattern` | Retrieve full detail + implementation guidance for a specific pattern |
|
|
11
|
+
| `get_incidents` | Notable Australian AI incidents with linked patterns and regulatory outcomes |
|
|
12
|
+
| `get_sector_benchmark` | AU AI Maturity Index scores for banking, insurance, government, retail, healthcare, utilities |
|
|
13
|
+
| `get_regulatory_changes` | APRA CPS 230, OAIC Privacy Act reform, ASIC INFO 183, TGA SaMD, and more |
|
|
14
|
+
|
|
15
|
+
No database connection or network calls are required at runtime — all data is served from the local pattern files and hardcoded seed data.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cd mcp-server
|
|
21
|
+
npm install
|
|
22
|
+
npm run build # compiles index.ts → index.js
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Add to Claude Desktop
|
|
26
|
+
|
|
27
|
+
Edit `~/.config/claude/claude_desktop_config.json` (macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcpServers": {
|
|
32
|
+
"aipatterns": {
|
|
33
|
+
"command": "node",
|
|
34
|
+
"args": ["/absolute/path/to/eaapl-web/mcp-server/index.js"]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Replace `/absolute/path/to/eaapl-web` with the actual path on your machine, then restart Claude Desktop.
|
|
41
|
+
|
|
42
|
+
## Add to Cursor
|
|
43
|
+
|
|
44
|
+
Create or edit `.cursor/mcp.json` in your project root:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"mcpServers": {
|
|
49
|
+
"aipatterns": {
|
|
50
|
+
"command": "node",
|
|
51
|
+
"args": ["/absolute/path/to/eaapl-web/mcp-server/index.js"]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Add to GitHub Copilot (VS Code MCP extension)
|
|
58
|
+
|
|
59
|
+
Add to your VS Code `settings.json`:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"mcp.servers": {
|
|
64
|
+
"aipatterns": {
|
|
65
|
+
"command": "node",
|
|
66
|
+
"args": ["/absolute/path/to/eaapl-web/mcp-server/index.js"],
|
|
67
|
+
"transport": "stdio"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Development
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm run dev # runs via tsx (no build step needed)
|
|
77
|
+
npm run build # compile TS → JS for production use
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Transport
|
|
81
|
+
|
|
82
|
+
stdio — the server reads JSON-RPC from stdin and writes responses to stdout. stderr is used for diagnostic messages only.
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* aipatterns.com.au MCP Server
|
|
3
|
+
* Exposes pattern library, incidents, sector benchmarks, and regulatory changes
|
|
4
|
+
* as tools callable by Claude, Cursor, GitHub Copilot, and other MCP clients.
|
|
5
|
+
*
|
|
6
|
+
* Transport: stdio (no HTTP calls, no DB connection required)
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
package/index.js
ADDED
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* aipatterns.com.au MCP Server
|
|
4
|
+
* Exposes pattern library, incidents, sector benchmarks, and regulatory changes
|
|
5
|
+
* as tools callable by Claude, Cursor, GitHub Copilot, and other MCP clients.
|
|
6
|
+
*
|
|
7
|
+
* Transport: stdio (no HTTP calls, no DB connection required)
|
|
8
|
+
*/
|
|
9
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
10
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
11
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
12
|
+
import { readdir, readFile } from "fs/promises";
|
|
13
|
+
import { join, dirname } from "path";
|
|
14
|
+
import { fileURLToPath } from "url";
|
|
15
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
const PATTERNS_DIR = join(__dirname, "..", "content", "patterns");
|
|
17
|
+
const SECTOR_BENCHMARKS = {
|
|
18
|
+
banking: {
|
|
19
|
+
sector: "banking",
|
|
20
|
+
overall: 57.3,
|
|
21
|
+
adoption: 60.1,
|
|
22
|
+
governance: 57.9,
|
|
23
|
+
investment: 60.6,
|
|
24
|
+
incidents: 48.4,
|
|
25
|
+
rank: 1,
|
|
26
|
+
national_average: {
|
|
27
|
+
overall: 41.8,
|
|
28
|
+
adoption: 40.9,
|
|
29
|
+
governance: 45.5,
|
|
30
|
+
investment: 41.3,
|
|
31
|
+
incidents: 38.9,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
insurance: {
|
|
35
|
+
sector: "insurance",
|
|
36
|
+
overall: 46.7,
|
|
37
|
+
adoption: 48.5,
|
|
38
|
+
governance: 47.0,
|
|
39
|
+
investment: 48.9,
|
|
40
|
+
incidents: 41.1,
|
|
41
|
+
rank: 2,
|
|
42
|
+
national_average: {
|
|
43
|
+
overall: 41.8,
|
|
44
|
+
adoption: 40.9,
|
|
45
|
+
governance: 45.5,
|
|
46
|
+
investment: 41.3,
|
|
47
|
+
incidents: 38.9,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
government: {
|
|
51
|
+
sector: "government",
|
|
52
|
+
overall: 33.5,
|
|
53
|
+
adoption: 25.4,
|
|
54
|
+
governance: 47.9,
|
|
55
|
+
investment: 24.1,
|
|
56
|
+
incidents: 39.3,
|
|
57
|
+
rank: 5,
|
|
58
|
+
national_average: {
|
|
59
|
+
overall: 41.8,
|
|
60
|
+
adoption: 40.9,
|
|
61
|
+
governance: 45.5,
|
|
62
|
+
investment: 41.3,
|
|
63
|
+
incidents: 38.9,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
retail: {
|
|
67
|
+
sector: "retail",
|
|
68
|
+
overall: 39.4,
|
|
69
|
+
adoption: 43.1,
|
|
70
|
+
governance: 35.0,
|
|
71
|
+
investment: 42.6,
|
|
72
|
+
incidents: 35.1,
|
|
73
|
+
rank: 4,
|
|
74
|
+
national_average: {
|
|
75
|
+
overall: 41.8,
|
|
76
|
+
adoption: 40.9,
|
|
77
|
+
governance: 45.5,
|
|
78
|
+
investment: 41.3,
|
|
79
|
+
incidents: 38.9,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
healthcare: {
|
|
83
|
+
sector: "healthcare",
|
|
84
|
+
overall: 42.3,
|
|
85
|
+
adoption: 40.2,
|
|
86
|
+
governance: 48.3,
|
|
87
|
+
investment: 41.4,
|
|
88
|
+
incidents: 38.9,
|
|
89
|
+
rank: 3,
|
|
90
|
+
national_average: {
|
|
91
|
+
overall: 41.8,
|
|
92
|
+
adoption: 40.9,
|
|
93
|
+
governance: 45.5,
|
|
94
|
+
investment: 41.3,
|
|
95
|
+
incidents: 38.9,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
utilities: {
|
|
99
|
+
sector: "utilities",
|
|
100
|
+
overall: 31.3,
|
|
101
|
+
adoption: 28.0,
|
|
102
|
+
governance: 37.1,
|
|
103
|
+
investment: 29.9,
|
|
104
|
+
incidents: 30.8,
|
|
105
|
+
rank: 6,
|
|
106
|
+
national_average: {
|
|
107
|
+
overall: 41.8,
|
|
108
|
+
adoption: 40.9,
|
|
109
|
+
governance: 45.5,
|
|
110
|
+
investment: 41.3,
|
|
111
|
+
incidents: 38.9,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
const AU_INCIDENTS = [
|
|
116
|
+
{
|
|
117
|
+
id: "robodebt",
|
|
118
|
+
title: "Robodebt Automated Debt Recovery Scheme",
|
|
119
|
+
sector: "government",
|
|
120
|
+
severity: "critical",
|
|
121
|
+
summary: "The Australian Government's automated welfare debt recovery system incorrectly raised debts against ~470,000 welfare recipients by income-averaging ATO data without human review. A Royal Commission found the scheme unlawful, resulting in $1.8B in repayments and criminal referrals of senior public servants.",
|
|
122
|
+
regulatory_bodies: ["OAIC", "ATO", "Services Australia"],
|
|
123
|
+
pattern_slugs: [
|
|
124
|
+
"human-in-the-loop/human-in-the-loop-gateway",
|
|
125
|
+
"compliance/algorithmic-impact-assessment",
|
|
126
|
+
"governance/model-governance-framework",
|
|
127
|
+
],
|
|
128
|
+
outcome: "Royal Commission 2023. $1.8B repaid. Class action settled. Multiple criminal referrals. Foundational AU AI governance case study.",
|
|
129
|
+
year: 2019,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: "medibank-breach",
|
|
133
|
+
title: "Medibank AI-Adjacent Data Breach",
|
|
134
|
+
sector: "healthcare",
|
|
135
|
+
severity: "critical",
|
|
136
|
+
summary: "Hackers accessed personal and health claims data of 9.7 million Medibank customers via stolen credentials. AI-powered anomaly detection failed to flag the lateral movement. OAIC commenced enforcement action; Medibank faces potential $21.5M+ in penalties under the Privacy Act.",
|
|
137
|
+
regulatory_bodies: ["OAIC", "ASIC", "APRA"],
|
|
138
|
+
pattern_slugs: [
|
|
139
|
+
"security/ai-security-policy-enforcement",
|
|
140
|
+
"observability/ai-audit-trail",
|
|
141
|
+
"governance/model-governance-framework",
|
|
142
|
+
],
|
|
143
|
+
outcome: "9.7M records exposed. OAIC enforcement action commenced 2023. ASIC litigation filed. Potential penalties exceed $21.5M.",
|
|
144
|
+
year: 2022,
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
id: "anz-credit-bias",
|
|
148
|
+
title: "ANZ Credit Decisioning Algorithmic Bias Review",
|
|
149
|
+
sector: "banking",
|
|
150
|
+
severity: "high",
|
|
151
|
+
summary: "ASIC's 2023 shadow-shopping study found ANZ's AI-assisted credit decisioning produced statistically significant disparate outcomes for customers from certain postcodes and demographic groups. The model lacked explainability tooling required under updated INFO 183 guidance. ANZ voluntarily remediated ~12,000 customer files.",
|
|
152
|
+
regulatory_bodies: ["ASIC", "APRA"],
|
|
153
|
+
pattern_slugs: [
|
|
154
|
+
"governance/explainability-layer",
|
|
155
|
+
"compliance/algorithmic-impact-assessment",
|
|
156
|
+
"human-in-the-loop/human-in-the-loop-gateway",
|
|
157
|
+
],
|
|
158
|
+
outcome: "Voluntary remediation of 12,000 files. ASIC infringement notice. Enhanced explainability tooling mandated in enforceable undertaking.",
|
|
159
|
+
year: 2023,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: "cba-payments-blocked",
|
|
163
|
+
title: "CBA AI Fraud Model Mass Payment Blocking",
|
|
164
|
+
sector: "banking",
|
|
165
|
+
severity: "high",
|
|
166
|
+
summary: "CBA's real-time AI fraud detection model experienced a model drift event following a data pipeline change, incorrectly flagging ~85,000 legitimate payments as fraudulent over a 6-hour window. 40,000 customers were unable to access funds. APRA required a post-incident model risk review under CPS 230.",
|
|
167
|
+
regulatory_bodies: ["APRA", "ASIC", "RBA"],
|
|
168
|
+
pattern_slugs: [
|
|
169
|
+
"observability/model-performance-monitor",
|
|
170
|
+
"agentic-ai/agent-checkpoint-and-recovery",
|
|
171
|
+
"governance/model-governance-framework",
|
|
172
|
+
],
|
|
173
|
+
outcome: "85,000 payments blocked. APRA CPS 230 model risk review required. Internal incident report published. Model drift detection controls mandated.",
|
|
174
|
+
year: 2024,
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: "nsw-chatgpt-breach",
|
|
178
|
+
title: "NSW Government ChatGPT Sensitive Data Exposure",
|
|
179
|
+
sector: "government",
|
|
180
|
+
severity: "high",
|
|
181
|
+
summary: "NSW public servants submitted sensitive cabinet documents, legal advice, and citizen PII into ChatGPT without authorisation. The NSWO Privacy Commissioner found the agency breached the PPIP Act. Subsequently NSW DCS issued a whole-of-government AI acceptable use policy and mandatory AI literacy training for APS staff.",
|
|
182
|
+
regulatory_bodies: ["NSW Privacy Commissioner", "OAIC", "NSW DCS"],
|
|
183
|
+
pattern_slugs: [
|
|
184
|
+
"security/ai-security-policy-enforcement",
|
|
185
|
+
"governance/model-governance-framework",
|
|
186
|
+
"compliance/data-minimisation-in-ai-pipelines",
|
|
187
|
+
],
|
|
188
|
+
outcome: "PPIP Act breach finding. Mandatory AI acceptable use policy issued across NSW Government. Mandatory AI literacy training for 100,000+ APS staff.",
|
|
189
|
+
year: 2023,
|
|
190
|
+
},
|
|
191
|
+
];
|
|
192
|
+
const REGULATORY_CHANGES = [
|
|
193
|
+
{
|
|
194
|
+
id: "apra-cps-230",
|
|
195
|
+
title: "APRA CPS 230 Operational Risk Management",
|
|
196
|
+
regulator: "APRA",
|
|
197
|
+
framework: "CPS 230",
|
|
198
|
+
impact_level: "critical",
|
|
199
|
+
sectors: ["banking", "insurance"],
|
|
200
|
+
summary: "APRA CPS 230 (effective July 2025) requires all ADIs, insurers, and super funds to map every material service provider — including AI vendors — against business continuity obligations. AI systems affecting operational resilience must have documented fallback procedures, model risk registers, and board-level accountability. Non-compliance triggers supervisory escalation.",
|
|
201
|
+
effective_date: "2025-07-01",
|
|
202
|
+
url: "https://www.apra.gov.au/cps-230",
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: "oaic-ai-privacy",
|
|
206
|
+
title: "OAIC Automated Decision-Making Disclosure Obligations",
|
|
207
|
+
regulator: "OAIC",
|
|
208
|
+
framework: "Privacy Act Review — Reform Package",
|
|
209
|
+
impact_level: "high",
|
|
210
|
+
sectors: ["government", "healthcare", "banking"],
|
|
211
|
+
summary: "The Privacy Act Reform Package (2024–2025) moves automated decision-making disclosure from guidance to enforceable obligation for entities with >$3M annual turnover. Organisations must disclose when AI systems make or substantially influence decisions affecting individuals, provide meaningful explanation on request, and maintain an AI decision register auditable by the OAIC.",
|
|
212
|
+
effective_date: "2025-12-01",
|
|
213
|
+
url: "https://www.ag.gov.au/rights-and-protections/privacy",
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
id: "asic-info-183",
|
|
217
|
+
title: "ASIC INFO 183 AI Governance in Financial Services",
|
|
218
|
+
regulator: "ASIC",
|
|
219
|
+
framework: "INFO 183 (updated 2024)",
|
|
220
|
+
impact_level: "high",
|
|
221
|
+
sectors: ["banking", "insurance", "retail"],
|
|
222
|
+
summary: "ASIC's updated INFO 183 (2024) and its September 2023 shadow shopping study found 22% of AI-generated financial advice failing the 'best interest' duty. ASIC has issued 6 infringement notices tied to undisclosed AI use in client-facing decisions. Financial services licensees must maintain explainability documentation for all AI-influenced client decisions and conduct annual model risk reviews.",
|
|
223
|
+
effective_date: "2024-03-01",
|
|
224
|
+
url: "https://www.asic.gov.au/regulatory-resources/financial-services/digital-advice",
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
id: "tga-samd",
|
|
228
|
+
title: "TGA AI-Enabled Software as a Medical Device (SaMD) Framework",
|
|
229
|
+
regulator: "TGA",
|
|
230
|
+
framework: "SaMD Guidance (updated Jan 2024)",
|
|
231
|
+
impact_level: "high",
|
|
232
|
+
sectors: ["healthcare"],
|
|
233
|
+
summary: "TGA's updated SaMD framework (Jan 2024) classifies AI diagnostic tools under Class IIb or Class III depending on clinical risk — mandating clinical validation, post-market surveillance, and AU-specific training data requirements. 74 SaMD applications pending as of Q1 2026. Adaptive AI models that learn post-deployment require separate re-registration under the framework.",
|
|
234
|
+
effective_date: "2024-01-15",
|
|
235
|
+
url: "https://www.tga.gov.au/resources/resource/guidance/software-medical-device-guidance",
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
id: "privacy-act-reform",
|
|
239
|
+
title: "Privacy Act Reform — AI Provisions",
|
|
240
|
+
regulator: "OAIC",
|
|
241
|
+
framework: "Privacy Act 1988 (reformed)",
|
|
242
|
+
impact_level: "critical",
|
|
243
|
+
sectors: ["banking", "insurance", "government", "retail", "healthcare", "utilities"],
|
|
244
|
+
summary: "Comprehensive Privacy Act reform introduces a direct right of action for individuals, statutory tort for serious invasions of privacy, and specific provisions on AI profiling and inferred data. Organisations using AI to infer sensitive attributes (health, financial stress, political views) must obtain explicit consent. Reform package expected to pass in 2025 with 12-month compliance transition.",
|
|
245
|
+
effective_date: "2026-01-01",
|
|
246
|
+
url: "https://www.ag.gov.au/rights-and-protections/privacy",
|
|
247
|
+
},
|
|
248
|
+
];
|
|
249
|
+
function parsePatternFile(raw) {
|
|
250
|
+
const lines = raw.split("\n");
|
|
251
|
+
// Title from H1: # [EAAPL-XXXNNN] Pattern Name
|
|
252
|
+
const h1 = lines.find((l) => l.startsWith("# "));
|
|
253
|
+
const title = h1
|
|
254
|
+
? h1.replace(/^#\s*/, "").replace(/\[[^\]]+\]\s*/, "").trim()
|
|
255
|
+
: "";
|
|
256
|
+
// Bold field parser: **FieldName:** value
|
|
257
|
+
const getField = (name) => {
|
|
258
|
+
const line = lines.find((l) => l.toLowerCase().startsWith(`**${name.toLowerCase()}:**`));
|
|
259
|
+
return line ? line.replace(/^\*\*[^*]+:\*\*\s*/, "").trim() : "";
|
|
260
|
+
};
|
|
261
|
+
const maturity = getField("Maturity") || getField("Status") || "";
|
|
262
|
+
// Regulatory from **Regulatory Relevance:** APRA CPS 230, ISO/IEC 42001
|
|
263
|
+
const regRaw = getField("Regulatory Relevance");
|
|
264
|
+
const regulatory = regRaw
|
|
265
|
+
? regRaw.split(",").map((s) => s.replace(/`/g, "").trim()).filter(Boolean)
|
|
266
|
+
: [];
|
|
267
|
+
// Description from Executive Summary section
|
|
268
|
+
const summaryIdx = lines.findIndex((l) => /^##\s+.*executive summary/i.test(l));
|
|
269
|
+
let description = "";
|
|
270
|
+
if (summaryIdx !== -1) {
|
|
271
|
+
const bodyLines = [];
|
|
272
|
+
for (let i = summaryIdx + 1; i < lines.length; i++) {
|
|
273
|
+
if (lines[i].startsWith("##"))
|
|
274
|
+
break;
|
|
275
|
+
bodyLines.push(lines[i]);
|
|
276
|
+
}
|
|
277
|
+
description = bodyLines
|
|
278
|
+
.join(" ")
|
|
279
|
+
.replace(/\s+/g, " ")
|
|
280
|
+
.trim()
|
|
281
|
+
.slice(0, 300);
|
|
282
|
+
}
|
|
283
|
+
return { title, description, maturity, regulatory, content: raw };
|
|
284
|
+
}
|
|
285
|
+
function getContent(raw) {
|
|
286
|
+
return raw;
|
|
287
|
+
}
|
|
288
|
+
async function listPatternFiles(dir, base = "") {
|
|
289
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
290
|
+
const files = [];
|
|
291
|
+
for (const entry of entries) {
|
|
292
|
+
if (entry.isDirectory()) {
|
|
293
|
+
const sub = await listPatternFiles(join(dir, entry.name), base ? `${base}/${entry.name}` : entry.name);
|
|
294
|
+
files.push(...sub);
|
|
295
|
+
}
|
|
296
|
+
else if (entry.name.endsWith(".md") || entry.name.endsWith(".mdx")) {
|
|
297
|
+
const slug = `${base ? base + "/" : ""}${entry.name.replace(/\.mdx?$/, "")}`;
|
|
298
|
+
files.push(slug);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return files;
|
|
302
|
+
}
|
|
303
|
+
async function readPattern(slug) {
|
|
304
|
+
for (const ext of [".md", ".mdx"]) {
|
|
305
|
+
try {
|
|
306
|
+
const raw = await readFile(join(PATTERNS_DIR, slug + ext), "utf8");
|
|
307
|
+
return parsePatternFile(raw);
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
// try next extension
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
// ---------------------------------------------------------------------------
|
|
316
|
+
// MCP Server
|
|
317
|
+
// ---------------------------------------------------------------------------
|
|
318
|
+
const server = new Server({ name: "aipatterns-mcp-server", version: "1.0.0" }, {
|
|
319
|
+
capabilities: {
|
|
320
|
+
tools: {},
|
|
321
|
+
},
|
|
322
|
+
});
|
|
323
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
324
|
+
tools: [
|
|
325
|
+
{
|
|
326
|
+
name: "search_patterns",
|
|
327
|
+
description: "Search the aipatterns.com.au AI pattern library. Returns matching patterns with slug, title, description, maturity level, and category. Useful for finding design patterns relevant to a specific AI use case, capability, or compliance concern.",
|
|
328
|
+
inputSchema: {
|
|
329
|
+
type: "object",
|
|
330
|
+
properties: {
|
|
331
|
+
query: {
|
|
332
|
+
type: "string",
|
|
333
|
+
description: "Search term to match against pattern title, description, or content",
|
|
334
|
+
},
|
|
335
|
+
category: {
|
|
336
|
+
type: "string",
|
|
337
|
+
description: "Optional category filter (e.g. agentic-ai, governance, security, rag, observability, compliance, human-in-the-loop)",
|
|
338
|
+
},
|
|
339
|
+
maturity: {
|
|
340
|
+
type: "string",
|
|
341
|
+
description: "Optional maturity filter (e.g. production, beta, experimental)",
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
required: ["query"],
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
name: "get_pattern",
|
|
349
|
+
description: "Retrieve full detail of a specific AI pattern from aipatterns.com.au, including implementation guidance and regulatory context. Use the slug returned by search_patterns.",
|
|
350
|
+
inputSchema: {
|
|
351
|
+
type: "object",
|
|
352
|
+
properties: {
|
|
353
|
+
slug: {
|
|
354
|
+
type: "string",
|
|
355
|
+
description: 'Pattern slug, e.g. "agentic-ai/agent-checkpoint-and-recovery"',
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
required: ["slug"],
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
name: "get_incidents",
|
|
363
|
+
description: "Retrieve notable Australian AI incidents. Useful for understanding real-world failures, regulatory enforcement actions, and which patterns could have prevented the incident.",
|
|
364
|
+
inputSchema: {
|
|
365
|
+
type: "object",
|
|
366
|
+
properties: {
|
|
367
|
+
sector: {
|
|
368
|
+
type: "string",
|
|
369
|
+
description: "Filter by sector: banking, insurance, government, retail, healthcare, utilities",
|
|
370
|
+
},
|
|
371
|
+
severity: {
|
|
372
|
+
type: "string",
|
|
373
|
+
description: "Filter by severity: critical, high, medium, low",
|
|
374
|
+
},
|
|
375
|
+
limit: {
|
|
376
|
+
type: "number",
|
|
377
|
+
description: "Maximum number of incidents to return (default 5)",
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
name: "get_sector_benchmark",
|
|
384
|
+
description: "Get the AU AI Maturity Index benchmark score for a specific sector. Returns overall score, dimension scores (adoption, governance, investment, incidents), sector rank, and national averages. Scores computed from Q2 2026 evidence base.",
|
|
385
|
+
inputSchema: {
|
|
386
|
+
type: "object",
|
|
387
|
+
properties: {
|
|
388
|
+
sector: {
|
|
389
|
+
type: "string",
|
|
390
|
+
description: "One of: banking, insurance, government, retail, healthcare, utilities",
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
required: ["sector"],
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
name: "get_regulatory_changes",
|
|
398
|
+
description: "Retrieve recent and upcoming Australian AI regulatory changes (APRA, OAIC, ASIC, TGA, Privacy Act reform). Useful for understanding compliance obligations when building AI systems for the Australian market.",
|
|
399
|
+
inputSchema: {
|
|
400
|
+
type: "object",
|
|
401
|
+
properties: {
|
|
402
|
+
regulator: {
|
|
403
|
+
type: "string",
|
|
404
|
+
description: "Filter by regulator abbreviation: APRA, OAIC, ASIC, TGA",
|
|
405
|
+
},
|
|
406
|
+
impact_level: {
|
|
407
|
+
type: "string",
|
|
408
|
+
description: "Filter by impact level: critical, high, medium, low",
|
|
409
|
+
},
|
|
410
|
+
limit: {
|
|
411
|
+
type: "number",
|
|
412
|
+
description: "Maximum number of changes to return (default 5)",
|
|
413
|
+
},
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
}));
|
|
419
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
420
|
+
const { name, arguments: args } = request.params;
|
|
421
|
+
try {
|
|
422
|
+
switch (name) {
|
|
423
|
+
case "search_patterns": {
|
|
424
|
+
const { query, category, maturity } = args;
|
|
425
|
+
const slugs = await listPatternFiles(PATTERNS_DIR);
|
|
426
|
+
const results = [];
|
|
427
|
+
for (const slug of slugs) {
|
|
428
|
+
if (results.length >= 10)
|
|
429
|
+
break;
|
|
430
|
+
const slugCategory = slug.includes("/") ? slug.split("/")[0] : "";
|
|
431
|
+
if (category && slugCategory !== category)
|
|
432
|
+
continue;
|
|
433
|
+
const parsed = await readPattern(slug);
|
|
434
|
+
if (!parsed)
|
|
435
|
+
continue;
|
|
436
|
+
if (maturity && parsed.maturity.toLowerCase() !== maturity.toLowerCase())
|
|
437
|
+
continue;
|
|
438
|
+
const q = query.toLowerCase();
|
|
439
|
+
const matchable = `${parsed.title} ${parsed.description} ${parsed.content}`.toLowerCase();
|
|
440
|
+
if (!matchable.includes(q))
|
|
441
|
+
continue;
|
|
442
|
+
results.push({
|
|
443
|
+
slug,
|
|
444
|
+
title: parsed.title || slug,
|
|
445
|
+
description: parsed.description,
|
|
446
|
+
maturity: parsed.maturity,
|
|
447
|
+
category: slugCategory,
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
return {
|
|
451
|
+
content: [
|
|
452
|
+
{
|
|
453
|
+
type: "text",
|
|
454
|
+
text: JSON.stringify(results, null, 2),
|
|
455
|
+
},
|
|
456
|
+
],
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
case "get_pattern": {
|
|
460
|
+
const { slug } = args;
|
|
461
|
+
const parsed = await readPattern(slug);
|
|
462
|
+
if (!parsed) {
|
|
463
|
+
return {
|
|
464
|
+
content: [
|
|
465
|
+
{
|
|
466
|
+
type: "text",
|
|
467
|
+
text: JSON.stringify({ error: `Pattern not found: ${slug}` }),
|
|
468
|
+
},
|
|
469
|
+
],
|
|
470
|
+
isError: true,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
const detail = {
|
|
474
|
+
slug,
|
|
475
|
+
title: parsed.title || slug,
|
|
476
|
+
description: parsed.description,
|
|
477
|
+
maturity: parsed.maturity,
|
|
478
|
+
category: slug.includes("/") ? slug.split("/")[0] : "",
|
|
479
|
+
regulatory: parsed.regulatory,
|
|
480
|
+
content: parsed.content.slice(0, 4000),
|
|
481
|
+
};
|
|
482
|
+
return {
|
|
483
|
+
content: [
|
|
484
|
+
{
|
|
485
|
+
type: "text",
|
|
486
|
+
text: JSON.stringify(detail, null, 2),
|
|
487
|
+
},
|
|
488
|
+
],
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
case "get_incidents": {
|
|
492
|
+
const { sector, severity, limit = 5 } = args;
|
|
493
|
+
let results = AU_INCIDENTS;
|
|
494
|
+
if (sector)
|
|
495
|
+
results = results.filter((i) => i.sector === sector);
|
|
496
|
+
if (severity)
|
|
497
|
+
results = results.filter((i) => i.severity === severity);
|
|
498
|
+
results = results.slice(0, limit);
|
|
499
|
+
return {
|
|
500
|
+
content: [
|
|
501
|
+
{
|
|
502
|
+
type: "text",
|
|
503
|
+
text: JSON.stringify(results, null, 2),
|
|
504
|
+
},
|
|
505
|
+
],
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
case "get_sector_benchmark": {
|
|
509
|
+
const { sector } = args;
|
|
510
|
+
const benchmark = SECTOR_BENCHMARKS[sector.toLowerCase()];
|
|
511
|
+
if (!benchmark) {
|
|
512
|
+
return {
|
|
513
|
+
content: [
|
|
514
|
+
{
|
|
515
|
+
type: "text",
|
|
516
|
+
text: JSON.stringify({
|
|
517
|
+
error: `Unknown sector: ${sector}. Valid sectors: ${Object.keys(SECTOR_BENCHMARKS).join(", ")}`,
|
|
518
|
+
}),
|
|
519
|
+
},
|
|
520
|
+
],
|
|
521
|
+
isError: true,
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
return {
|
|
525
|
+
content: [
|
|
526
|
+
{
|
|
527
|
+
type: "text",
|
|
528
|
+
text: JSON.stringify(benchmark, null, 2),
|
|
529
|
+
},
|
|
530
|
+
],
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
case "get_regulatory_changes": {
|
|
534
|
+
const { regulator, impact_level, limit = 5 } = args;
|
|
535
|
+
let results = REGULATORY_CHANGES;
|
|
536
|
+
if (regulator) {
|
|
537
|
+
results = results.filter((r) => r.regulator.toLowerCase() === regulator.toLowerCase());
|
|
538
|
+
}
|
|
539
|
+
if (impact_level) {
|
|
540
|
+
results = results.filter((r) => r.impact_level === impact_level);
|
|
541
|
+
}
|
|
542
|
+
results = results.slice(0, limit);
|
|
543
|
+
return {
|
|
544
|
+
content: [
|
|
545
|
+
{
|
|
546
|
+
type: "text",
|
|
547
|
+
text: JSON.stringify(results, null, 2),
|
|
548
|
+
},
|
|
549
|
+
],
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
default:
|
|
553
|
+
return {
|
|
554
|
+
content: [
|
|
555
|
+
{
|
|
556
|
+
type: "text",
|
|
557
|
+
text: JSON.stringify({ error: `Unknown tool: ${name}` }),
|
|
558
|
+
},
|
|
559
|
+
],
|
|
560
|
+
isError: true,
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
catch (err) {
|
|
565
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
566
|
+
return {
|
|
567
|
+
content: [
|
|
568
|
+
{
|
|
569
|
+
type: "text",
|
|
570
|
+
text: JSON.stringify({ error: message }),
|
|
571
|
+
},
|
|
572
|
+
],
|
|
573
|
+
isError: true,
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
// ---------------------------------------------------------------------------
|
|
578
|
+
// Bootstrap
|
|
579
|
+
// ---------------------------------------------------------------------------
|
|
580
|
+
async function main() {
|
|
581
|
+
const transport = new StdioServerTransport();
|
|
582
|
+
await server.connect(transport);
|
|
583
|
+
// MCP servers communicate over stdio; stderr is safe for diagnostics
|
|
584
|
+
process.stderr.write("aipatterns MCP server running on stdio\n");
|
|
585
|
+
}
|
|
586
|
+
main().catch((err) => {
|
|
587
|
+
process.stderr.write(`Fatal: ${err}\n`);
|
|
588
|
+
process.exit(1);
|
|
589
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aipatterns-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for aipatterns.com.au — search 138 AU enterprise AI patterns, get sector benchmarks, incidents, and regulatory changes via Claude, Cursor, or any MCP client.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"aipatterns-mcp-server": "index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"index.js",
|
|
12
|
+
"index.d.ts",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"start": "node index.js",
|
|
18
|
+
"dev": "tsx index.ts"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"mcp",
|
|
22
|
+
"model-context-protocol",
|
|
23
|
+
"ai-patterns",
|
|
24
|
+
"australia",
|
|
25
|
+
"enterprise-ai",
|
|
26
|
+
"claude",
|
|
27
|
+
"governance",
|
|
28
|
+
"regulatory"
|
|
29
|
+
],
|
|
30
|
+
"author": "uchit",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/uchit86/aipatterns-mcp-server"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"typescript": "^5.0.0",
|
|
41
|
+
"tsx": "^4.0.0",
|
|
42
|
+
"@types/node": "^20.0.0"
|
|
43
|
+
}
|
|
44
|
+
}
|