storkai 1.0.0 → 1.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/bin/storkai.js +48 -12
- package/package.json +1 -4
package/bin/storkai.js
CHANGED
|
@@ -6,16 +6,39 @@
|
|
|
6
6
|
* Install once: npx storkai
|
|
7
7
|
*
|
|
8
8
|
* https://www.stork.ai/mcp
|
|
9
|
+
*
|
|
10
|
+
* Zero dependencies — uses only Node.js built-in fetch().
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
13
|
import process from "node:process";
|
|
12
|
-
import { ConvexHttpClient } from "convex/browser";
|
|
13
14
|
|
|
14
15
|
const SERVER_NAME = "storkai";
|
|
15
|
-
const SERVER_VERSION = "1.0.
|
|
16
|
-
const CONVEX_URL = "https://expert-egret-407.convex.cloud";
|
|
16
|
+
const SERVER_VERSION = "1.0.1";
|
|
17
|
+
const CONVEX_URL = process.env.STORK_CONVEX_URL || "https://expert-egret-407.convex.cloud";
|
|
18
|
+
|
|
19
|
+
async function convexQuery(fnPath, args) {
|
|
20
|
+
const res = await fetch(`${CONVEX_URL}/api/query`, {
|
|
21
|
+
method: "POST",
|
|
22
|
+
headers: { "Content-Type": "application/json" },
|
|
23
|
+
body: JSON.stringify({ path: fnPath, args: args ?? {}, format: "json" }),
|
|
24
|
+
});
|
|
25
|
+
if (!res.ok) throw new Error(`Convex query failed: ${res.status}`);
|
|
26
|
+
const data = await res.json();
|
|
27
|
+
if (data.status === "error") throw new Error(data.errorMessage || "Query error");
|
|
28
|
+
return data.value;
|
|
29
|
+
}
|
|
17
30
|
|
|
18
|
-
|
|
31
|
+
async function convexAction(fnPath, args) {
|
|
32
|
+
const res = await fetch(`${CONVEX_URL}/api/action`, {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: { "Content-Type": "application/json" },
|
|
35
|
+
body: JSON.stringify({ path: fnPath, args: args ?? {}, format: "json" }),
|
|
36
|
+
});
|
|
37
|
+
if (!res.ok) throw new Error(`Convex action failed: ${res.status}`);
|
|
38
|
+
const data = await res.json();
|
|
39
|
+
if (data.status === "error") throw new Error(data.errorMessage || "Action error");
|
|
40
|
+
return data.value;
|
|
41
|
+
}
|
|
19
42
|
|
|
20
43
|
let stdinBuffer = Buffer.alloc(0);
|
|
21
44
|
|
|
@@ -115,15 +138,15 @@ function fmtCompare(d) {
|
|
|
115
138
|
|
|
116
139
|
const tools = [
|
|
117
140
|
{ name: "stork_search", description: "Search for MCP servers by natural language. Example: 'manage Jira tickets' or 'query Postgres databases'. Returns top matches with trust scores, tools, and install commands.", inputSchema: { type: "object", required: ["query"], properties: { query: { type: "string", description: "What you need the MCP server to do" }, category: { type: "string", description: "Category filter" }, transport: { type: "string", enum: ["stdio", "sse", "streamable-http"], description: "Transport filter" }, limit: { type: "number", minimum: 1, maximum: 10, description: "Max results (default 3)" } } },
|
|
118
|
-
handler: async (a) => { const args = { query: String(a.query || ""), category: a.category || undefined, transport: a.transport || undefined, limit: typeof a.limit === "number" ? a.limit : undefined }; try { return fmtSearch(await
|
|
141
|
+
handler: async (a) => { const args = { query: String(a.query || ""), category: a.category || undefined, transport: a.transport || undefined, limit: typeof a.limit === "number" ? a.limit : undefined }; try { return fmtSearch(await convexAction("mcpDiscoveryActions:semanticSearchServers", args)); } catch { return fmtSearch(await convexQuery("mcpDiscovery:searchServers", args)); } } },
|
|
119
142
|
{ name: "stork_server_details", description: "Get full details about an MCP server: tools, auth, trust scores, health, and more. Use the slug from search results.", inputSchema: { type: "object", required: ["slug"], properties: { slug: { type: "string", description: "Server slug" } } },
|
|
120
|
-
handler: async (a) => fmtDetails(await
|
|
143
|
+
handler: async (a) => fmtDetails(await convexQuery("mcpDiscovery:getServerDetails", { slug: String(a.slug) })) },
|
|
121
144
|
{ name: "stork_get_install_config", description: "Get ready-to-paste JSON config for installing an MCP server in your IDE. Supports cursor, claude-desktop, claude-code, vscode, and zed.", inputSchema: { type: "object", required: ["slug", "client"], properties: { slug: { type: "string", description: "Server slug" }, client: { type: "string", enum: ["cursor", "claude-desktop", "claude-code", "vscode", "zed"], description: "Target IDE" } } },
|
|
122
|
-
handler: async (a) => fmtConfig(await
|
|
145
|
+
handler: async (a) => fmtConfig(await convexQuery("mcpDiscovery:getInstallConfig", { slug: String(a.slug), client: String(a.client) })) },
|
|
123
146
|
{ name: "stork_compare", description: "Compare 2-5 MCP servers side by side on tools, trust, transport, auth, and more.", inputSchema: { type: "object", required: ["slugs"], properties: { slugs: { type: "array", items: { type: "string" }, minItems: 2, maxItems: 5, description: "Server slugs to compare" } } },
|
|
124
|
-
handler: async (a) => fmtCompare(await
|
|
147
|
+
handler: async (a) => fmtCompare(await convexQuery("mcpDiscovery:compareServers", { slugs: Array.isArray(a.slugs) ? a.slugs.map(String) : [] })) },
|
|
125
148
|
{ name: "stork_list_filters", description: "List available categories and hosting filters with server counts.", inputSchema: { type: "object", properties: {} },
|
|
126
|
-
handler: async () => { const r = await
|
|
149
|
+
handler: async () => { const r = await convexQuery("mcpServers:listServerFilters", {}); const l = ["# Available Filters\n"]; if (r?.categories?.length) { l.push("## Categories"); for (const c of r.categories) l.push(`- ${c.id} (${c.count})`); } if (r?.hosting?.length) { l.push("\n## Hosting"); for (const h of r.hosting) l.push(`- ${h.id} (${h.count})`); } return l.join("\n"); } },
|
|
127
150
|
{ name: "stork_submit", description: "Submit a new MCP server to Stork. Provide a GitHub repo URL or npm package name.", inputSchema: { type: "object", required: ["url"], properties: { url: { type: "string", description: "GitHub repo URL or npm package" }, name: { type: "string", description: "Display name" }, description: { type: "string", description: "What the server does" } } },
|
|
128
151
|
handler: async (a) => `Submission received for: ${a.url}\n\nTo complete registration, visit: https://www.stork.ai/mcp/submit\nYour server will be auto-enriched with metadata, tools, and trust signals.` },
|
|
129
152
|
];
|
|
@@ -149,8 +172,10 @@ async function handle(msg) {
|
|
|
149
172
|
return rpcError(id, -32601, `Method not found: ${method}`);
|
|
150
173
|
}
|
|
151
174
|
|
|
152
|
-
|
|
153
|
-
|
|
175
|
+
let pendingRequests = 0;
|
|
176
|
+
let stdinEnded = false;
|
|
177
|
+
|
|
178
|
+
async function processBuffer() {
|
|
154
179
|
while (true) {
|
|
155
180
|
let parsed;
|
|
156
181
|
try { parsed = parseOneMessage(stdinBuffer); } catch (err) {
|
|
@@ -166,9 +191,20 @@ process.stdin.on("data", async (chunk) => {
|
|
|
166
191
|
continue;
|
|
167
192
|
}
|
|
168
193
|
if (!("id" in msg)) { try { await handle(msg); } catch {} continue; }
|
|
194
|
+
pendingRequests++;
|
|
169
195
|
try { const r = await handle(msg); if (r) writeMessage(r); }
|
|
170
196
|
catch (err) { writeMessage(rpcError(msg.id ?? null, -32603, "Internal error", err?.message)); }
|
|
197
|
+
pendingRequests--;
|
|
198
|
+
if (stdinEnded && pendingRequests === 0) process.exit(0);
|
|
171
199
|
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
process.stdin.on("data", (chunk) => {
|
|
203
|
+
stdinBuffer = Buffer.concat([stdinBuffer, chunk]);
|
|
204
|
+
processBuffer();
|
|
172
205
|
});
|
|
173
206
|
|
|
174
|
-
process.stdin.on("end", () =>
|
|
207
|
+
process.stdin.on("end", () => {
|
|
208
|
+
stdinEnded = true;
|
|
209
|
+
if (pendingRequests === 0) process.exit(0);
|
|
210
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storkai",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "The MCP server for MCP servers. Search, discover, and configure MCP servers from inside your IDE.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,9 +30,6 @@
|
|
|
30
30
|
"type": "git",
|
|
31
31
|
"url": "https://github.com/stork-ai/storkai"
|
|
32
32
|
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"convex": "^1.31.2"
|
|
35
|
-
},
|
|
36
33
|
"engines": {
|
|
37
34
|
"node": ">=18.0.0"
|
|
38
35
|
}
|