@createsomething/ground-mcp 0.1.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 +92 -0
- package/bin/.gitkeep +4 -0
- package/install.js +169 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# @createsomething/ground-mcp
|
|
2
|
+
|
|
3
|
+
Grounded claims for code. An MCP server that prevents AI hallucination in code analysis.
|
|
4
|
+
|
|
5
|
+
## The Problem
|
|
6
|
+
|
|
7
|
+
AI agents are confident. Too confident.
|
|
8
|
+
|
|
9
|
+
They'll tell you two files are "95% similar" without ever comparing them. They'll declare code "dead" without checking who uses it. They'll claim a module is "disconnected" while it's serving thousands of requests.
|
|
10
|
+
|
|
11
|
+
This is hallucination dressed up as analysis.
|
|
12
|
+
|
|
13
|
+
## The Solution
|
|
14
|
+
|
|
15
|
+
**You can't claim something until you've checked it.**
|
|
16
|
+
|
|
17
|
+
Ground is an MCP server that:
|
|
18
|
+
- Finds duplicates, dead code, and orphaned modules
|
|
19
|
+
- Requires verification before claims
|
|
20
|
+
- Blocks hallucinated analysis
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g @createsomething/ground-mcp
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## MCP Configuration
|
|
29
|
+
|
|
30
|
+
Add to `.cursor/mcp.json`:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"mcpServers": {
|
|
35
|
+
"ground": {
|
|
36
|
+
"command": "ground-mcp"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Restart Cursor. Ground tools are now available.
|
|
43
|
+
|
|
44
|
+
## Available Tools
|
|
45
|
+
|
|
46
|
+
| Tool | What it does |
|
|
47
|
+
|------|--------------|
|
|
48
|
+
| `ground_compare` | Compare two files for similarity |
|
|
49
|
+
| `ground_count_uses` | Count symbol uses (distinguishes definitions vs actual uses) |
|
|
50
|
+
| `ground_check_connections` | Check if a module is connected (understands Workers) |
|
|
51
|
+
| `ground_find_duplicate_functions` | Find copied functions across files |
|
|
52
|
+
| `ground_find_orphans` | Find modules nothing imports |
|
|
53
|
+
| `ground_find_dead_exports` | Find exports never imported elsewhere |
|
|
54
|
+
| `ground_check_environment` | Detect Workers/Node.js API leakage |
|
|
55
|
+
| `ground_analyze` | Batch analysis: duplicates + orphans + dead exports |
|
|
56
|
+
| `ground_claim_*` | Make verified claims (requires checking first) |
|
|
57
|
+
|
|
58
|
+
## Usage Examples
|
|
59
|
+
|
|
60
|
+
Ask Claude:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Find duplicate functions in src/ with at least 10 lines
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
Check if the old-utils module is still connected to anything
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
Run ground_analyze on packages/sdk to find dead code
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Philosophy
|
|
75
|
+
|
|
76
|
+
Ground is based on a simple principle: **no claim without evidence**.
|
|
77
|
+
|
|
78
|
+
- **Duplicates** → You have to compare the files first
|
|
79
|
+
- **Dead code** → You have to count the uses first
|
|
80
|
+
- **Orphans** → You have to check the connections first
|
|
81
|
+
|
|
82
|
+
This prevents AI hallucination by requiring computation before synthesis.
|
|
83
|
+
|
|
84
|
+
## Links
|
|
85
|
+
|
|
86
|
+
- [Full Documentation](https://github.com/createsomethingtoday/create-something-monorepo/tree/main/packages/ground)
|
|
87
|
+
- [Case Study: Kickstand Triad Audit](https://createsomething.io/papers/kickstand-triad-audit)
|
|
88
|
+
- [CREATE SOMETHING Agency](https://createsomething.agency)
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT
|
package/bin/.gitkeep
ADDED
package/install.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Ground MCP - Binary installer
|
|
5
|
+
*
|
|
6
|
+
* Downloads the appropriate pre-built binary for the current platform.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { execSync } = require('child_process');
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const https = require('https');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const zlib = require('zlib');
|
|
14
|
+
|
|
15
|
+
const REPO = 'createsomethingtoday/create-something-monorepo';
|
|
16
|
+
const VERSION = require('./package.json').version;
|
|
17
|
+
|
|
18
|
+
// Platform mapping
|
|
19
|
+
const PLATFORMS = {
|
|
20
|
+
'darwin-arm64': 'darwin-arm64',
|
|
21
|
+
'darwin-x64': 'darwin-x64',
|
|
22
|
+
'linux-arm64': 'linux-arm64',
|
|
23
|
+
'linux-x64': 'linux-x64',
|
|
24
|
+
'win32-x64': 'win32-x64',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function getPlatformKey() {
|
|
28
|
+
const platform = process.platform;
|
|
29
|
+
const arch = process.arch;
|
|
30
|
+
return `${platform}-${arch}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getBinaryName() {
|
|
34
|
+
const key = getPlatformKey();
|
|
35
|
+
const name = PLATFORMS[key];
|
|
36
|
+
|
|
37
|
+
if (!name) {
|
|
38
|
+
console.error(`Unsupported platform: ${key}`);
|
|
39
|
+
console.error(`Supported platforms: ${Object.keys(PLATFORMS).join(', ')}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return name;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getDownloadUrl(binaryName) {
|
|
47
|
+
const ext = process.platform === 'win32' ? 'zip' : 'tar.gz';
|
|
48
|
+
// Tag format: ground-v0.1.0
|
|
49
|
+
return `https://github.com/${REPO}/releases/download/ground-v${VERSION}/ground-${binaryName}.${ext}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function download(url) {
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
const request = (url) => {
|
|
55
|
+
https.get(url, { headers: { 'User-Agent': 'ground-mcp-installer' } }, (response) => {
|
|
56
|
+
// Handle redirects
|
|
57
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
58
|
+
request(response.headers.location);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (response.statusCode !== 200) {
|
|
63
|
+
reject(new Error(`Download failed: HTTP ${response.statusCode}`));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const chunks = [];
|
|
68
|
+
response.on('data', (chunk) => chunks.push(chunk));
|
|
69
|
+
response.on('end', () => resolve(Buffer.concat(chunks)));
|
|
70
|
+
response.on('error', reject);
|
|
71
|
+
}).on('error', reject);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
request(url);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function extractTarGz(buffer, destDir) {
|
|
79
|
+
const { execSync } = require('child_process');
|
|
80
|
+
const tmpFile = path.join(destDir, 'archive.tar.gz');
|
|
81
|
+
|
|
82
|
+
fs.writeFileSync(tmpFile, buffer);
|
|
83
|
+
execSync(`tar -xzf "${tmpFile}" -C "${destDir}"`, { stdio: 'inherit' });
|
|
84
|
+
fs.unlinkSync(tmpFile);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function extractZip(buffer, destDir) {
|
|
88
|
+
const AdmZip = require('adm-zip');
|
|
89
|
+
const zip = new AdmZip(buffer);
|
|
90
|
+
zip.extractAllTo(destDir, true);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function install() {
|
|
94
|
+
console.log('Ground MCP: Installing binary...');
|
|
95
|
+
|
|
96
|
+
const binaryName = getBinaryName();
|
|
97
|
+
const url = getDownloadUrl(binaryName);
|
|
98
|
+
const binDir = path.join(__dirname, 'bin');
|
|
99
|
+
|
|
100
|
+
console.log(`Platform: ${getPlatformKey()}`);
|
|
101
|
+
console.log(`Downloading: ${url}`);
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
// Create bin directory
|
|
105
|
+
if (!fs.existsSync(binDir)) {
|
|
106
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Download archive
|
|
110
|
+
const buffer = await download(url);
|
|
111
|
+
console.log(`Downloaded ${(buffer.length / 1024 / 1024).toFixed(2)} MB`);
|
|
112
|
+
|
|
113
|
+
// Extract based on platform
|
|
114
|
+
if (process.platform === 'win32') {
|
|
115
|
+
// For Windows, we need adm-zip (optional dependency)
|
|
116
|
+
try {
|
|
117
|
+
await extractZip(buffer, binDir);
|
|
118
|
+
} catch (e) {
|
|
119
|
+
// Fallback: use PowerShell
|
|
120
|
+
const tmpFile = path.join(binDir, 'archive.zip');
|
|
121
|
+
fs.writeFileSync(tmpFile, buffer);
|
|
122
|
+
execSync(`powershell -Command "Expand-Archive -Path '${tmpFile}' -DestinationPath '${binDir}' -Force"`, { stdio: 'inherit' });
|
|
123
|
+
fs.unlinkSync(tmpFile);
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
await extractTarGz(buffer, binDir);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Make binaries executable (Unix)
|
|
130
|
+
if (process.platform !== 'win32') {
|
|
131
|
+
const groundMcp = path.join(binDir, 'ground-mcp');
|
|
132
|
+
const ground = path.join(binDir, 'ground');
|
|
133
|
+
|
|
134
|
+
if (fs.existsSync(groundMcp)) {
|
|
135
|
+
fs.chmodSync(groundMcp, 0o755);
|
|
136
|
+
}
|
|
137
|
+
if (fs.existsSync(ground)) {
|
|
138
|
+
fs.chmodSync(ground, 0o755);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
console.log('Ground MCP: Installation complete!');
|
|
143
|
+
console.log('');
|
|
144
|
+
console.log('Add to your .cursor/mcp.json:');
|
|
145
|
+
console.log('');
|
|
146
|
+
console.log(' {');
|
|
147
|
+
console.log(' "mcpServers": {');
|
|
148
|
+
console.log(' "ground": {');
|
|
149
|
+
console.log(' "command": "ground-mcp"');
|
|
150
|
+
console.log(' }');
|
|
151
|
+
console.log(' }');
|
|
152
|
+
console.log(' }');
|
|
153
|
+
console.log('');
|
|
154
|
+
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error('Ground MCP: Installation failed');
|
|
157
|
+
console.error(error.message);
|
|
158
|
+
console.error('');
|
|
159
|
+
console.error('You can manually download from:');
|
|
160
|
+
console.error(`https://github.com/${REPO}/releases`);
|
|
161
|
+
console.error('');
|
|
162
|
+
console.error('Or build from source:');
|
|
163
|
+
console.error(' cargo install --git https://github.com/' + REPO + ' --path packages/ground');
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Run installer
|
|
169
|
+
install();
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@createsomething/ground-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Grounded claims for code. MCP server that prevents AI hallucination in code analysis.",
|
|
5
|
+
"author": "CREATE SOMETHING <hello@createsomething.io>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/createsomethingtoday/create-something-monorepo",
|
|
10
|
+
"directory": "packages/ground"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/createsomethingtoday/create-something-monorepo/tree/main/packages/ground",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/createsomethingtoday/create-something-monorepo/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"model-context-protocol",
|
|
19
|
+
"ai",
|
|
20
|
+
"code-analysis",
|
|
21
|
+
"duplicate-detection",
|
|
22
|
+
"dead-code",
|
|
23
|
+
"grounding",
|
|
24
|
+
"llm",
|
|
25
|
+
"claude",
|
|
26
|
+
"cursor"
|
|
27
|
+
],
|
|
28
|
+
"bin": {
|
|
29
|
+
"ground-mcp": "bin/ground-mcp",
|
|
30
|
+
"ground": "bin/ground"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"postinstall": "node install.js"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"bin",
|
|
37
|
+
"install.js",
|
|
38
|
+
"README.md"
|
|
39
|
+
],
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=16"
|
|
42
|
+
},
|
|
43
|
+
"os": [
|
|
44
|
+
"darwin",
|
|
45
|
+
"linux",
|
|
46
|
+
"win32"
|
|
47
|
+
],
|
|
48
|
+
"cpu": [
|
|
49
|
+
"x64",
|
|
50
|
+
"arm64"
|
|
51
|
+
]
|
|
52
|
+
}
|