@donotdev/mcp-server 0.0.1
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 +102 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# DoNotDev MCP Server
|
|
2
|
+
|
|
3
|
+
MCP server that provides component type lookups from published `.d.ts` files. Prevents AI hallucination by giving access to actual TypeScript definitions.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
### 1. Build
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
cd packages/mcp-server
|
|
11
|
+
bun install
|
|
12
|
+
bun run build
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Configure Claude Code
|
|
16
|
+
|
|
17
|
+
Add to your project's `.mcp.json`:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"mcpServers": {
|
|
22
|
+
"donotdev": {
|
|
23
|
+
"command": "node",
|
|
24
|
+
"args": ["/absolute/path/to/dndev/packages/mcp-server/dist/index.js"]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or for Claude Desktop, add to `~/.claude/claude_desktop_config.json`:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"mcpServers": {
|
|
35
|
+
"donotdev": {
|
|
36
|
+
"command": "node",
|
|
37
|
+
"args": ["/absolute/path/to/dndev/packages/mcp-server/dist/index.js"]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 3. Restart Claude Code
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
claude --mcp-debug
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Tools
|
|
50
|
+
|
|
51
|
+
### `lookup_component`
|
|
52
|
+
|
|
53
|
+
Get TypeScript props/types for a component.
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Input: { "component": "Button" }
|
|
57
|
+
Output: Full ButtonProps interface from .d.ts
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
Input: { "component": "EntityFormRenderer", "package": "@donotdev/ui" }
|
|
62
|
+
Output: Full EntityFormRendererProps interface
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### `list_components`
|
|
66
|
+
|
|
67
|
+
List all exports from a package.
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Input: { "package": "@donotdev/components" }
|
|
71
|
+
Output: Button, Text, Stack, Card, Grid, Section, Badge, Spinner, ...
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### `list_packages`
|
|
75
|
+
|
|
76
|
+
List all available DoNotDev packages.
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Input: {}
|
|
80
|
+
Output: @donotdev/components, @donotdev/ui, @donotdev/core, ...
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## How It Works
|
|
84
|
+
|
|
85
|
+
1. AI calls `lookup_component({ component: "Button" })`
|
|
86
|
+
2. Server reads `node_modules/@donotdev/components/dist/index.d.ts`
|
|
87
|
+
3. Extracts `ButtonProps` interface using regex
|
|
88
|
+
4. Returns actual TypeScript definition
|
|
89
|
+
5. AI sees real props, can't hallucinate
|
|
90
|
+
|
|
91
|
+
## Usage in CLAUDE.md
|
|
92
|
+
|
|
93
|
+
Add to your project's CLAUDE.md:
|
|
94
|
+
|
|
95
|
+
```markdown
|
|
96
|
+
## Component Usage
|
|
97
|
+
|
|
98
|
+
BEFORE writing any component, call:
|
|
99
|
+
- `lookup_component` to get the actual props
|
|
100
|
+
|
|
101
|
+
NEVER guess props. If MCP unavailable, ask user.
|
|
102
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{Server as v}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as y}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as k,ListToolsRequestSchema as S}from"@modelcontextprotocol/sdk/types.js";import{readFileSync as f,existsSync as m}from"fs";import{join as a}from"path";const g=["@donotdev/components","@donotdev/adv-comps","@donotdev/core","@donotdev/crud","@donotdev/firebase","@donotdev/auth","@donotdev/billing","@donotdev/oauth","@donotdev/ui","@donotdev/templates","@donotdev/functions","@donotdev/providers"];function w(){let e=process.cwd();for(;e!=="/";){const o=a(e,"node_modules");if(m(o))return o;e=a(e,"..")}return null}function $(e,o){const c=new RegExp(`export\\s+interface\\s+${o}\\s*(?:<[^>]+>)?\\s*(?:extends[^{]+)?\\{[^}]+\\}`,"gs");let n=e.match(c);if(n)return n[0];const s=new RegExp(`export\\s+type\\s+${o}\\s*(?:<[^>]+>)?\\s*=[^;]+;`,"gs");if(n=e.match(s),n)return n[0];const r=new RegExp(`export\\s+const\\s+${o}\\s*[=:][^;]+;`,"gs");return n=e.match(r),n?n[0]:null}function R(e){const o=[],c=e.matchAll(/export\s*\{([^}]+)\}/g);for(const t of c)if(t[1]){const d=t[1].split(",").map(p=>p.trim().split(" ")[0]).filter(p=>!!p);o.push(...d)}const n=e.matchAll(/export\s+interface\s+(\w+)/g);for(const t of n)t[1]&&o.push(t[1]);const s=e.matchAll(/export\s+type\s+(\w+)/g);for(const t of s)t[1]&&o.push(t[1]);const r=e.matchAll(/export\s+const\s+(\w+)/g);for(const t of r)t[1]&&o.push(t[1]);const i=e.matchAll(/export\s+default\s+(\w+)/g);for(const t of i)t[1]&&o.push(t[1]);return[...new Set(o)].filter(t=>t&&t!=="default")}const l=new v({name:"donotdev-mcp",version:"0.0.1"},{capabilities:{tools:{}}});l.setRequestHandler(S,async()=>({tools:[{name:"lookup_component",description:"Get TypeScript props/types for a DoNotDev component. Returns the actual interface from .d.ts files.",inputSchema:{type:"object",properties:{component:{type:"string",description:'Component name (e.g., "Button", "ButtonProps", "Stack", "EntityFormRenderer")'},package:{type:"string",description:'Package name (e.g., "@donotdev/components"). If omitted, searches all packages.'}},required:["component"]}},{name:"list_components",description:"List all exported components/types from a DoNotDev package",inputSchema:{type:"object",properties:{package:{type:"string",description:'Package name (e.g., "@donotdev/components")'}},required:["package"]}},{name:"list_packages",description:"List all DoNotDev packages",inputSchema:{type:"object",properties:{}}}]})),l.setRequestHandler(k,async e=>{const{name:o,arguments:c}=e.params,n=w();if(!n)return{content:[{type:"text",text:"Error: node_modules not found. Run from project directory."}]};if(o==="list_packages")return{content:[{type:"text",text:`Available packages:
|
|
3
|
+
${g.filter(r=>m(a(n,r,"dist","index.d.ts"))).join(`
|
|
4
|
+
`)}`}]};if(o==="list_components"){const s=c?.package,r=a(n,s,"dist","index.d.ts");if(!m(r))return{content:[{type:"text",text:`Error: ${s} not found at ${r}`}]};const i=f(r,"utf-8"),t=R(i);return{content:[{type:"text",text:`Exports from ${s}:
|
|
5
|
+
${t.join(`
|
|
6
|
+
`)}`}]}}if(o==="lookup_component"){const s=c?.component,r=c?.package,i=[s,`${s}Props`,`${s.replace(/Props$/,"")}Props`],t=r?[r]:g;for(const d of t){const p=a(n,d,"dist","index.d.ts");if(!m(p))continue;const x=f(p,"utf-8");for(const h of i){const u=$(x,h);if(u)return{content:[{type:"text",text:`Found in ${d}:
|
|
7
|
+
|
|
8
|
+
${u}`}]}}}return{content:[{type:"text",text:`Not found: ${s}
|
|
9
|
+
|
|
10
|
+
Tip: Try lookup_component with just the component name (e.g., "Button" not "ButtonProps"), or use list_components to see available exports.`}]}}return{content:[{type:"text",text:`Unknown tool: ${o}`}]}});async function b(){const e=new y;await l.connect(e)}b().catch(console.error);
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@donotdev/mcp-server",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "MCP server for DoNotDev component type lookups",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": false,
|
|
7
|
+
"bin": {
|
|
8
|
+
"@donotdev/mcp-server": "./dist/index.js",
|
|
9
|
+
"donotdev-mcp": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "dn bundle --package @donotdev/mcp-server",
|
|
27
|
+
"dev": "tsc -p tsconfig.build.json --watch",
|
|
28
|
+
"clean": "rimraf dist tsconfig.tsbuildinfo",
|
|
29
|
+
"type-check": "tsc --noEmit"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.26.0"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/donotdev/mcp-server.git"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"dndev",
|
|
40
|
+
"mcp",
|
|
41
|
+
"model-context-protocol",
|
|
42
|
+
"typescript",
|
|
43
|
+
"component-lookup"
|
|
44
|
+
],
|
|
45
|
+
"author": "AMBROISE PARK Consulting",
|
|
46
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=20.0.0"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"registry": "https://registry.npmjs.org",
|
|
52
|
+
"access": "public"
|
|
53
|
+
}
|
|
54
|
+
}
|