mcp-software-design 0.1.0 → 0.1.2
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 +37 -6
- package/build/catalog.js +51 -0
- package/build/index.js +17 -4
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -1,14 +1,40 @@
|
|
|
1
1
|
# mcp-software-design
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/mcp-software-design)
|
|
4
|
+
[](https://www.npmjs.com/package/mcp-software-design)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://modelcontextprotocol.io)
|
|
7
|
+
|
|
3
8
|
An [MCP](https://modelcontextprotocol.io) server that teaches and helps apply
|
|
4
9
|
**software-design guidance** — the SOLID principles, the OOP pillars, DRY /
|
|
5
|
-
KISS / YAGNI, and the 23 Gang-of-Four design patterns —
|
|
6
|
-
scaffolding and heuristic code-smell detection.
|
|
10
|
+
KISS / YAGNI / meaningful naming, and the 23 Gang-of-Four design patterns —
|
|
11
|
+
plus pattern scaffolding and heuristic code-smell detection.
|
|
7
12
|
|
|
8
13
|
It's the companion to
|
|
9
14
|
[`mcp-udacity-commit`](../mcp-udacity-commit): same stack (TypeScript, the MCP
|
|
10
15
|
SDK, stdio transport), same shape (pure logic modules + thin server wiring).
|
|
11
16
|
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
Register it with Claude Code — one line, nothing to clone:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
claude mcp add software-design -- npx -y mcp-software-design
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or in an MCP client config:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"mcpServers": {
|
|
30
|
+
"software-design": {
|
|
31
|
+
"command": "npx",
|
|
32
|
+
"args": ["-y", "mcp-software-design"]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
12
38
|
## Why this exists — and its one honest caveat
|
|
13
39
|
|
|
14
40
|
The commit server can *lint*: "subject ≤ 50 chars" is objectively checkable.
|
|
@@ -33,7 +59,8 @@ pretending to understand your snippet.
|
|
|
33
59
|
## Tools
|
|
34
60
|
|
|
35
61
|
- **`list_catalog`** `{ kind? }` — list concepts, optionally filtered
|
|
36
|
-
(`principle` | `pattern` | `creational` | `structural` |
|
|
62
|
+
(`principle` | `solid` | `oop` | `pattern` | `creational` | `structural` |
|
|
63
|
+
`behavioral`). `solid` / `oop` narrow to the SOLID five / the four OOP pillars.
|
|
37
64
|
- **`explain_concept`** `{ name }` — full guidance for one principle or
|
|
38
65
|
pattern (intent, when-to-use, trade-offs, participants). Accepts a slug,
|
|
39
66
|
name, or alias (`"SRP"`, `"open-closed"`, `"pubsub"`).
|
|
@@ -47,7 +74,8 @@ pretending to understand your snippet.
|
|
|
47
74
|
|
|
48
75
|
## Resources
|
|
49
76
|
|
|
50
|
-
- **`design://principles`** — SOLID, OOP pillars, DRY, KISS, YAGNI,
|
|
77
|
+
- **`design://principles`** — SOLID, OOP pillars, DRY, KISS, YAGNI, meaningful
|
|
78
|
+
naming, and more.
|
|
51
79
|
- **`design://patterns`** — the 23 GoF patterns, grouped creational /
|
|
52
80
|
structural / behavioral.
|
|
53
81
|
- **`design://smells`** — what `check_smells` detects, its thresholds, and its
|
|
@@ -60,7 +88,10 @@ pretending to understand your snippet.
|
|
|
60
88
|
- **`apply_pattern`** `{ pattern, code }` — refactor a snippet to apply a named
|
|
61
89
|
pattern (and first judge whether it even fits).
|
|
62
90
|
|
|
63
|
-
##
|
|
91
|
+
## Build from source
|
|
92
|
+
|
|
93
|
+
For local development, or to run a local checkout instead of the published
|
|
94
|
+
package:
|
|
64
95
|
|
|
65
96
|
```bash
|
|
66
97
|
npm install
|
|
@@ -70,7 +101,7 @@ npm test # builds, then runs the unit tests
|
|
|
70
101
|
npm run test:client # end-to-end check against the built server
|
|
71
102
|
```
|
|
72
103
|
|
|
73
|
-
|
|
104
|
+
Then register the local build with Claude Code:
|
|
74
105
|
|
|
75
106
|
```bash
|
|
76
107
|
claude mcp add software-design -- node /absolute/path/to/mcp-software-design/build/index.js
|
package/build/catalog.js
CHANGED
|
@@ -166,6 +166,29 @@ export const PRINCIPLES = [
|
|
|
166
166
|
],
|
|
167
167
|
related: ["kiss", "open-closed"],
|
|
168
168
|
},
|
|
169
|
+
{
|
|
170
|
+
slug: "meaningful-names",
|
|
171
|
+
name: "Meaningful Names",
|
|
172
|
+
category: "principle",
|
|
173
|
+
aka: ["intention-revealing-names", "naming", "self-documenting-code"],
|
|
174
|
+
summary: "Names should reveal intent — reach for a word before a comment.",
|
|
175
|
+
intent: "A name is the first documentation a reader meets. Prefer intention-" +
|
|
176
|
+
"revealing names that state what a value is or what a function does, so " +
|
|
177
|
+
"the code explains itself without a comment. Single-letter names are fine " +
|
|
178
|
+
"in tiny scopes — loop counters, short lambda parameters, coordinates/math " +
|
|
179
|
+
"— but hide meaning the moment a value outlives a line or two.",
|
|
180
|
+
whenToUse: [
|
|
181
|
+
"A variable needs a comment to explain what it holds.",
|
|
182
|
+
"You reach for `data`, `tmp`, `mgr`, or `x2` because the real name is hard.",
|
|
183
|
+
"A single-letter name is used far from where it was declared.",
|
|
184
|
+
],
|
|
185
|
+
tradeoffs: [
|
|
186
|
+
"Over-long names (userAccountRepositoryFactoryInstance) hurt readability as much as cryptic ones.",
|
|
187
|
+
"Conventional short names beat forced verbosity — `i` in a for-loop, `e` for an event.",
|
|
188
|
+
"Renaming for clarity is cheap; keep established public/API names stable to avoid churn.",
|
|
189
|
+
],
|
|
190
|
+
related: ["kiss", "single-responsibility", "separation-of-concerns"],
|
|
191
|
+
},
|
|
169
192
|
{
|
|
170
193
|
slug: "composition-over-inheritance",
|
|
171
194
|
name: "Composition Over Inheritance",
|
|
@@ -854,6 +877,34 @@ export const PATTERNS = [
|
|
|
854
877
|
* Lookup + rendering
|
|
855
878
|
* ------------------------------------------------------------------ */
|
|
856
879
|
export const ALL = [...PRINCIPLES, ...PATTERNS];
|
|
880
|
+
/** The five SOLID principles, by slug. */
|
|
881
|
+
const SOLID_SLUGS = new Set([
|
|
882
|
+
"single-responsibility",
|
|
883
|
+
"open-closed",
|
|
884
|
+
"liskov-substitution",
|
|
885
|
+
"interface-segregation",
|
|
886
|
+
"dependency-inversion",
|
|
887
|
+
]);
|
|
888
|
+
/** The four classic OOP pillars, by slug. */
|
|
889
|
+
const OOP_SLUGS = new Set([
|
|
890
|
+
"encapsulation",
|
|
891
|
+
"abstraction",
|
|
892
|
+
"inheritance",
|
|
893
|
+
"polymorphism",
|
|
894
|
+
]);
|
|
895
|
+
/**
|
|
896
|
+
* Which sub-group a concept belongs to. Patterns and the remaining principles
|
|
897
|
+
* (DRY, KISS, YAGNI, composition-over-inheritance, law-of-demeter,
|
|
898
|
+
* separation-of-concerns) are "general". Drives the "solid"/"oop" filters on
|
|
899
|
+
* the list_catalog tool.
|
|
900
|
+
*/
|
|
901
|
+
export function principleGroup(concept) {
|
|
902
|
+
if (SOLID_SLUGS.has(concept.slug))
|
|
903
|
+
return "solid";
|
|
904
|
+
if (OOP_SLUGS.has(concept.slug))
|
|
905
|
+
return "oop";
|
|
906
|
+
return "general";
|
|
907
|
+
}
|
|
857
908
|
/** Normalize a query for fuzzy matching: lowercase, strip non-alphanumerics. */
|
|
858
909
|
function normalize(text) {
|
|
859
910
|
return text.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
package/build/index.js
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
2
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
5
|
import { z } from "zod";
|
|
5
|
-
import { ALL, CATEGORY_LABEL, conceptLine, conceptToMarkdown, findConcept, principlesMarkdown, patternsMarkdown, } from "./catalog.js";
|
|
6
|
+
import { ALL, CATEGORY_LABEL, conceptLine, conceptToMarkdown, findConcept, principleGroup, principlesMarkdown, patternsMarkdown, } from "./catalog.js";
|
|
6
7
|
import { detectSmells, DEFAULTS } from "./smells.js";
|
|
7
8
|
import { scaffoldPattern } from "./scaffold.js";
|
|
8
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Single source of truth: read the version from package.json at startup so it
|
|
11
|
+
* can never drift from the published package. Resolved relative to this module,
|
|
12
|
+
* so it works both from `build/` in the repo and from the installed package
|
|
13
|
+
* (npm ships package.json alongside build/).
|
|
14
|
+
*/
|
|
15
|
+
const VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
9
16
|
/** Human-readable summary of what the smell checker looks for. */
|
|
10
17
|
const SMELLS_GUIDE = `# Code-smell heuristics (design://smells)
|
|
11
18
|
|
|
@@ -65,9 +72,11 @@ export function createServer() {
|
|
|
65
72
|
"kind. Returns each concept's slug, name, category, and one-line summary.",
|
|
66
73
|
inputSchema: {
|
|
67
74
|
kind: z
|
|
68
|
-
.enum(["all", "principle", "pattern", "creational", "structural", "behavioral"])
|
|
75
|
+
.enum(["all", "principle", "solid", "oop", "pattern", "creational", "structural", "behavioral"])
|
|
69
76
|
.optional()
|
|
70
|
-
.describe('Filter by kind. "
|
|
77
|
+
.describe('Filter by kind. "principle" = all principles; "solid"/"oop" narrow ' +
|
|
78
|
+
'to the SOLID five / the four OOP pillars; "pattern" = all GoF ' +
|
|
79
|
+
'patterns. Default "all".'),
|
|
71
80
|
},
|
|
72
81
|
outputSchema: {
|
|
73
82
|
count: z.number(),
|
|
@@ -85,6 +94,10 @@ export function createServer() {
|
|
|
85
94
|
return true;
|
|
86
95
|
if (selectedKind === "principle")
|
|
87
96
|
return concept.category === "principle";
|
|
97
|
+
if (selectedKind === "solid")
|
|
98
|
+
return principleGroup(concept) === "solid";
|
|
99
|
+
if (selectedKind === "oop")
|
|
100
|
+
return principleGroup(concept) === "oop";
|
|
88
101
|
if (selectedKind === "pattern")
|
|
89
102
|
return concept.category !== "principle";
|
|
90
103
|
return concept.category === selectedKind;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-software-design",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "MCP server that teaches and applies software-design guidance: SOLID/OOP/DRY principles, the 23 GoF design patterns, pattern scaffolding, and heuristic code-smell detection.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,13 +12,21 @@
|
|
|
12
12
|
},
|
|
13
13
|
"keywords": [
|
|
14
14
|
"mcp",
|
|
15
|
+
"mcp-server",
|
|
15
16
|
"modelcontextprotocol",
|
|
17
|
+
"model-context-protocol",
|
|
18
|
+
"claude",
|
|
19
|
+
"developer-tools",
|
|
20
|
+
"software-design",
|
|
16
21
|
"design-patterns",
|
|
22
|
+
"design-principles",
|
|
17
23
|
"solid",
|
|
18
24
|
"oop",
|
|
19
25
|
"gof",
|
|
26
|
+
"gang-of-four",
|
|
20
27
|
"refactoring",
|
|
21
|
-
"
|
|
28
|
+
"clean-code",
|
|
29
|
+
"code-smells"
|
|
22
30
|
],
|
|
23
31
|
"bin": {
|
|
24
32
|
"mcp-software-design": "build/index.js"
|