@vinkius-core/mcp-fusion 3.0.1 → 3.1.2
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 +161 -161
- package/dist/cli/fusion.js +47 -47
- package/dist/cli/fusion.js.map +1 -1
- package/dist/cli/templates/config.js +28 -28
- package/dist/cli/templates/config.js.map +1 -1
- package/dist/cli/templates/core.js +127 -127
- package/dist/cli/templates/middleware.js +25 -25
- package/dist/cli/templates/readme.js +142 -142
- package/dist/cli/templates/readme.js.map +1 -1
- package/dist/cli/templates/testing.js +84 -84
- package/dist/cli/templates/tools.js +46 -46
- package/dist/cli/templates/vectors/database.js +69 -69
- package/dist/cli/templates/vectors/oauth.js +63 -63
- package/dist/cli/templates/vectors/openapi.js +97 -97
- package/dist/core/schema/SchemaGenerator.js +4 -1
- package/dist/core/schema/SchemaGenerator.js.map +1 -1
- package/dist/core/schema/SchemaUtils.d.ts +1 -1
- package/dist/core/schema/SchemaUtils.d.ts.map +1 -1
- package/dist/core/schema/SchemaUtils.js +4 -3
- package/dist/core/schema/SchemaUtils.js.map +1 -1
- package/dist/exposition/ExpositionCompiler.js +8 -1
- package/dist/exposition/ExpositionCompiler.js.map +1 -1
- package/dist/introspection/SemanticProbe.js +49 -49
- package/dist/prompt/FluentPromptBuilder.d.ts.map +1 -1
- package/package.json +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/cli/templates/config.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7F,wDAAwD;AACxD,MAAM,UAAU,WAAW,CAAC,MAAqB;IAC7C,MAAM,IAAI,GAA2B;QACjC,2BAA2B,EAAE,eAAe;QAC5C,0BAA0B,EAAE,YAAY;QACxC,KAAK,EAAE,WAAW;KACrB,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,gBAAgB,CAAC,GAAG,QAAQ,CAAC;QAClC,IAAI,CAAC,qCAAqC,CAAC,GAAG,QAAQ,CAAC;IAC3D,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,8BAA8B,CAAC,GAAG,QAAQ,CAAC;IACpD,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,sCAAsC,CAAC,GAAG,QAAQ,CAAC;IAC5D,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,gCAAgC,CAAC,GAAG,QAAQ,CAAC;IACtD,CAAC;IAED,MAAM,OAAO,GAA2B;QACpC,KAAK,EAAE,SAAS;QAChB,YAAY,EAAE,QAAQ;QACtB,aAAa,EAAE,SAAS;KAC3B,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;IACjC,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;QAC7B,OAAO,CAAC,kCAAkC,CAAC,GAAG,eAAe,CAAC;IAClE,CAAC;IAED,MAAM,OAAO,GAA2B;QACpC,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/cli/templates/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,145 +1,145 @@
|
|
|
1
1
|
/** Generate `src/fusion.ts` — The one-file context center */
|
|
2
2
|
export function fusionTs() {
|
|
3
|
-
return `/**
|
|
4
|
-
* Fusion Instance — Context Initialization
|
|
5
|
-
*
|
|
6
|
-
* Define your context type ONCE. Every f.query(), f.mutation(),
|
|
7
|
-
* f.presenter(), f.prompt(), and f.middleware() call inherits
|
|
8
|
-
* AppContext — zero generic repetition anywhere in the codebase.
|
|
9
|
-
*/
|
|
10
|
-
import { initFusion } from '@vinkius-core/mcp-fusion';
|
|
11
|
-
import type { AppContext } from './context.js';
|
|
12
|
-
|
|
13
|
-
export const f = initFusion<AppContext>();
|
|
3
|
+
return `/**
|
|
4
|
+
* Fusion Instance — Context Initialization
|
|
5
|
+
*
|
|
6
|
+
* Define your context type ONCE. Every f.query(), f.mutation(),
|
|
7
|
+
* f.presenter(), f.prompt(), and f.middleware() call inherits
|
|
8
|
+
* AppContext — zero generic repetition anywhere in the codebase.
|
|
9
|
+
*/
|
|
10
|
+
import { initFusion } from '@vinkius-core/mcp-fusion';
|
|
11
|
+
import type { AppContext } from './context.js';
|
|
12
|
+
|
|
13
|
+
export const f = initFusion<AppContext>();
|
|
14
14
|
`;
|
|
15
15
|
}
|
|
16
16
|
/** Generate `src/context.ts` — Application context type + factory */
|
|
17
17
|
export function contextTs() {
|
|
18
|
-
return `/**
|
|
19
|
-
* Application Context — Shared State for Every Tool Handler
|
|
20
|
-
*
|
|
21
|
-
* Every f.query() / f.mutation() handler receives (input, ctx)
|
|
22
|
-
* where ctx is this AppContext. Extend it with your own services
|
|
23
|
-
* (DB client, auth, external APIs, etc.)
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
export interface AppContext {
|
|
27
|
-
/** Current user role for RBAC checks */
|
|
28
|
-
role: 'ADMIN' | 'USER' | 'GUEST';
|
|
29
|
-
|
|
30
|
-
/** Tenant identifier (multi-tenancy) */
|
|
31
|
-
tenantId: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Create the application context for each tool invocation.
|
|
36
|
-
*
|
|
37
|
-
* In production, hydrate this from the MCP session metadata,
|
|
38
|
-
* JWT tokens, or environment variables.
|
|
39
|
-
*/
|
|
40
|
-
export function createContext(): AppContext {
|
|
41
|
-
return {
|
|
42
|
-
role: 'ADMIN',
|
|
43
|
-
tenantId: 'default',
|
|
44
|
-
};
|
|
45
|
-
}
|
|
18
|
+
return `/**
|
|
19
|
+
* Application Context — Shared State for Every Tool Handler
|
|
20
|
+
*
|
|
21
|
+
* Every f.query() / f.mutation() handler receives (input, ctx)
|
|
22
|
+
* where ctx is this AppContext. Extend it with your own services
|
|
23
|
+
* (DB client, auth, external APIs, etc.)
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
export interface AppContext {
|
|
27
|
+
/** Current user role for RBAC checks */
|
|
28
|
+
role: 'ADMIN' | 'USER' | 'GUEST';
|
|
29
|
+
|
|
30
|
+
/** Tenant identifier (multi-tenancy) */
|
|
31
|
+
tenantId: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Create the application context for each tool invocation.
|
|
36
|
+
*
|
|
37
|
+
* In production, hydrate this from the MCP session metadata,
|
|
38
|
+
* JWT tokens, or environment variables.
|
|
39
|
+
*/
|
|
40
|
+
export function createContext(): AppContext {
|
|
41
|
+
return {
|
|
42
|
+
role: 'ADMIN',
|
|
43
|
+
tenantId: 'default',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
46
|
`;
|
|
47
47
|
}
|
|
48
48
|
/** Generate `src/server.ts` — Bootstrap with autoDiscover + transport */
|
|
49
49
|
export function serverTs(config) {
|
|
50
50
|
if (config.transport === 'stdio') {
|
|
51
51
|
// Simplified: one-liner bootstrap via startServer()
|
|
52
|
-
return `/**
|
|
53
|
-
* Server Bootstrap — MCP Fusion
|
|
54
|
-
*
|
|
55
|
-
* Tools are auto-discovered from src/tools/.
|
|
56
|
-
* Drop a file, it becomes a tool.
|
|
57
|
-
*/
|
|
58
|
-
import { fileURLToPath } from 'node:url';
|
|
59
|
-
import { autoDiscover, PromptRegistry, startServer } from '@vinkius-core/mcp-fusion';
|
|
60
|
-
import { createContext } from './context.js';
|
|
61
|
-
import { f } from './fusion.js';
|
|
62
|
-
import { GreetPrompt } from './prompts/greet.js';
|
|
63
|
-
|
|
64
|
-
// ── Registry ─────────────────────────────────────────────
|
|
65
|
-
const registry = f.registry();
|
|
66
|
-
const prompts = new PromptRegistry();
|
|
67
|
-
|
|
68
|
-
// ── Auto-Discover & Register ─────────────────────────────
|
|
69
|
-
await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
|
|
70
|
-
prompts.register(GreetPrompt);
|
|
71
|
-
|
|
72
|
-
// ── Start ────────────────────────────────────────────────
|
|
73
|
-
await startServer({
|
|
74
|
-
name: '${config.name}',
|
|
75
|
-
registry,
|
|
76
|
-
prompts,
|
|
77
|
-
contextFactory: () => createContext(),
|
|
78
|
-
});
|
|
52
|
+
return `/**
|
|
53
|
+
* Server Bootstrap — MCP Fusion
|
|
54
|
+
*
|
|
55
|
+
* Tools are auto-discovered from src/tools/.
|
|
56
|
+
* Drop a file, it becomes a tool.
|
|
57
|
+
*/
|
|
58
|
+
import { fileURLToPath } from 'node:url';
|
|
59
|
+
import { autoDiscover, PromptRegistry, startServer } from '@vinkius-core/mcp-fusion';
|
|
60
|
+
import { createContext } from './context.js';
|
|
61
|
+
import { f } from './fusion.js';
|
|
62
|
+
import { GreetPrompt } from './prompts/greet.js';
|
|
63
|
+
|
|
64
|
+
// ── Registry ─────────────────────────────────────────────
|
|
65
|
+
const registry = f.registry();
|
|
66
|
+
const prompts = new PromptRegistry();
|
|
67
|
+
|
|
68
|
+
// ── Auto-Discover & Register ─────────────────────────────
|
|
69
|
+
await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
|
|
70
|
+
prompts.register(GreetPrompt);
|
|
71
|
+
|
|
72
|
+
// ── Start ────────────────────────────────────────────────
|
|
73
|
+
await startServer({
|
|
74
|
+
name: '${config.name}',
|
|
75
|
+
registry,
|
|
76
|
+
prompts,
|
|
77
|
+
contextFactory: () => createContext(),
|
|
78
|
+
});
|
|
79
79
|
`;
|
|
80
80
|
}
|
|
81
81
|
// SSE transport — manual setup required (startServer is stdio-only)
|
|
82
|
-
return `/**
|
|
83
|
-
* Server Bootstrap — MCP Fusion with SSE Transport
|
|
84
|
-
*
|
|
85
|
-
* Tools are auto-discovered from src/tools/.
|
|
86
|
-
* Drop a file, it becomes a tool.
|
|
87
|
-
*/
|
|
88
|
-
import { fileURLToPath } from 'node:url';
|
|
89
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
90
|
-
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
91
|
-
import { createServer } from 'node:http';
|
|
92
|
-
import { autoDiscover, PromptRegistry } from '@vinkius-core/mcp-fusion';
|
|
93
|
-
import { createContext } from './context.js';
|
|
94
|
-
import { f } from './fusion.js';
|
|
95
|
-
import { GreetPrompt } from './prompts/greet.js';
|
|
96
|
-
|
|
97
|
-
// ── Registry ─────────────────────────────────────────────
|
|
98
|
-
const registry = f.registry();
|
|
99
|
-
const prompts = new PromptRegistry();
|
|
100
|
-
|
|
101
|
-
// ── Auto-Discover & Register ─────────────────────────────
|
|
102
|
-
await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
|
|
103
|
-
prompts.register(GreetPrompt);
|
|
104
|
-
|
|
105
|
-
// ── Server ───────────────────────────────────────────────
|
|
106
|
-
const server = new Server(
|
|
107
|
-
{ name: '${config.name}', version: '0.1.0' },
|
|
108
|
-
{ capabilities: { tools: {}, prompts: {} } },
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
registry.attachToServer(server, {
|
|
112
|
-
contextFactory: () => createContext(),
|
|
113
|
-
prompts,
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// ── Transport ────────────────────────────────────────────
|
|
117
|
-
const PORT = Number(process.env['PORT'] ?? 3001);
|
|
118
|
-
const transports = new Map<string, SSEServerTransport>();
|
|
119
|
-
|
|
120
|
-
const httpServer = createServer(async (req, res) => {
|
|
121
|
-
if (req.method === 'GET' && req.url === '/sse') {
|
|
122
|
-
const sseTransport = new SSEServerTransport('/mcp/messages', res);
|
|
123
|
-
transports.set(sseTransport.sessionId, sseTransport);
|
|
124
|
-
res.on('close', () => transports.delete(sseTransport.sessionId));
|
|
125
|
-
await server.connect(sseTransport);
|
|
126
|
-
} else if (req.method === 'POST' && req.url?.startsWith('/mcp/messages')) {
|
|
127
|
-
const url = new URL(req.url, \`http://localhost:\${PORT}\`);
|
|
128
|
-
const sessionId = url.searchParams.get('sessionId') ?? '';
|
|
129
|
-
const transport = transports.get(sessionId);
|
|
130
|
-
if (transport) {
|
|
131
|
-
await transport.handlePostMessage(req, res);
|
|
132
|
-
} else {
|
|
133
|
-
res.writeHead(400).end('Unknown session');
|
|
134
|
-
}
|
|
135
|
-
} else {
|
|
136
|
-
res.writeHead(404).end();
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
httpServer.listen(PORT, () => {
|
|
141
|
-
console.error(\`⚡ MCP Fusion SSE server on http://localhost:\${PORT}/sse\`);
|
|
142
|
-
});
|
|
82
|
+
return `/**
|
|
83
|
+
* Server Bootstrap — MCP Fusion with SSE Transport
|
|
84
|
+
*
|
|
85
|
+
* Tools are auto-discovered from src/tools/.
|
|
86
|
+
* Drop a file, it becomes a tool.
|
|
87
|
+
*/
|
|
88
|
+
import { fileURLToPath } from 'node:url';
|
|
89
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
90
|
+
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
91
|
+
import { createServer } from 'node:http';
|
|
92
|
+
import { autoDiscover, PromptRegistry } from '@vinkius-core/mcp-fusion';
|
|
93
|
+
import { createContext } from './context.js';
|
|
94
|
+
import { f } from './fusion.js';
|
|
95
|
+
import { GreetPrompt } from './prompts/greet.js';
|
|
96
|
+
|
|
97
|
+
// ── Registry ─────────────────────────────────────────────
|
|
98
|
+
const registry = f.registry();
|
|
99
|
+
const prompts = new PromptRegistry();
|
|
100
|
+
|
|
101
|
+
// ── Auto-Discover & Register ─────────────────────────────
|
|
102
|
+
await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
|
|
103
|
+
prompts.register(GreetPrompt);
|
|
104
|
+
|
|
105
|
+
// ── Server ───────────────────────────────────────────────
|
|
106
|
+
const server = new Server(
|
|
107
|
+
{ name: '${config.name}', version: '0.1.0' },
|
|
108
|
+
{ capabilities: { tools: {}, prompts: {} } },
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
registry.attachToServer(server, {
|
|
112
|
+
contextFactory: () => createContext(),
|
|
113
|
+
prompts,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// ── Transport ────────────────────────────────────────────
|
|
117
|
+
const PORT = Number(process.env['PORT'] ?? 3001);
|
|
118
|
+
const transports = new Map<string, SSEServerTransport>();
|
|
119
|
+
|
|
120
|
+
const httpServer = createServer(async (req, res) => {
|
|
121
|
+
if (req.method === 'GET' && req.url === '/sse') {
|
|
122
|
+
const sseTransport = new SSEServerTransport('/mcp/messages', res);
|
|
123
|
+
transports.set(sseTransport.sessionId, sseTransport);
|
|
124
|
+
res.on('close', () => transports.delete(sseTransport.sessionId));
|
|
125
|
+
await server.connect(sseTransport);
|
|
126
|
+
} else if (req.method === 'POST' && req.url?.startsWith('/mcp/messages')) {
|
|
127
|
+
const url = new URL(req.url, \`http://localhost:\${PORT}\`);
|
|
128
|
+
const sessionId = url.searchParams.get('sessionId') ?? '';
|
|
129
|
+
const transport = transports.get(sessionId);
|
|
130
|
+
if (transport) {
|
|
131
|
+
await transport.handlePostMessage(req, res);
|
|
132
|
+
} else {
|
|
133
|
+
res.writeHead(400).end('Unknown session');
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
res.writeHead(404).end();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
httpServer.listen(PORT, () => {
|
|
141
|
+
console.error(\`⚡ MCP Fusion SSE server on http://localhost:\${PORT}/sse\`);
|
|
142
|
+
});
|
|
143
143
|
`;
|
|
144
144
|
}
|
|
145
145
|
//# sourceMappingURL=core.js.map
|
|
@@ -4,31 +4,31 @@
|
|
|
4
4
|
*/
|
|
5
5
|
/** Generate `src/middleware/auth.ts` — RBAC middleware */
|
|
6
6
|
export function authMiddlewareTs() {
|
|
7
|
-
return `/**
|
|
8
|
-
* Auth Middleware — RBAC Guard (Fluent API)
|
|
9
|
-
*
|
|
10
|
-
* Demonstrates f.middleware() — tRPC-style context derivation.
|
|
11
|
-
* Rejects GUEST requests with a structured error.
|
|
12
|
-
*
|
|
13
|
-
* Usage in tools:
|
|
14
|
-
* f.query('users.list')
|
|
15
|
-
* .use(withAuth)
|
|
16
|
-
* .handle(async (input, ctx) => {
|
|
17
|
-
* // ctx now has ctx.role guaranteed non-GUEST
|
|
18
|
-
* });
|
|
19
|
-
*
|
|
20
|
-
* In production, replace with JWT validation,
|
|
21
|
-
* API key checks, or OAuth token verification.
|
|
22
|
-
*/
|
|
23
|
-
import { f } from '../fusion.js';
|
|
24
|
-
import { error } from '@vinkius-core/mcp-fusion';
|
|
25
|
-
|
|
26
|
-
export const withAuth = f.middleware(async (ctx) => {
|
|
27
|
-
if (ctx.role === 'GUEST') {
|
|
28
|
-
throw error('Access denied. Authentication required.');
|
|
29
|
-
}
|
|
30
|
-
return { verified: true as const };
|
|
31
|
-
});
|
|
7
|
+
return `/**
|
|
8
|
+
* Auth Middleware — RBAC Guard (Fluent API)
|
|
9
|
+
*
|
|
10
|
+
* Demonstrates f.middleware() — tRPC-style context derivation.
|
|
11
|
+
* Rejects GUEST requests with a structured error.
|
|
12
|
+
*
|
|
13
|
+
* Usage in tools:
|
|
14
|
+
* f.query('users.list')
|
|
15
|
+
* .use(withAuth)
|
|
16
|
+
* .handle(async (input, ctx) => {
|
|
17
|
+
* // ctx now has ctx.role guaranteed non-GUEST
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* In production, replace with JWT validation,
|
|
21
|
+
* API key checks, or OAuth token verification.
|
|
22
|
+
*/
|
|
23
|
+
import { f } from '../fusion.js';
|
|
24
|
+
import { error } from '@vinkius-core/mcp-fusion';
|
|
25
|
+
|
|
26
|
+
export const withAuth = f.middleware(async (ctx) => {
|
|
27
|
+
if (ctx.role === 'GUEST') {
|
|
28
|
+
throw error('Access denied. Authentication required.');
|
|
29
|
+
}
|
|
30
|
+
return { verified: true as const };
|
|
31
|
+
});
|
|
32
32
|
`;
|
|
33
33
|
}
|
|
34
34
|
//# sourceMappingURL=middleware.js.map
|
|
@@ -11,160 +11,160 @@ export function readme(config) {
|
|
|
11
11
|
const sseNote = config.transport === 'sse'
|
|
12
12
|
? `\n> **Note:** SSE transport requires the server to be running first. Run \\\`npm start\\\` before connecting.`
|
|
13
13
|
: '';
|
|
14
|
-
return `# ${config.name}
|
|
15
|
-
|
|
16
|
-
MCP Server built with [MCP Fusion](https://mcp-fusion.vinkius.com/) — the MVA framework for the Model Context Protocol.
|
|
17
|
-
|
|
18
|
-
## Quick Start
|
|
19
|
-
|
|
20
|
-
\`\`\`bash
|
|
21
|
-
npm install
|
|
22
|
-
|
|
23
|
-
\`\`\`
|
|
24
|
-
${config.testing ? `
|
|
25
|
-
## Testing
|
|
26
|
-
|
|
27
|
-
\`\`\`bash
|
|
28
|
-
npm test
|
|
29
|
-
\`\`\`
|
|
30
|
-
` : ''}
|
|
31
|
-
## Project Structure
|
|
32
|
-
|
|
33
|
-
\`\`\`
|
|
34
|
-
src/
|
|
35
|
-
├── fusion.ts # initFusion<AppContext>() — context center
|
|
36
|
-
├── context.ts # AppContext type + factory
|
|
37
|
-
├── server.ts # Bootstrap with autoDiscover
|
|
38
|
-
├── tools/ # Drop a file → it's a tool (autoDiscover)
|
|
39
|
-
│ └── system/
|
|
40
|
-
│ ├── health.ts # Health check with Presenter
|
|
41
|
-
│ └── echo.ts # Echo for connectivity testing
|
|
42
|
-
├── presenters/ # MVA View Layer (Egress Firewall)
|
|
43
|
-
│ └── SystemPresenter.ts
|
|
44
|
-
├── prompts/ # MCP Prompt Engine
|
|
45
|
-
│ └── greet.ts
|
|
46
|
-
└── middleware/ # RBAC guards
|
|
47
|
-
└── auth.ts
|
|
48
|
-
\`\`\`
|
|
49
|
-
|
|
50
|
-
## Client Configuration
|
|
51
|
-
|
|
52
|
-
### Cursor Editor
|
|
53
|
-
|
|
54
|
-
> **Already configured!** The \`.cursor/mcp.json\` file was generated automatically.
|
|
55
|
-
> Just open this folder in Cursor and the server connects instantly.
|
|
56
|
-
${sseNote}
|
|
57
|
-
|
|
58
|
-
### Claude Desktop
|
|
59
|
-
|
|
60
|
-
Add to your \`claude_desktop_config.json\`:
|
|
61
|
-
|
|
62
|
-
\`\`\`json
|
|
63
|
-
${clientConfig}
|
|
64
|
-
\`\`\`
|
|
65
|
-
${vectorReadmeSection(config)}
|
|
66
|
-
## Adding New Tools
|
|
67
|
-
|
|
68
|
-
Create a new file in \`src/tools/\`. It's automatically discovered:
|
|
69
|
-
|
|
70
|
-
\`\`\`typescript
|
|
71
|
-
// src/tools/my-domain/my-tool.ts
|
|
72
|
-
import { f } from '../../fusion.js';
|
|
73
|
-
|
|
74
|
-
export default f.query('my_domain.my_tool')
|
|
75
|
-
.describe('What this tool does')
|
|
76
|
-
.withString('query', 'Search query')
|
|
77
|
-
.handle(async (input, ctx) => {
|
|
78
|
-
return { result: input.query };
|
|
79
|
-
});
|
|
80
|
-
\`\`\`
|
|
81
|
-
|
|
82
|
-
No registration needed. The \`autoDiscover()\` system picks it up automatically.
|
|
83
|
-
|
|
84
|
-
## Documentation
|
|
85
|
-
|
|
86
|
-
- [MCP Fusion Docs](https://mcp-fusion.vinkius.com/)
|
|
87
|
-
- [Presenter — Egress Firewall](https://mcp-fusion.vinkius.com/presenter)
|
|
88
|
-
- [DX Guide — initFusion()](https://mcp-fusion.vinkius.com/dx-guide)
|
|
89
|
-
- [Testing](https://mcp-fusion.vinkius.com/testing)
|
|
14
|
+
return `# ${config.name}
|
|
15
|
+
|
|
16
|
+
MCP Server built with [MCP Fusion](https://mcp-fusion.vinkius.com/) — the MVA framework for the Model Context Protocol.
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
\`\`\`bash
|
|
21
|
+
npm install
|
|
22
|
+
fusion dev
|
|
23
|
+
\`\`\`
|
|
24
|
+
${config.testing ? `
|
|
25
|
+
## Testing
|
|
26
|
+
|
|
27
|
+
\`\`\`bash
|
|
28
|
+
npm test
|
|
29
|
+
\`\`\`
|
|
30
|
+
` : ''}
|
|
31
|
+
## Project Structure
|
|
32
|
+
|
|
33
|
+
\`\`\`
|
|
34
|
+
src/
|
|
35
|
+
├── fusion.ts # initFusion<AppContext>() — context center
|
|
36
|
+
├── context.ts # AppContext type + factory
|
|
37
|
+
├── server.ts # Bootstrap with autoDiscover
|
|
38
|
+
├── tools/ # Drop a file → it's a tool (autoDiscover)
|
|
39
|
+
│ └── system/
|
|
40
|
+
│ ├── health.ts # Health check with Presenter
|
|
41
|
+
│ └── echo.ts # Echo for connectivity testing
|
|
42
|
+
├── presenters/ # MVA View Layer (Egress Firewall)
|
|
43
|
+
│ └── SystemPresenter.ts
|
|
44
|
+
├── prompts/ # MCP Prompt Engine
|
|
45
|
+
│ └── greet.ts
|
|
46
|
+
└── middleware/ # RBAC guards
|
|
47
|
+
└── auth.ts
|
|
48
|
+
\`\`\`
|
|
49
|
+
|
|
50
|
+
## Client Configuration
|
|
51
|
+
|
|
52
|
+
### Cursor Editor
|
|
53
|
+
|
|
54
|
+
> **Already configured!** The \`.cursor/mcp.json\` file was generated automatically.
|
|
55
|
+
> Just open this folder in Cursor and the server connects instantly.
|
|
56
|
+
${sseNote}
|
|
57
|
+
|
|
58
|
+
### Claude Desktop
|
|
59
|
+
|
|
60
|
+
Add to your \`claude_desktop_config.json\`:
|
|
61
|
+
|
|
62
|
+
\`\`\`json
|
|
63
|
+
${clientConfig}
|
|
64
|
+
\`\`\`
|
|
65
|
+
${vectorReadmeSection(config)}
|
|
66
|
+
## Adding New Tools
|
|
67
|
+
|
|
68
|
+
Create a new file in \`src/tools/\`. It's automatically discovered:
|
|
69
|
+
|
|
70
|
+
\`\`\`typescript
|
|
71
|
+
// src/tools/my-domain/my-tool.ts
|
|
72
|
+
import { f } from '../../fusion.js';
|
|
73
|
+
|
|
74
|
+
export default f.query('my_domain.my_tool')
|
|
75
|
+
.describe('What this tool does')
|
|
76
|
+
.withString('query', 'Search query')
|
|
77
|
+
.handle(async (input, ctx) => {
|
|
78
|
+
return { result: input.query };
|
|
79
|
+
});
|
|
80
|
+
\`\`\`
|
|
81
|
+
|
|
82
|
+
No registration needed. The \`autoDiscover()\` system picks it up automatically.
|
|
83
|
+
|
|
84
|
+
## Documentation
|
|
85
|
+
|
|
86
|
+
- [MCP Fusion Docs](https://mcp-fusion.vinkius.com/)
|
|
87
|
+
- [Presenter — Egress Firewall](https://mcp-fusion.vinkius.com/presenter)
|
|
88
|
+
- [DX Guide — initFusion()](https://mcp-fusion.vinkius.com/dx-guide)
|
|
89
|
+
- [Testing](https://mcp-fusion.vinkius.com/testing)
|
|
90
90
|
`;
|
|
91
91
|
}
|
|
92
92
|
/** Vector-specific README section */
|
|
93
93
|
function vectorReadmeSection(config) {
|
|
94
94
|
switch (config.vector) {
|
|
95
95
|
case 'prisma':
|
|
96
|
-
return `
|
|
97
|
-
## Database Setup (Prisma)
|
|
98
|
-
|
|
99
|
-
1. Configure your database URL in \`.env\`:
|
|
100
|
-
\`\`\`
|
|
101
|
-
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
|
|
102
|
-
\`\`\`
|
|
103
|
-
|
|
104
|
-
2. Edit \`prisma/schema.prisma\` to define your models
|
|
105
|
-
|
|
106
|
-
3. Generate the Prisma client and Fusion tools:
|
|
107
|
-
\`\`\`bash
|
|
108
|
-
npm run db:generate
|
|
109
|
-
\`\`\`
|
|
110
|
-
|
|
111
|
-
4. Push the schema to your database:
|
|
112
|
-
\`\`\`bash
|
|
113
|
-
npm run db:push
|
|
114
|
-
\`\`\`
|
|
115
|
-
|
|
116
|
-
Use \`/// @fusion.hide\` on sensitive fields to strip them from the Egress Firewall.
|
|
96
|
+
return `
|
|
97
|
+
## Database Setup (Prisma)
|
|
98
|
+
|
|
99
|
+
1. Configure your database URL in \`.env\`:
|
|
100
|
+
\`\`\`
|
|
101
|
+
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
|
|
102
|
+
\`\`\`
|
|
103
|
+
|
|
104
|
+
2. Edit \`prisma/schema.prisma\` to define your models
|
|
105
|
+
|
|
106
|
+
3. Generate the Prisma client and Fusion tools:
|
|
107
|
+
\`\`\`bash
|
|
108
|
+
npm run db:generate
|
|
109
|
+
\`\`\`
|
|
110
|
+
|
|
111
|
+
4. Push the schema to your database:
|
|
112
|
+
\`\`\`bash
|
|
113
|
+
npm run db:push
|
|
114
|
+
\`\`\`
|
|
115
|
+
|
|
116
|
+
Use \`/// @fusion.hide\` on sensitive fields to strip them from the Egress Firewall.
|
|
117
117
|
`;
|
|
118
118
|
case 'n8n':
|
|
119
|
-
return `
|
|
120
|
-
## n8n Workflow Setup
|
|
121
|
-
|
|
122
|
-
1. Configure your n8n instance in \`.env\`:
|
|
123
|
-
\`\`\`
|
|
124
|
-
N8N_BASE_URL=http://localhost:5678
|
|
125
|
-
N8N_API_KEY=your-api-key
|
|
126
|
-
\`\`\`
|
|
127
|
-
|
|
128
|
-
2. The connector in \`src/n8n.ts\` auto-discovers webhook workflows
|
|
129
|
-
and registers them as MCP tools.
|
|
119
|
+
return `
|
|
120
|
+
## n8n Workflow Setup
|
|
121
|
+
|
|
122
|
+
1. Configure your n8n instance in \`.env\`:
|
|
123
|
+
\`\`\`
|
|
124
|
+
N8N_BASE_URL=http://localhost:5678
|
|
125
|
+
N8N_API_KEY=your-api-key
|
|
126
|
+
\`\`\`
|
|
127
|
+
|
|
128
|
+
2. The connector in \`src/n8n.ts\` auto-discovers webhook workflows
|
|
129
|
+
and registers them as MCP tools.
|
|
130
130
|
`;
|
|
131
131
|
case 'openapi':
|
|
132
|
-
return `
|
|
133
|
-
## OpenAPI Generator Setup
|
|
134
|
-
|
|
135
|
-
1. Replace \`openapi.yaml\` with your actual OpenAPI 3.x spec
|
|
136
|
-
|
|
137
|
-
2. Generate the MCP server from the spec:
|
|
138
|
-
\`\`\`bash
|
|
139
|
-
npx @vinkius-core/mcp-fusion-openapi-gen ./openapi.yaml --outDir ./src/generated
|
|
140
|
-
\`\`\`
|
|
141
|
-
|
|
142
|
-
3. Import and register the generated tools in \`src/server.ts\`
|
|
132
|
+
return `
|
|
133
|
+
## OpenAPI Generator Setup
|
|
134
|
+
|
|
135
|
+
1. Replace \`openapi.yaml\` with your actual OpenAPI 3.x spec
|
|
136
|
+
|
|
137
|
+
2. Generate the MCP server from the spec:
|
|
138
|
+
\`\`\`bash
|
|
139
|
+
npx @vinkius-core/mcp-fusion-openapi-gen ./openapi.yaml --outDir ./src/generated
|
|
140
|
+
\`\`\`
|
|
141
|
+
|
|
142
|
+
3. Import and register the generated tools in \`src/server.ts\`
|
|
143
143
|
`;
|
|
144
144
|
case 'oauth':
|
|
145
|
-
return `
|
|
146
|
-
## OAuth Device Flow Setup
|
|
147
|
-
|
|
148
|
-
1. Configure your OAuth provider in \`.env\`:
|
|
149
|
-
\`\`\`
|
|
150
|
-
OAUTH_CLIENT_ID=your-client-id
|
|
151
|
-
OAUTH_AUTH_ENDPOINT=https://api.example.com/oauth/device/code
|
|
152
|
-
OAUTH_TOKEN_ENDPOINT=https://api.example.com/oauth/device/token
|
|
153
|
-
\`\`\`
|
|
154
|
-
|
|
155
|
-
2. The auth tool in \`src/auth.ts\` is pre-configured with login, complete, status, and logout actions.
|
|
156
|
-
|
|
157
|
-
3. Protect any tool with the \`withAuth\` middleware from \`src/middleware/auth.ts\`:
|
|
158
|
-
\`\`\`ts
|
|
159
|
-
import { withAuth } from '../middleware/auth.js';
|
|
160
|
-
|
|
161
|
-
export default f.query('protected.action')
|
|
162
|
-
.describe('A protected query')
|
|
163
|
-
.use(withAuth)
|
|
164
|
-
.handle(async (input, ctx) => {
|
|
165
|
-
// ctx is authenticated
|
|
166
|
-
});
|
|
167
|
-
\`\`\`
|
|
145
|
+
return `
|
|
146
|
+
## OAuth Device Flow Setup
|
|
147
|
+
|
|
148
|
+
1. Configure your OAuth provider in \`.env\`:
|
|
149
|
+
\`\`\`
|
|
150
|
+
OAUTH_CLIENT_ID=your-client-id
|
|
151
|
+
OAUTH_AUTH_ENDPOINT=https://api.example.com/oauth/device/code
|
|
152
|
+
OAUTH_TOKEN_ENDPOINT=https://api.example.com/oauth/device/token
|
|
153
|
+
\`\`\`
|
|
154
|
+
|
|
155
|
+
2. The auth tool in \`src/auth.ts\` is pre-configured with login, complete, status, and logout actions.
|
|
156
|
+
|
|
157
|
+
3. Protect any tool with the \`withAuth\` middleware from \`src/middleware/auth.ts\`:
|
|
158
|
+
\`\`\`ts
|
|
159
|
+
import { withAuth } from '../middleware/auth.js';
|
|
160
|
+
|
|
161
|
+
export default f.query('protected.action')
|
|
162
|
+
.describe('A protected query')
|
|
163
|
+
.use(withAuth)
|
|
164
|
+
.handle(async (input, ctx) => {
|
|
165
|
+
// ctx is authenticated
|
|
166
|
+
});
|
|
167
|
+
\`\`\`
|
|
168
168
|
`;
|
|
169
169
|
default:
|
|
170
170
|
return '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readme.js","sourceRoot":"","sources":["../../../src/cli/templates/readme.ts"],"names":[],"mappings":"AAMA,8DAA8D;AAC9D,MAAM,UAAU,MAAM,CAAC,MAAqB;IACxC,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,KAAK,KAAK;QAC1C,CAAC,CAAC,EAAE,GAAG,EAAE,2BAA2B,EAAE;QACtC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC;IAEzD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,UAAU,EAAE;YACR,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW;SAC7B;KACJ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAEZ,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,KAAK,KAAK;QACtC,CAAC,CAAC,+GAA+G;QACjH,CAAC,CAAC,EAAE,CAAC;IAET,OAAO,KAAK,MAAM,CAAC,IAAI
|
|
1
|
+
{"version":3,"file":"readme.js","sourceRoot":"","sources":["../../../src/cli/templates/readme.ts"],"names":[],"mappings":"AAMA,8DAA8D;AAC9D,MAAM,UAAU,MAAM,CAAC,MAAqB;IACxC,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,KAAK,KAAK;QAC1C,CAAC,CAAC,EAAE,GAAG,EAAE,2BAA2B,EAAE;QACtC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC;IAEzD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,UAAU,EAAE;YACR,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW;SAC7B;KACJ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAEZ,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,KAAK,KAAK;QACtC,CAAC,CAAC,+GAA+G;QACjH,CAAC,CAAC,EAAE,CAAC;IAET,OAAO,KAAK,MAAM,CAAC,IAAI;;;;;;;;;;EAUzB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;;;;;;CAMlB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BJ,OAAO;;;;;;;EAOP,YAAY;;EAEZ,mBAAmB,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;CAyB5B,CAAC;AACF,CAAC;AAED,qCAAqC;AACrC,SAAS,mBAAmB,CAAC,MAAqB;IAC9C,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;QACpB,KAAK,QAAQ;YACT,OAAO;;;;;;;;;;;;;;;;;;;;;CAqBlB,CAAC;QACM,KAAK,KAAK;YACN,OAAO;;;;;;;;;;;CAWlB,CAAC;QACM,KAAK,SAAS;YACV,OAAO;;;;;;;;;;;CAWlB,CAAC;QACM,KAAK,OAAO;YACR,OAAO;;;;;;;;;;;;;;;;;;;;;;;CAuBlB,CAAC;QACM;YACI,OAAO,EAAE,CAAC;IAClB,CAAC;AACL,CAAC"}
|