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