maybethisone 0.1.0 → 0.2.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 +55 -2
- package/dist/index.js +43 -26
- package/dist/mcp.js +352 -0
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# maybethisone
|
|
2
2
|
|
|
3
|
-
A CLI tool to check name availability across multiple platforms - GitHub, npm, Twitter/X, LinkedIn, and domains.
|
|
3
|
+
A CLI tool and MCP server to check name availability across multiple platforms - GitHub, npm, Twitter/X, LinkedIn, and domains.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -73,11 +73,64 @@ Results for: myproject
|
|
|
73
73
|
| `~ No DNS` | No DNS record found (domain may still be registered - verify manually) |
|
|
74
74
|
| `? Error` | Check failed |
|
|
75
75
|
|
|
76
|
+
## MCP Server (for AI Agents)
|
|
77
|
+
|
|
78
|
+
maybethisone includes an MCP (Model Context Protocol) server that allows AI agents like Claude to check name availability.
|
|
79
|
+
|
|
80
|
+
### Tools Available
|
|
81
|
+
|
|
82
|
+
| Tool | Description |
|
|
83
|
+
| ---------------------------- | -------------------------------------------------------------- |
|
|
84
|
+
| `check_name_availability` | Full check - all platforms including social media (uses browser) |
|
|
85
|
+
| `check_name_availability_quick` | Quick check - GitHub, npm package, and .com domain only (no browser) |
|
|
86
|
+
|
|
87
|
+
### Claude Desktop Configuration
|
|
88
|
+
|
|
89
|
+
Add to your `claude_desktop_config.json`:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
"maybethisone": {
|
|
95
|
+
"command": "npx",
|
|
96
|
+
"args": ["maybethisone-mcp"]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Or if installed locally:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"mcpServers": {
|
|
107
|
+
"maybethisone": {
|
|
108
|
+
"command": "node",
|
|
109
|
+
"args": ["/path/to/maybethisone/dist/mcp.js"]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Example Response
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"name": "myproject",
|
|
120
|
+
"results": [
|
|
121
|
+
{ "resource": "github.com/orgs/myproject", "status": "available" },
|
|
122
|
+
{ "resource": "npm package: myproject", "status": "taken" },
|
|
123
|
+
{ "resource": "myproject.com", "status": "taken" }
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
76
128
|
## Project Structure
|
|
77
129
|
|
|
78
130
|
```
|
|
79
131
|
src/
|
|
80
|
-
├── index.ts #
|
|
132
|
+
├── index.ts # CLI entry point
|
|
133
|
+
├── mcp.ts # MCP server entry point
|
|
81
134
|
├── types.ts # TypeScript type definitions
|
|
82
135
|
├── checkers/
|
|
83
136
|
│ ├── index.ts # Re-exports all checkers
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,13 @@ async function getBrowserContext() {
|
|
|
33
33
|
}
|
|
34
34
|
return browserContext;
|
|
35
35
|
}
|
|
36
|
+
async function closeBrowser() {
|
|
37
|
+
if (browser) {
|
|
38
|
+
await browser.close();
|
|
39
|
+
browser = null;
|
|
40
|
+
browserContext = null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
36
43
|
|
|
37
44
|
// src/checkers/npm.ts
|
|
38
45
|
async function checkNpmPackage(name) {
|
|
@@ -145,7 +152,7 @@ async function checkDomain(name, extension) {
|
|
|
145
152
|
import { chromium as chromium2 } from "playwright";
|
|
146
153
|
var browser2 = null;
|
|
147
154
|
var browserContext2 = null;
|
|
148
|
-
async function
|
|
155
|
+
async function closeBrowser2() {
|
|
149
156
|
if (browser2) {
|
|
150
157
|
await browser2.close();
|
|
151
158
|
browser2 = null;
|
|
@@ -190,30 +197,34 @@ function formatStatus(result) {
|
|
|
190
197
|
return chalk2.red("\u2717 Taken");
|
|
191
198
|
}
|
|
192
199
|
async function checkAllForName(name) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
logProgress("Checking domains...");
|
|
210
|
-
const domainResults = await Promise.all(DOMAIN_EXTENSIONS.map(async (ext) => {
|
|
211
|
-
const result = await checkDomain(name, ext);
|
|
212
|
-
return { resource: `${name}${ext}`, ...result };
|
|
213
|
-
}));
|
|
214
|
-
results.push(...domainResults);
|
|
200
|
+
logProgress("Checking all platforms...");
|
|
201
|
+
const [
|
|
202
|
+
githubResult,
|
|
203
|
+
npmPkgResult,
|
|
204
|
+
npmOrgResult,
|
|
205
|
+
twitterResult,
|
|
206
|
+
linkedinResult,
|
|
207
|
+
...domainResults
|
|
208
|
+
] = await Promise.all([
|
|
209
|
+
checkGitHubOrg(name),
|
|
210
|
+
checkNpmPackage(name),
|
|
211
|
+
checkNpmOrg(name),
|
|
212
|
+
checkTwitter(name),
|
|
213
|
+
checkLinkedIn(name),
|
|
214
|
+
...DOMAIN_EXTENSIONS.map((ext) => checkDomain(name, ext))
|
|
215
|
+
]);
|
|
215
216
|
clearProgress();
|
|
216
|
-
return
|
|
217
|
+
return [
|
|
218
|
+
{ resource: `github.com/orgs/${name}`, ...githubResult },
|
|
219
|
+
{ resource: `npm package: ${name}`, ...npmPkgResult },
|
|
220
|
+
{ resource: `npm org: @${name}`, ...npmOrgResult },
|
|
221
|
+
{ resource: `x.com/${name}`, ...twitterResult },
|
|
222
|
+
{ resource: `linkedin.com/company/${name}`, ...linkedinResult },
|
|
223
|
+
...DOMAIN_EXTENSIONS.map((ext, i) => ({
|
|
224
|
+
resource: `${name}${ext}`,
|
|
225
|
+
...domainResults[i]
|
|
226
|
+
}))
|
|
227
|
+
];
|
|
217
228
|
}
|
|
218
229
|
function displayResults(name, results) {
|
|
219
230
|
console.log(chalk2.bold(`
|
|
@@ -247,6 +258,12 @@ function showUsage() {
|
|
|
247
258
|
console.log(" \u2022 Twitter/X username");
|
|
248
259
|
console.log(" \u2022 LinkedIn company page");
|
|
249
260
|
console.log(` \u2022 Domains (${DOMAIN_EXTENSIONS.join(", ")})
|
|
261
|
+
`);
|
|
262
|
+
console.log(chalk2.bold("MCP Server (for AI agents):"));
|
|
263
|
+
console.log(` maybethisone-mcp
|
|
264
|
+
`);
|
|
265
|
+
console.log(" Add to Claude Desktop config:");
|
|
266
|
+
console.log(` { "mcpServers": { "maybethisone": { "command": "npx", "args": ["maybethisone-mcp"] } } }
|
|
250
267
|
`);
|
|
251
268
|
}
|
|
252
269
|
function isValidName(name) {
|
|
@@ -275,10 +292,10 @@ async function main() {
|
|
|
275
292
|
await Bun.sleep(500);
|
|
276
293
|
}
|
|
277
294
|
}
|
|
278
|
-
await
|
|
295
|
+
await closeBrowser2();
|
|
279
296
|
}
|
|
280
297
|
main().catch(async (err) => {
|
|
281
298
|
console.error(err);
|
|
282
|
-
await
|
|
299
|
+
await closeBrowser2();
|
|
283
300
|
process.exit(1);
|
|
284
301
|
});
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/mcp.ts
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
8
|
+
// src/checkers/github.ts
|
|
9
|
+
async function checkGitHubOrg(name) {
|
|
10
|
+
try {
|
|
11
|
+
const response = await fetch(`https://github.com/orgs/${name}`, {
|
|
12
|
+
method: "HEAD",
|
|
13
|
+
redirect: "manual"
|
|
14
|
+
});
|
|
15
|
+
return { available: response.status === 404 };
|
|
16
|
+
} catch (error) {
|
|
17
|
+
return { available: null, error: error.message };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// src/utils/browser.ts
|
|
21
|
+
import { chromium } from "playwright";
|
|
22
|
+
var browser = null;
|
|
23
|
+
var browserContext = null;
|
|
24
|
+
async function getBrowserContext() {
|
|
25
|
+
if (!browser) {
|
|
26
|
+
browser = await chromium.launch({
|
|
27
|
+
headless: true,
|
|
28
|
+
args: ["--disable-blink-features=AutomationControlled"]
|
|
29
|
+
});
|
|
30
|
+
browserContext = await browser.newContext({
|
|
31
|
+
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return browserContext;
|
|
35
|
+
}
|
|
36
|
+
async function closeBrowser() {
|
|
37
|
+
if (browser) {
|
|
38
|
+
await browser.close();
|
|
39
|
+
browser = null;
|
|
40
|
+
browserContext = null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/checkers/npm.ts
|
|
45
|
+
async function checkNpmPackage(name) {
|
|
46
|
+
try {
|
|
47
|
+
const response = await fetch(`https://registry.npmjs.org/${name}`, {
|
|
48
|
+
method: "HEAD"
|
|
49
|
+
});
|
|
50
|
+
const isAvailable = response.status === 404;
|
|
51
|
+
return { available: isAvailable, maybeAvailable: isAvailable };
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return { available: null, error: error.message };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function checkNpmOrg(name) {
|
|
57
|
+
try {
|
|
58
|
+
const context = await getBrowserContext();
|
|
59
|
+
const page = await context.newPage();
|
|
60
|
+
await page.addInitScript(() => {
|
|
61
|
+
Object.defineProperty(navigator, "webdriver", { get: () => false });
|
|
62
|
+
});
|
|
63
|
+
await page.goto(`https://www.npmjs.com/org/${name}`, {
|
|
64
|
+
waitUntil: "load",
|
|
65
|
+
timeout: 30000
|
|
66
|
+
});
|
|
67
|
+
try {
|
|
68
|
+
await page.waitForFunction(() => !document.title.includes("moment"), { timeout: 15000 });
|
|
69
|
+
} catch {}
|
|
70
|
+
await page.waitForTimeout(1000);
|
|
71
|
+
const bodyText = await page.evaluate(() => document.body.innerText);
|
|
72
|
+
await page.close();
|
|
73
|
+
const notFoundPatterns = [
|
|
74
|
+
/scope not found/i,
|
|
75
|
+
/NotFoundError/i,
|
|
76
|
+
/couldn't find.*org/i
|
|
77
|
+
];
|
|
78
|
+
const isNotFound = notFoundPatterns.some((pattern) => pattern.test(bodyText));
|
|
79
|
+
return { available: isNotFound };
|
|
80
|
+
} catch (error) {
|
|
81
|
+
return { available: null, error: error.message };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// src/checkers/twitter.ts
|
|
85
|
+
async function checkTwitter(name) {
|
|
86
|
+
try {
|
|
87
|
+
const context = await getBrowserContext();
|
|
88
|
+
const page = await context.newPage();
|
|
89
|
+
await page.addInitScript(() => {
|
|
90
|
+
Object.defineProperty(navigator, "webdriver", { get: () => false });
|
|
91
|
+
});
|
|
92
|
+
await page.goto(`https://x.com/${name}`, {
|
|
93
|
+
waitUntil: "domcontentloaded",
|
|
94
|
+
timeout: 45000
|
|
95
|
+
});
|
|
96
|
+
await page.waitForTimeout(3000);
|
|
97
|
+
const bodyText = await page.evaluate(() => document.body.innerText);
|
|
98
|
+
await page.close();
|
|
99
|
+
const notFoundPatterns = [
|
|
100
|
+
/this account doesn.t exist/i,
|
|
101
|
+
/account suspended/i,
|
|
102
|
+
/doesn.t exist/i,
|
|
103
|
+
/hmm.*this page doesn.t exist/i
|
|
104
|
+
];
|
|
105
|
+
const isNotFound = notFoundPatterns.some((pattern) => pattern.test(bodyText));
|
|
106
|
+
return { available: isNotFound };
|
|
107
|
+
} catch (error) {
|
|
108
|
+
return { available: null, error: error.message };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// src/checkers/linkedin.ts
|
|
112
|
+
async function checkLinkedIn(name) {
|
|
113
|
+
try {
|
|
114
|
+
const context = await getBrowserContext();
|
|
115
|
+
const page = await context.newPage();
|
|
116
|
+
await page.addInitScript(() => {
|
|
117
|
+
Object.defineProperty(navigator, "webdriver", { get: () => false });
|
|
118
|
+
});
|
|
119
|
+
await page.goto(`https://www.linkedin.com/company/${name}`, {
|
|
120
|
+
waitUntil: "load",
|
|
121
|
+
timeout: 30000
|
|
122
|
+
});
|
|
123
|
+
await page.waitForTimeout(2000);
|
|
124
|
+
const bodyText = await page.evaluate(() => document.body.innerText);
|
|
125
|
+
const url = page.url();
|
|
126
|
+
await page.close();
|
|
127
|
+
const notFoundPatterns = [
|
|
128
|
+
/page not found/i,
|
|
129
|
+
/this page doesn.t exist/i,
|
|
130
|
+
/couldn.t find/i
|
|
131
|
+
];
|
|
132
|
+
const isNotFound = notFoundPatterns.some((pattern) => pattern.test(bodyText)) || url.includes("/404") || url.includes("pagenotfound");
|
|
133
|
+
return { available: isNotFound };
|
|
134
|
+
} catch (error) {
|
|
135
|
+
return { available: null, error: error.message };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// src/checkers/domain.ts
|
|
139
|
+
import { resolve } from "dns/promises";
|
|
140
|
+
async function checkDomain(name, extension) {
|
|
141
|
+
try {
|
|
142
|
+
await resolve(`${name}${extension}`);
|
|
143
|
+
return { available: false };
|
|
144
|
+
} catch (error) {
|
|
145
|
+
if (error.code === "ENOTFOUND" || error.code === "ENODATA") {
|
|
146
|
+
return { available: true, dnsOnly: true };
|
|
147
|
+
}
|
|
148
|
+
return { available: null, error: error.message };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// src/types.ts
|
|
152
|
+
var DOMAIN_EXTENSIONS = [".com", ".dev", ".io", ".org", ".net", ".co", ".app"];
|
|
153
|
+
|
|
154
|
+
// src/mcp.ts
|
|
155
|
+
var server = new McpServer({
|
|
156
|
+
name: "maybethisone",
|
|
157
|
+
version: "0.1.0"
|
|
158
|
+
});
|
|
159
|
+
function formatResult(result) {
|
|
160
|
+
if (result.error) {
|
|
161
|
+
return "error";
|
|
162
|
+
}
|
|
163
|
+
if (result.available) {
|
|
164
|
+
if (result.dnsOnly) {
|
|
165
|
+
return "no_dns";
|
|
166
|
+
}
|
|
167
|
+
if (result.maybeAvailable) {
|
|
168
|
+
return "maybe";
|
|
169
|
+
}
|
|
170
|
+
return "available";
|
|
171
|
+
}
|
|
172
|
+
return "taken";
|
|
173
|
+
}
|
|
174
|
+
async function checkAllForName(name) {
|
|
175
|
+
const [
|
|
176
|
+
githubResult,
|
|
177
|
+
npmPkgResult,
|
|
178
|
+
npmOrgResult,
|
|
179
|
+
twitterResult,
|
|
180
|
+
linkedinResult,
|
|
181
|
+
...domainResults
|
|
182
|
+
] = await Promise.all([
|
|
183
|
+
checkGitHubOrg(name),
|
|
184
|
+
checkNpmPackage(name),
|
|
185
|
+
checkNpmOrg(name),
|
|
186
|
+
checkTwitter(name),
|
|
187
|
+
checkLinkedIn(name),
|
|
188
|
+
...DOMAIN_EXTENSIONS.map((ext) => checkDomain(name, ext))
|
|
189
|
+
]);
|
|
190
|
+
return [
|
|
191
|
+
{ resource: `github.com/orgs/${name}`, ...githubResult },
|
|
192
|
+
{ resource: `npm package: ${name}`, ...npmPkgResult },
|
|
193
|
+
{ resource: `npm org: @${name}`, ...npmOrgResult },
|
|
194
|
+
{ resource: `x.com/${name}`, ...twitterResult },
|
|
195
|
+
{ resource: `linkedin.com/company/${name}`, ...linkedinResult },
|
|
196
|
+
...DOMAIN_EXTENSIONS.map((ext, i) => ({
|
|
197
|
+
resource: `${name}${ext}`,
|
|
198
|
+
...domainResults[i]
|
|
199
|
+
}))
|
|
200
|
+
];
|
|
201
|
+
}
|
|
202
|
+
server.tool("check_name_availability", "Check if a name is available across GitHub orgs, npm packages/orgs, Twitter/X, LinkedIn, and domains (.com, .dev, .io, .org, .net, .co, .app)", {
|
|
203
|
+
name: z.string().describe('The name to check availability for (e.g., "myproject")')
|
|
204
|
+
}, async ({ name }) => {
|
|
205
|
+
const validNamePattern = /^[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/;
|
|
206
|
+
if (!validNamePattern.test(name)) {
|
|
207
|
+
return {
|
|
208
|
+
content: [{
|
|
209
|
+
type: "text",
|
|
210
|
+
text: JSON.stringify({
|
|
211
|
+
error: "Invalid name format. Name must start and end with alphanumeric characters and can contain hyphens.",
|
|
212
|
+
name
|
|
213
|
+
}, null, 2)
|
|
214
|
+
}]
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
const results = await checkAllForName(name.toLowerCase());
|
|
219
|
+
await closeBrowser();
|
|
220
|
+
const formattedResults = results.map((r) => ({
|
|
221
|
+
resource: r.resource,
|
|
222
|
+
status: formatResult(r),
|
|
223
|
+
error: r.error || undefined
|
|
224
|
+
}));
|
|
225
|
+
const summary = {
|
|
226
|
+
name,
|
|
227
|
+
results: formattedResults,
|
|
228
|
+
legend: {
|
|
229
|
+
available: "Confirmed available",
|
|
230
|
+
taken: "Confirmed taken",
|
|
231
|
+
maybe: "npm package - may conflict with normalized names or private packages",
|
|
232
|
+
no_dns: "No DNS record found (domain may still be registered)",
|
|
233
|
+
error: "Check failed"
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
return {
|
|
237
|
+
content: [{
|
|
238
|
+
type: "text",
|
|
239
|
+
text: JSON.stringify(summary, null, 2)
|
|
240
|
+
}]
|
|
241
|
+
};
|
|
242
|
+
} catch (error) {
|
|
243
|
+
await closeBrowser();
|
|
244
|
+
return {
|
|
245
|
+
content: [{
|
|
246
|
+
type: "text",
|
|
247
|
+
text: JSON.stringify({
|
|
248
|
+
error: `Failed to check availability: ${error.message}`,
|
|
249
|
+
name
|
|
250
|
+
}, null, 2)
|
|
251
|
+
}],
|
|
252
|
+
isError: true
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
server.tool("check_name_availability_quick", "Quick check for name availability - only checks GitHub org, npm package, and .com domain (faster, no browser needed)", {
|
|
257
|
+
name: z.string().describe("The name to check availability for")
|
|
258
|
+
}, async ({ name }) => {
|
|
259
|
+
const validNamePattern = /^[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/;
|
|
260
|
+
if (!validNamePattern.test(name)) {
|
|
261
|
+
return {
|
|
262
|
+
content: [{
|
|
263
|
+
type: "text",
|
|
264
|
+
text: JSON.stringify({
|
|
265
|
+
error: "Invalid name format",
|
|
266
|
+
name
|
|
267
|
+
}, null, 2)
|
|
268
|
+
}]
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
const results = [];
|
|
273
|
+
const lowerName = name.toLowerCase();
|
|
274
|
+
const githubResult = await checkGitHubOrg(lowerName);
|
|
275
|
+
results.push({ resource: `github.com/orgs/${lowerName}`, ...githubResult });
|
|
276
|
+
const npmPkgResult = await checkNpmPackage(lowerName);
|
|
277
|
+
results.push({ resource: `npm package: ${lowerName}`, ...npmPkgResult });
|
|
278
|
+
const domainResult = await checkDomain(lowerName, ".com");
|
|
279
|
+
results.push({ resource: `${lowerName}.com`, ...domainResult });
|
|
280
|
+
const formattedResults = results.map((r) => ({
|
|
281
|
+
resource: r.resource,
|
|
282
|
+
status: formatResult(r),
|
|
283
|
+
error: r.error || undefined
|
|
284
|
+
}));
|
|
285
|
+
return {
|
|
286
|
+
content: [{
|
|
287
|
+
type: "text",
|
|
288
|
+
text: JSON.stringify({
|
|
289
|
+
name,
|
|
290
|
+
results: formattedResults
|
|
291
|
+
}, null, 2)
|
|
292
|
+
}]
|
|
293
|
+
};
|
|
294
|
+
} catch (error) {
|
|
295
|
+
return {
|
|
296
|
+
content: [{
|
|
297
|
+
type: "text",
|
|
298
|
+
text: JSON.stringify({
|
|
299
|
+
error: `Failed to check: ${error.message}`,
|
|
300
|
+
name
|
|
301
|
+
}, null, 2)
|
|
302
|
+
}],
|
|
303
|
+
isError: true
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
function logStartup() {
|
|
308
|
+
const msg = (text) => console.error(text);
|
|
309
|
+
const cwd = process.cwd();
|
|
310
|
+
msg("");
|
|
311
|
+
msg("✓ maybethisone MCP server running");
|
|
312
|
+
msg("");
|
|
313
|
+
msg("Available tools:");
|
|
314
|
+
msg(" • check_name_availability - Full check (all platforms, uses browser)");
|
|
315
|
+
msg(" • check_name_availability_quick - Quick check (GitHub, npm, .com only)");
|
|
316
|
+
msg("");
|
|
317
|
+
msg("Claude Desktop config (~/.config/claude/claude_desktop_config.json):");
|
|
318
|
+
msg("");
|
|
319
|
+
msg(" // If installed via npm");
|
|
320
|
+
msg(" {");
|
|
321
|
+
msg(' "mcpServers": {');
|
|
322
|
+
msg(' "maybethisone": {');
|
|
323
|
+
msg(' "command": "npx",');
|
|
324
|
+
msg(' "args": ["maybethisone-mcp"]');
|
|
325
|
+
msg(" }");
|
|
326
|
+
msg(" }");
|
|
327
|
+
msg(" }");
|
|
328
|
+
msg("");
|
|
329
|
+
msg(" // For local development");
|
|
330
|
+
msg(" {");
|
|
331
|
+
msg(' "mcpServers": {');
|
|
332
|
+
msg(' "maybethisone": {');
|
|
333
|
+
msg(' "command": "bun",');
|
|
334
|
+
msg(' "args": ["run", "src/mcp.ts"],');
|
|
335
|
+
msg(` "cwd": "${cwd}"`);
|
|
336
|
+
msg(" }");
|
|
337
|
+
msg(" }");
|
|
338
|
+
msg(" }");
|
|
339
|
+
msg("");
|
|
340
|
+
msg("Note: You don't need to run this manually.");
|
|
341
|
+
msg("Claude Desktop will start it automatically when configured.");
|
|
342
|
+
msg("");
|
|
343
|
+
}
|
|
344
|
+
async function main() {
|
|
345
|
+
logStartup();
|
|
346
|
+
const transport = new StdioServerTransport;
|
|
347
|
+
await server.connect(transport);
|
|
348
|
+
}
|
|
349
|
+
main().catch((error) => {
|
|
350
|
+
console.error("MCP server error:", error);
|
|
351
|
+
process.exit(1);
|
|
352
|
+
});
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maybethisone",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Check availability of GitHub orgs, npm packages, social media handles, and domains",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"maybethisone": "dist/index.js"
|
|
8
|
+
"maybethisone": "dist/index.js",
|
|
9
|
+
"maybethisone-mcp": "dist/mcp.js"
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"dist"
|
|
@@ -13,7 +14,8 @@
|
|
|
13
14
|
"scripts": {
|
|
14
15
|
"search": "bun run src/index.ts",
|
|
15
16
|
"dev": "bun --watch src/index.ts",
|
|
16
|
-
"
|
|
17
|
+
"mcp": "bun run src/mcp.ts",
|
|
18
|
+
"build": "bun build src/index.ts src/mcp.ts --outdir dist --target node --format esm --external playwright --external chalk --external cli-table3 --external @modelcontextprotocol/sdk --external zod",
|
|
17
19
|
"clean": "rm -rf dist",
|
|
18
20
|
"prebuild": "bun run clean",
|
|
19
21
|
"prepublishOnly": "bun run build",
|
|
@@ -37,14 +39,18 @@
|
|
|
37
39
|
"twitter",
|
|
38
40
|
"linkedin",
|
|
39
41
|
"cli",
|
|
42
|
+
"mcp",
|
|
43
|
+
"model-context-protocol",
|
|
40
44
|
"maybethisone"
|
|
41
45
|
],
|
|
42
46
|
"author": "",
|
|
43
47
|
"license": "MIT",
|
|
44
48
|
"dependencies": {
|
|
49
|
+
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
45
50
|
"chalk": "^5.4.1",
|
|
46
51
|
"cli-table3": "^0.6.5",
|
|
47
|
-
"playwright": "^1.57.0"
|
|
52
|
+
"playwright": "^1.57.0",
|
|
53
|
+
"zod": "^4.3.5"
|
|
48
54
|
},
|
|
49
55
|
"devDependencies": {
|
|
50
56
|
"@types/bun": "latest",
|