vibeshield-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.
@@ -0,0 +1,13 @@
1
+ {
2
+ "mcpServers": {
3
+ "vibeshield": {
4
+ "command": "node",
5
+ "args": [
6
+ "/home/glebs/VibeShield/vibeshield-mcp-shim/index.mjs"
7
+ ],
8
+ "env": {
9
+ "VIBESHIELD_TOKEN": "hoNWJ75uxe900YXmBJ1I1Weh9IWVNnkw"
10
+ }
11
+ }
12
+ }
13
+ }
package/index.mjs ADDED
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
5
+
6
+ // Product-owned (NOT user config)
7
+ const GATEWAY_URL = "https://vibeshield-gateway-651372710922.europe-north1.run.app";
8
+ const TOOL_PATH = "/mcp/tools/vibeshield.analyze_prompt";
9
+
10
+ // User-owned (only)
11
+ const TOKEN = process.env.VIBESHIELD_TOKEN ?? process.env.VIBESHIELD_API_KEY;
12
+
13
+ if (!TOKEN) {
14
+ console.error(
15
+ "VibeShield: missing VIBESHIELD_TOKEN. Copy your token from the VibeShield dashboard and paste it into your MCP server env."
16
+ );
17
+ process.exit(1);
18
+ }
19
+
20
+ const server = new Server(
21
+ { name: "vibeshield", version: "0.1.0" },
22
+ { capabilities: { tools: {} } }
23
+ );
24
+
25
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
26
+ tools: [
27
+ {
28
+ name: "analyze_prompt",
29
+ description:
30
+ "Analyze a plain-English prompt, select intent/policy packs, and return an injected rewrittenPrompt.",
31
+ inputSchema: {
32
+ type: "object",
33
+ properties: {
34
+ prompt: { type: "string", minLength: 1 },
35
+ context: { type: "object" },
36
+ },
37
+ required: ["prompt"],
38
+ additionalProperties: false,
39
+ },
40
+ },
41
+ ],
42
+ }));
43
+
44
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
45
+ if (request.params.name !== "analyze_prompt") {
46
+ return {
47
+ content: [{ type: "text", text: `Unknown tool: ${request.params.name}` }],
48
+ isError: true,
49
+ };
50
+ }
51
+
52
+ const args = request.params.arguments ?? {};
53
+ if (typeof args.prompt !== "string" || args.prompt.trim().length === 0) {
54
+ return {
55
+ content: [{ type: "text", text: "Invalid input: 'prompt' must be a non-empty string." }],
56
+ isError: true,
57
+ };
58
+ }
59
+
60
+ try {
61
+ const controller = new AbortController();
62
+ const timeoutId = setTimeout(() => controller.abort(), 60000);
63
+
64
+ const response = await fetch(`${GATEWAY_URL}${TOOL_PATH}`, {
65
+ method: "POST",
66
+ headers: {
67
+ "Content-Type": "application/json",
68
+ "Authorization": `Bearer ${TOKEN}`,
69
+ },
70
+ body: JSON.stringify({ prompt: args.prompt, context: args.context }),
71
+ signal: controller.signal,
72
+ });
73
+
74
+ clearTimeout(timeoutId);
75
+
76
+ const raw = await response.text();
77
+ if (!response.ok) {
78
+ if (response.status === 401 || response.status === 403) {
79
+ return {
80
+ content: [{ type: "text", text: "VibeShield token is invalid or revoked. Rotate it in the dashboard." }],
81
+ isError: true
82
+ };
83
+ }
84
+ if (response.status === 429) {
85
+ return {
86
+ content: [{ type: "text", text: "VibeShield rate limit exceeded. Try again later." }],
87
+ isError: true
88
+ };
89
+ }
90
+ return {
91
+ content: [{ type: "text", text: `VibeShield gateway error ${response.status}: ${raw}` }],
92
+ isError: true,
93
+ };
94
+ }
95
+
96
+ // Prefer returning rewrittenPrompt; fallback to raw
97
+ try {
98
+ const json = JSON.parse(raw);
99
+ return { content: [{ type: "text", text: json?.rewrittenPrompt ?? raw }] };
100
+ } catch {
101
+ return { content: [{ type: "text", text: raw }] };
102
+ }
103
+ } catch (error) {
104
+ if (error.name === 'AbortError') {
105
+ return { content: [{ type: "text", text: "VibeShield gateway timed out. Please try again." }], isError: true };
106
+ }
107
+ const message = error?.message ?? String(error);
108
+ console.error("VibeShield analyze_prompt failed:", message);
109
+ return { content: [{ type: "text", text: message }], isError: true };
110
+ }
111
+ });
112
+
113
+ await server.connect(new StdioServerTransport());
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "vibeshield-mcp",
3
+ "version": "0.1.0",
4
+ "description": "VibeShield MCP shim (stdio)",
5
+ "type": "module",
6
+ "bin": {
7
+ "vibeshield-mcp": "./index.mjs"
8
+ },
9
+ "engines": {
10
+ "node": ">=18"
11
+ },
12
+ "dependencies": {
13
+ "@modelcontextprotocol/sdk": "^1.0.0"
14
+ }
15
+ }
Binary file