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 CHANGED
@@ -1,14 +1,40 @@
1
1
  # mcp-software-design
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/mcp-software-design)](https://www.npmjs.com/package/mcp-software-design)
4
+ [![npm downloads](https://img.shields.io/npm/dm/mcp-software-design)](https://www.npmjs.com/package/mcp-software-design)
5
+ [![License: MIT](https://img.shields.io/npm/l/mcp-software-design)](./LICENSE)
6
+ [![MCP](https://img.shields.io/badge/MCP-server-blue)](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 — plus pattern
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` | `behavioral`).
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, and more.
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
- ## Install & run
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
- ### Register with Claude Code
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
- const VERSION = "0.1.0";
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. "pattern" = all GoF patterns. Default "all".'),
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.0",
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
- "claude"
28
+ "clean-code",
29
+ "code-smells"
22
30
  ],
23
31
  "bin": {
24
32
  "mcp-software-design": "build/index.js"