@briefgate/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/LICENSE +21 -0
- package/README.md +329 -0
- package/dist/client.d.ts +128 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +138 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +188 -0
- package/dist/index.js.map +1 -0
- package/dist/tools.d.ts +616 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +591 -0
- package/dist/tools.js.map +1 -0
- package/dist/webhook.d.ts +54 -0
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +94 -0
- package/dist/webhook.js.map +1 -0
- package/package.json +68 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// BriefGate MCP server entrypoint.
|
|
3
|
+
// Supports two transports selected by CLI flags or environment variables:
|
|
4
|
+
// stdio (default) — for Claude Code, Cursor, and other local MCP clients
|
|
5
|
+
// --http [--port N] — Streamable HTTP for remote / multi-session usage
|
|
6
|
+
// also activated by: BRIEFGATE_MCP_HTTP=1
|
|
7
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
8
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
9
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
10
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
+
import { createServer } from 'node:http';
|
|
12
|
+
import { TOOLS, executeTool } from './tools.js';
|
|
13
|
+
// ─── Config ───────────────────────────────────────────────────────────────────
|
|
14
|
+
const apiKey = process.env['BRIEFGATE_API_KEY'];
|
|
15
|
+
const baseUrl = process.env['BRIEFGATE_BASE_URL'] ?? 'https://api.briefgate.dev';
|
|
16
|
+
// Warn early if BRIEFGATE_BASE_URL looks unsafe — it controls where API calls
|
|
17
|
+
// (including the Authorization header) are sent, so it must be an https URL in
|
|
18
|
+
// production. http:// localhost/127.0.0.1 is allowed for local development.
|
|
19
|
+
if (process.env['BRIEFGATE_BASE_URL']) {
|
|
20
|
+
const isLocalhostHttp = /^http:\/\/(?:localhost|127\.0\.0\.1)(:\d+)?(?:\/|$)/.test(baseUrl);
|
|
21
|
+
if (!baseUrl.startsWith('https://') && !isLocalhostHttp) {
|
|
22
|
+
process.stderr.write('Warning: BRIEFGATE_BASE_URL does not use https:// — API keys will be sent over an insecure connection.\n');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (!apiKey) {
|
|
26
|
+
// Start anyway so clients and registries (e.g. Glama, mcp.so) can
|
|
27
|
+
// introspect the tool list before a key is configured. Tool calls return
|
|
28
|
+
// a clear error until BRIEFGATE_API_KEY is set (see the CallTool handler).
|
|
29
|
+
process.stderr.write([
|
|
30
|
+
'Warning: BRIEFGATE_API_KEY is not set — tool calls will fail until it is.',
|
|
31
|
+
'Get an API key at https://briefgate.dev and set it in your MCP client config.',
|
|
32
|
+
'Example: BRIEFGATE_API_KEY=bg_live_... npx @briefgate/mcp',
|
|
33
|
+
'',
|
|
34
|
+
].join('\n'));
|
|
35
|
+
}
|
|
36
|
+
const config = {
|
|
37
|
+
apiKey: apiKey ?? '',
|
|
38
|
+
baseUrl,
|
|
39
|
+
};
|
|
40
|
+
// ─── Server factory ───────────────────────────────────────────────────────────
|
|
41
|
+
// Returns a fresh Server instance bound to the shared config.
|
|
42
|
+
// In HTTP mode we create one Server per request (stateless pattern).
|
|
43
|
+
function buildServer() {
|
|
44
|
+
const server = new Server({ name: '@briefgate/mcp', version: '0.1.0' }, { capabilities: { tools: {} } });
|
|
45
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
46
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
47
|
+
const { name, arguments: rawArgs } = request.params;
|
|
48
|
+
const args = (rawArgs ?? {});
|
|
49
|
+
if (!apiKey) {
|
|
50
|
+
return {
|
|
51
|
+
content: [
|
|
52
|
+
{
|
|
53
|
+
type: 'text',
|
|
54
|
+
text: 'Error: BRIEFGATE_API_KEY is not set. Get a key at https://briefgate.dev and add it to your MCP client config.',
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
isError: true,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const result = await executeTool(name, config, args);
|
|
62
|
+
return {
|
|
63
|
+
content: [{ type: 'text', text: result.text }],
|
|
64
|
+
...(result.isError ? { isError: true } : {}),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
69
|
+
return {
|
|
70
|
+
content: [{ type: 'text', text: message }],
|
|
71
|
+
isError: true,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return server;
|
|
76
|
+
}
|
|
77
|
+
// ─── Transport selection ──────────────────────────────────────────────────────
|
|
78
|
+
const argv = process.argv.slice(2);
|
|
79
|
+
const useHttp = argv.includes('--http') ||
|
|
80
|
+
process.env['BRIEFGATE_MCP_HTTP'] === '1';
|
|
81
|
+
if (useHttp) {
|
|
82
|
+
// ── Streamable HTTP transport ──────────────────────────────────────────────
|
|
83
|
+
// Parse --port N or fall back to env / default.
|
|
84
|
+
const portIndex = argv.indexOf('--port');
|
|
85
|
+
const portArg = portIndex !== -1 ? parseInt(argv[portIndex + 1] ?? '', 10) : NaN;
|
|
86
|
+
const port = !isNaN(portArg)
|
|
87
|
+
? portArg
|
|
88
|
+
: parseInt(process.env['BRIEFGATE_MCP_PORT'] ?? '', 10) || 3000;
|
|
89
|
+
// Bind to loopback only — DNS rebinding attacks require the server to accept
|
|
90
|
+
// requests from any origin; binding to 127.0.0.1 prevents cross-origin access
|
|
91
|
+
// from a browser-based attacker even when the Host header is spoofed.
|
|
92
|
+
const host = '127.0.0.1';
|
|
93
|
+
const httpServer = createServer(async (req, res) => {
|
|
94
|
+
// DNS rebinding guard: reject requests whose Host header does not resolve
|
|
95
|
+
// to a loopback address. A real browser attacker cannot spoof this header,
|
|
96
|
+
// but a misconfigured proxy or custom client might send something unexpected.
|
|
97
|
+
const host_ = req.headers['host'] ?? '';
|
|
98
|
+
if (!isSafeHost(host_)) {
|
|
99
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
100
|
+
res.end(JSON.stringify({ error: 'Invalid Host header — only localhost connections are accepted' }));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// CORS: allow claude.ai and localhost origins; reject everything else.
|
|
104
|
+
const origin = req.headers['origin'];
|
|
105
|
+
if (origin !== undefined) {
|
|
106
|
+
if (isSafeOrigin(origin)) {
|
|
107
|
+
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
108
|
+
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, DELETE, OPTIONS');
|
|
109
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, mcp-session-id');
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
res.writeHead(403, { 'Content-Type': 'application/json' });
|
|
113
|
+
res.end(JSON.stringify({ error: 'Origin not allowed' }));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (req.method === 'OPTIONS') {
|
|
118
|
+
res.writeHead(204).end();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// Stateless mode: one Server + one Transport per request.
|
|
122
|
+
// This is correct because MCP tool calls are independent request/response
|
|
123
|
+
// cycles — no shared streaming context is needed between calls.
|
|
124
|
+
const rawBody = await readBody(req);
|
|
125
|
+
let parsedBody;
|
|
126
|
+
try {
|
|
127
|
+
parsedBody = rawBody ? JSON.parse(rawBody) : undefined;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
131
|
+
res.end(JSON.stringify({ jsonrpc: '2.0', error: { code: -32700, message: 'Parse error' }, id: null }));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
135
|
+
const server = buildServer();
|
|
136
|
+
res.on('close', () => {
|
|
137
|
+
transport.close();
|
|
138
|
+
server.close();
|
|
139
|
+
});
|
|
140
|
+
try {
|
|
141
|
+
await server.connect(transport);
|
|
142
|
+
await transport.handleRequest(req, res, parsedBody);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
if (!res.headersSent) {
|
|
146
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
147
|
+
res.end(JSON.stringify({
|
|
148
|
+
jsonrpc: '2.0',
|
|
149
|
+
error: { code: -32603, message: 'Internal server error' },
|
|
150
|
+
id: null,
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
process.stderr.write(`BriefGate MCP HTTP error: ${String(err)}\n`);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
httpServer.listen(port, host, () => {
|
|
157
|
+
process.stderr.write(`BriefGate MCP server listening on http://${host}:${port}\n`);
|
|
158
|
+
});
|
|
159
|
+
httpServer.on('error', (err) => {
|
|
160
|
+
process.stderr.write(`BriefGate MCP HTTP server error: ${String(err)}\n`);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// ── stdio transport (default) ──────────────────────────────────────────────
|
|
166
|
+
const server = buildServer();
|
|
167
|
+
const transport = new StdioServerTransport();
|
|
168
|
+
await server.connect(transport);
|
|
169
|
+
}
|
|
170
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
171
|
+
function readBody(req) {
|
|
172
|
+
return new Promise((resolve, reject) => {
|
|
173
|
+
const chunks = [];
|
|
174
|
+
req.on('data', (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
175
|
+
req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
176
|
+
req.on('error', reject);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
const SAFE_HOST_RE = /^(?:localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/;
|
|
180
|
+
function isSafeHost(host) {
|
|
181
|
+
return SAFE_HOST_RE.test(host);
|
|
182
|
+
}
|
|
183
|
+
// Allow requests from localhost origins and claude.ai (which proxies MCP).
|
|
184
|
+
const SAFE_ORIGIN_RE = /^https?:\/\/(?:localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$|^https:\/\/claude\.ai$/;
|
|
185
|
+
function isSafeOrigin(origin) {
|
|
186
|
+
return SAFE_ORIGIN_RE.test(origin);
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|