@vinkius-core/mcp-fusion 2.8.0 → 2.9.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/dist/cli/fusion.d.ts +29 -0
- package/dist/cli/fusion.d.ts.map +1 -1
- package/dist/cli/fusion.js +202 -17
- package/dist/cli/fusion.js.map +1 -1
- package/dist/cli/scaffold.d.ts +10 -0
- package/dist/cli/scaffold.d.ts.map +1 -0
- package/dist/cli/scaffold.js +92 -0
- package/dist/cli/scaffold.js.map +1 -0
- package/dist/cli/templates/config.d.ts +14 -0
- package/dist/cli/templates/config.d.ts.map +1 -0
- package/dist/cli/templates/config.js +133 -0
- package/dist/cli/templates/config.js.map +1 -0
- package/dist/cli/templates/constants.d.ts +9 -0
- package/dist/cli/templates/constants.d.ts.map +1 -0
- package/dist/cli/templates/constants.js +9 -0
- package/dist/cli/templates/constants.js.map +1 -0
- package/dist/cli/templates/core.d.ts +14 -0
- package/dist/cli/templates/core.d.ts.map +1 -0
- package/dist/cli/templates/core.js +130 -0
- package/dist/cli/templates/core.js.map +1 -0
- package/dist/cli/templates/cursor.d.ts +8 -0
- package/dist/cli/templates/cursor.d.ts.map +1 -0
- package/dist/cli/templates/cursor.js +13 -0
- package/dist/cli/templates/cursor.js.map +1 -0
- package/dist/cli/templates/index.d.ts +17 -0
- package/dist/cli/templates/index.d.ts.map +1 -0
- package/dist/cli/templates/index.js +27 -0
- package/dist/cli/templates/index.js.map +1 -0
- package/dist/cli/templates/middleware.d.ts +7 -0
- package/dist/cli/templates/middleware.d.ts.map +1 -0
- package/dist/cli/templates/middleware.js +31 -0
- package/dist/cli/templates/middleware.js.map +1 -0
- package/dist/cli/templates/presenter.d.ts +7 -0
- package/dist/cli/templates/presenter.d.ts.map +1 -0
- package/dist/cli/templates/presenter.js +46 -0
- package/dist/cli/templates/presenter.js.map +1 -0
- package/dist/cli/templates/prompt.d.ts +7 -0
- package/dist/cli/templates/prompt.d.ts.map +1 -0
- package/dist/cli/templates/prompt.js +42 -0
- package/dist/cli/templates/prompt.js.map +1 -0
- package/dist/cli/templates/readme.d.ts +8 -0
- package/dist/cli/templates/readme.d.ts.map +1 -0
- package/dist/cli/templates/readme.js +177 -0
- package/dist/cli/templates/readme.js.map +1 -0
- package/dist/cli/templates/testing.d.ts +11 -0
- package/dist/cli/templates/testing.d.ts.map +1 -0
- package/dist/cli/templates/testing.js +100 -0
- package/dist/cli/templates/testing.js.map +1 -0
- package/dist/cli/templates/tools.d.ts +9 -0
- package/dist/cli/templates/tools.d.ts.map +1 -0
- package/dist/cli/templates/tools.js +66 -0
- package/dist/cli/templates/tools.js.map +1 -0
- package/dist/cli/templates/vectors/database.d.ts +9 -0
- package/dist/cli/templates/vectors/database.d.ts.map +1 -0
- package/dist/cli/templates/vectors/database.js +87 -0
- package/dist/cli/templates/vectors/database.js.map +1 -0
- package/dist/cli/templates/vectors/index.d.ts +9 -0
- package/dist/cli/templates/vectors/index.d.ts.map +1 -0
- package/dist/cli/templates/vectors/index.js +9 -0
- package/dist/cli/templates/vectors/index.js.map +1 -0
- package/dist/cli/templates/vectors/oauth.d.ts +10 -0
- package/dist/cli/templates/vectors/oauth.d.ts.map +1 -0
- package/dist/cli/templates/vectors/oauth.js +77 -0
- package/dist/cli/templates/vectors/oauth.js.map +1 -0
- package/dist/cli/templates/vectors/openapi.d.ts +10 -0
- package/dist/cli/templates/vectors/openapi.d.ts.map +1 -0
- package/dist/cli/templates/vectors/openapi.js +106 -0
- package/dist/cli/templates/vectors/openapi.js.map +1 -0
- package/dist/cli/templates/vectors/workflow.d.ts +7 -0
- package/dist/cli/templates/vectors/workflow.d.ts.map +1 -0
- package/dist/cli/templates/vectors/workflow.js +49 -0
- package/dist/cli/templates/vectors/workflow.js.map +1 -0
- package/dist/cli/types.d.ts +29 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +10 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/introspection/BehaviorDigest.d.ts.map +1 -1
- package/dist/introspection/BehaviorDigest.js +1 -0
- package/dist/introspection/BehaviorDigest.js.map +1 -1
- package/dist/introspection/CapabilityLockfile.d.ts +2 -0
- package/dist/introspection/CapabilityLockfile.d.ts.map +1 -1
- package/dist/introspection/CapabilityLockfile.js +1 -0
- package/dist/introspection/CapabilityLockfile.js.map +1 -1
- package/dist/introspection/ContractDiff.js +1 -1
- package/dist/introspection/ContractDiff.js.map +1 -1
- package/dist/introspection/EntitlementScanner.d.ts +63 -10
- package/dist/introspection/EntitlementScanner.d.ts.map +1 -1
- package/dist/introspection/EntitlementScanner.js +224 -9
- package/dist/introspection/EntitlementScanner.js.map +1 -1
- package/dist/introspection/ToolContract.d.ts +2 -0
- package/dist/introspection/ToolContract.d.ts.map +1 -1
- package/dist/introspection/ToolContract.js +1 -0
- package/dist/introspection/ToolContract.js.map +1 -1
- package/dist/introspection/index.d.ts +2 -2
- package/dist/introspection/index.d.ts.map +1 -1
- package/dist/introspection/index.js +1 -1
- package/dist/introspection/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/** Generate `README.md` with Claude/Cursor config snippets */
|
|
2
|
+
export function readme(config) {
|
|
3
|
+
const clientEntry = config.transport === 'sse'
|
|
4
|
+
? { url: 'http://localhost:3001/sse' }
|
|
5
|
+
: { command: 'npx', args: ['tsx', 'src/server.ts'] };
|
|
6
|
+
const clientConfig = JSON.stringify({
|
|
7
|
+
mcpServers: {
|
|
8
|
+
[config.name]: clientEntry,
|
|
9
|
+
},
|
|
10
|
+
}, null, 2);
|
|
11
|
+
const sseNote = config.transport === 'sse'
|
|
12
|
+
? `\n> **Note:** SSE transport requires the server to be running first. Run \\\`npm start\\\` before connecting.`
|
|
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
|
+
${config.transport === 'sse' ? 'npm start' : 'npm run 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
|
+
import { success } from '@vinkius-core/mcp-fusion';
|
|
74
|
+
|
|
75
|
+
export default f.tool({
|
|
76
|
+
name: 'my_domain.my_tool',
|
|
77
|
+
description: 'What this tool does',
|
|
78
|
+
input: {
|
|
79
|
+
query: { type: 'string', description: 'Search query' },
|
|
80
|
+
},
|
|
81
|
+
handler: async ({ input, ctx }) => {
|
|
82
|
+
return success({ result: input.query });
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
\`\`\`
|
|
86
|
+
|
|
87
|
+
No registration needed. The \`autoDiscover()\` system picks it up automatically.
|
|
88
|
+
|
|
89
|
+
## Documentation
|
|
90
|
+
|
|
91
|
+
- [MCP Fusion Docs](https://mcp-fusion.vinkius.com/)
|
|
92
|
+
- [Presenter — Egress Firewall](https://mcp-fusion.vinkius.com/presenter)
|
|
93
|
+
- [DX Guide — initFusion()](https://mcp-fusion.vinkius.com/dx-guide)
|
|
94
|
+
- [Testing](https://mcp-fusion.vinkius.com/testing)
|
|
95
|
+
`;
|
|
96
|
+
}
|
|
97
|
+
/** Vector-specific README section */
|
|
98
|
+
function vectorReadmeSection(config) {
|
|
99
|
+
switch (config.vector) {
|
|
100
|
+
case 'prisma':
|
|
101
|
+
return `
|
|
102
|
+
## Database Setup (Prisma)
|
|
103
|
+
|
|
104
|
+
1. Configure your database URL in \`.env\`:
|
|
105
|
+
\`\`\`
|
|
106
|
+
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
|
|
107
|
+
\`\`\`
|
|
108
|
+
|
|
109
|
+
2. Edit \`prisma/schema.prisma\` to define your models
|
|
110
|
+
|
|
111
|
+
3. Generate the Prisma client and Fusion tools:
|
|
112
|
+
\`\`\`bash
|
|
113
|
+
npm run db:generate
|
|
114
|
+
\`\`\`
|
|
115
|
+
|
|
116
|
+
4. Push the schema to your database:
|
|
117
|
+
\`\`\`bash
|
|
118
|
+
npm run db:push
|
|
119
|
+
\`\`\`
|
|
120
|
+
|
|
121
|
+
Use \`/// @fusion.hide\` on sensitive fields to strip them from the Egress Firewall.
|
|
122
|
+
`;
|
|
123
|
+
case 'n8n':
|
|
124
|
+
return `
|
|
125
|
+
## n8n Workflow Setup
|
|
126
|
+
|
|
127
|
+
1. Configure your n8n instance in \`.env\`:
|
|
128
|
+
\`\`\`
|
|
129
|
+
N8N_BASE_URL=http://localhost:5678
|
|
130
|
+
N8N_API_KEY=your-api-key
|
|
131
|
+
\`\`\`
|
|
132
|
+
|
|
133
|
+
2. The connector in \`src/n8n.ts\` auto-discovers webhook workflows
|
|
134
|
+
and registers them as MCP tools.
|
|
135
|
+
`;
|
|
136
|
+
case 'openapi':
|
|
137
|
+
return `
|
|
138
|
+
## OpenAPI Generator Setup
|
|
139
|
+
|
|
140
|
+
1. Replace \`openapi.yaml\` with your actual OpenAPI 3.x spec
|
|
141
|
+
|
|
142
|
+
2. Generate the MCP server from the spec:
|
|
143
|
+
\`\`\`bash
|
|
144
|
+
npx mcp-fusion-openapi-gen ./openapi.yaml --outDir ./src/generated
|
|
145
|
+
\`\`\`
|
|
146
|
+
|
|
147
|
+
3. Import and register the generated tools in \`src/server.ts\`
|
|
148
|
+
`;
|
|
149
|
+
case 'oauth':
|
|
150
|
+
return `
|
|
151
|
+
## OAuth Device Flow Setup
|
|
152
|
+
|
|
153
|
+
1. Configure your OAuth provider in \`.env\`:
|
|
154
|
+
\`\`\`
|
|
155
|
+
OAUTH_CLIENT_ID=your-client-id
|
|
156
|
+
OAUTH_AUTH_ENDPOINT=https://api.example.com/oauth/device/code
|
|
157
|
+
OAUTH_TOKEN_ENDPOINT=https://api.example.com/oauth/device/token
|
|
158
|
+
\`\`\`
|
|
159
|
+
|
|
160
|
+
2. The auth tool in \`src/auth.ts\` is pre-configured with login, complete, status, and logout actions.
|
|
161
|
+
|
|
162
|
+
3. Protect any tool with the \`withAuth\` middleware from \`src/middleware/auth.ts\`:
|
|
163
|
+
\`\`\`ts
|
|
164
|
+
import { withAuth } from '../middleware/auth.js';
|
|
165
|
+
|
|
166
|
+
export default f.tool({
|
|
167
|
+
name: 'protected.action',
|
|
168
|
+
middleware: [withAuth],
|
|
169
|
+
handler: async ({ ctx }) => { /* authenticated */ },
|
|
170
|
+
});
|
|
171
|
+
\`\`\`
|
|
172
|
+
`;
|
|
173
|
+
default:
|
|
174
|
+
return '';
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=readme.js.map
|
|
@@ -0,0 +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;;;;;;;;EAQzB,MAAM,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;;EAExD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;;;;;;CAMlB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BJ,OAAO;;;;;;;EAOP,YAAY;;EAEZ,mBAAmB,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B5B,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;;;;;;;;;;;;;;;;;;;;;;CAsBlB,CAAC;QACM;YACI,OAAO,EAAE,CAAC;IAClB,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Testing Templates — Test setup and example tests
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
/** Generate `vitest.config.ts` */
|
|
6
|
+
export declare function vitestConfig(): string;
|
|
7
|
+
/** Generate `tests/setup.ts` — Test infrastructure */
|
|
8
|
+
export declare function testSetupTs(): string;
|
|
9
|
+
/** Generate `tests/system.test.ts` — Egress Firewall + RBAC tests */
|
|
10
|
+
export declare function systemTestTs(): string;
|
|
11
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/testing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,kCAAkC;AAClC,wBAAgB,YAAY,IAAI,MAAM,CASrC;AAED,sDAAsD;AACtD,wBAAgB,WAAW,IAAI,MAAM,CAwBpC;AAED,qEAAqE;AACrE,wBAAgB,YAAY,IAAI,MAAM,CAwDrC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Testing Templates — Test setup and example tests
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
/** Generate `vitest.config.ts` */
|
|
6
|
+
export function vitestConfig() {
|
|
7
|
+
return `import { defineConfig } from 'vitest/config';
|
|
8
|
+
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
test: {
|
|
11
|
+
include: ['tests/**/*.test.ts'],
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
`;
|
|
15
|
+
}
|
|
16
|
+
/** Generate `tests/setup.ts` — Test infrastructure */
|
|
17
|
+
export function testSetupTs() {
|
|
18
|
+
return `/**
|
|
19
|
+
* Test Setup — In-Memory MVA Emulator
|
|
20
|
+
*
|
|
21
|
+
* Creates a FusionTester that runs the full pipeline
|
|
22
|
+
* (Zod → Middleware → Handler → Egress Firewall)
|
|
23
|
+
* without any network transport.
|
|
24
|
+
*
|
|
25
|
+
* 2ms per test. $0.00 in tokens. Zero servers.
|
|
26
|
+
*/
|
|
27
|
+
import { createFusionTester } from '@vinkius-core/mcp-fusion-testing';
|
|
28
|
+
import { ToolRegistry, autoDiscover } from '@vinkius-core/mcp-fusion';
|
|
29
|
+
import type { AppContext } from '../src/context.js';
|
|
30
|
+
|
|
31
|
+
const registry = new ToolRegistry<AppContext>();
|
|
32
|
+
await autoDiscover(registry, new URL('../src/tools', import.meta.url).pathname);
|
|
33
|
+
|
|
34
|
+
export const tester = createFusionTester(registry, {
|
|
35
|
+
contextFactory: () => ({
|
|
36
|
+
role: 'ADMIN' as const,
|
|
37
|
+
tenantId: 'test-tenant',
|
|
38
|
+
}),
|
|
39
|
+
});
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
/** Generate `tests/system.test.ts` — Egress Firewall + RBAC tests */
|
|
43
|
+
export function systemTestTs() {
|
|
44
|
+
return `/**
|
|
45
|
+
* System Tools — Egress Firewall & RBAC Tests
|
|
46
|
+
*
|
|
47
|
+
* Proves that:
|
|
48
|
+
* 1. The Presenter strips undeclared fields (SOC2 CC6.1)
|
|
49
|
+
* 2. RBAC middleware blocks GUEST access (SOC2 CC6.3)
|
|
50
|
+
* 3. System rules from .describe() are injected
|
|
51
|
+
*/
|
|
52
|
+
import { describe, it, expect } from 'vitest';
|
|
53
|
+
import { tester } from './setup.js';
|
|
54
|
+
|
|
55
|
+
describe('System Tools', () => {
|
|
56
|
+
describe('Egress Firewall', () => {
|
|
57
|
+
it('should return validated health data through the Presenter', async () => {
|
|
58
|
+
const result = await tester.callAction('system', 'health');
|
|
59
|
+
|
|
60
|
+
expect(result.isError).toBe(false);
|
|
61
|
+
expect(result.data).toHaveProperty('status');
|
|
62
|
+
expect(result.data).toHaveProperty('uptime');
|
|
63
|
+
expect(result.data).toHaveProperty('version');
|
|
64
|
+
expect(result.data).toHaveProperty('timestamp');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should strip undeclared fields (tenant must NOT leak)', async () => {
|
|
68
|
+
const result = await tester.callAction('system', 'health');
|
|
69
|
+
|
|
70
|
+
expect(result.isError).toBe(false);
|
|
71
|
+
// The handler returns 'tenant' but the Presenter schema
|
|
72
|
+
// does not declare it → stripped by Egress Firewall
|
|
73
|
+
expect(result.data).not.toHaveProperty('tenant');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should include JIT system rules from .describe()', async () => {
|
|
77
|
+
const result = await tester.callAction('system', 'health');
|
|
78
|
+
|
|
79
|
+
expect(result.systemRules.length).toBeGreaterThan(0);
|
|
80
|
+
expect(result.systemRules.some(
|
|
81
|
+
(r: string) => r.includes('uptime') || r.includes('Uptime')
|
|
82
|
+
)).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('Echo Tool', () => {
|
|
87
|
+
it('should echo the message back', async () => {
|
|
88
|
+
const result = await tester.callAction('system', 'echo', {
|
|
89
|
+
message: 'hello fusion',
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
expect(result.isError).toBe(false);
|
|
93
|
+
expect(result.data).toHaveProperty('echo', 'hello fusion');
|
|
94
|
+
expect(result.data).toHaveProperty('receivedAt');
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../../src/cli/templates/testing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,kCAAkC;AAClC,MAAM,UAAU,YAAY;IACxB,OAAO;;;;;;;CAOV,CAAC;AACF,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,WAAW;IACvB,OAAO;;;;;;;;;;;;;;;;;;;;;;CAsBV,CAAC;AACF,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,YAAY;IACxB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsDV,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Templates — Example tools for the scaffolded project
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
/** Generate `src/tools/system/health.ts` — Health check with Presenter */
|
|
6
|
+
export declare function healthToolTs(): string;
|
|
7
|
+
/** Generate `src/tools/system/echo.ts` — Simple echo tool */
|
|
8
|
+
export declare function echoToolTs(): string;
|
|
9
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/tools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,0EAA0E;AAC1E,wBAAgB,YAAY,IAAI,MAAM,CA+BrC;AAED,6DAA6D;AAC7D,wBAAgB,UAAU,IAAI,MAAM,CA0BnC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Templates — Example tools for the scaffolded project
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
/** Generate `src/tools/system/health.ts` — Health check with Presenter */
|
|
6
|
+
export function healthToolTs() {
|
|
7
|
+
return `/**
|
|
8
|
+
* System Health Tool — Full MVA Pipeline Example
|
|
9
|
+
*
|
|
10
|
+
* Demonstrates:
|
|
11
|
+
* - f.tool() with automatic context typing
|
|
12
|
+
* - Presenter integration (Egress Firewall)
|
|
13
|
+
* - readOnly annotation for LLM optimization
|
|
14
|
+
* - export default for autoDiscover()
|
|
15
|
+
*/
|
|
16
|
+
import { f } from '../../fusion.js';
|
|
17
|
+
import { SystemPresenter } from '../../presenters/SystemPresenter.js';
|
|
18
|
+
|
|
19
|
+
export default f.tool({
|
|
20
|
+
name: 'system.health',
|
|
21
|
+
description: 'Real-time server health status',
|
|
22
|
+
readOnly: true,
|
|
23
|
+
returns: SystemPresenter,
|
|
24
|
+
handler: async ({ ctx }) => {
|
|
25
|
+
// Return raw data — the Presenter validates, strips
|
|
26
|
+
// undeclared fields, injects rules, and renders UI.
|
|
27
|
+
return {
|
|
28
|
+
status: 'healthy',
|
|
29
|
+
uptime: process.uptime(),
|
|
30
|
+
version: '0.1.0',
|
|
31
|
+
timestamp: new Date().toISOString(),
|
|
32
|
+
tenant: ctx.tenantId,
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
`;
|
|
37
|
+
}
|
|
38
|
+
/** Generate `src/tools/system/echo.ts` — Simple echo tool */
|
|
39
|
+
export function echoToolTs() {
|
|
40
|
+
return `/**
|
|
41
|
+
* Echo Tool — Connectivity Testing
|
|
42
|
+
*
|
|
43
|
+
* Minimal tool without a Presenter. Uses success() for
|
|
44
|
+
* a raw JSON response. Useful for verifying the MCP
|
|
45
|
+
* connection is alive.
|
|
46
|
+
*/
|
|
47
|
+
import { f } from '../../fusion.js';
|
|
48
|
+
import { success } from '@vinkius-core/mcp-fusion';
|
|
49
|
+
|
|
50
|
+
export default f.tool({
|
|
51
|
+
name: 'system.echo',
|
|
52
|
+
description: 'Echo a message back (connectivity test)',
|
|
53
|
+
readOnly: true,
|
|
54
|
+
input: {
|
|
55
|
+
message: { type: 'string', description: 'Message to echo back' },
|
|
56
|
+
},
|
|
57
|
+
handler: async ({ input }) => {
|
|
58
|
+
return success({
|
|
59
|
+
echo: input.message,
|
|
60
|
+
receivedAt: new Date().toISOString(),
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/cli/templates/tools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,0EAA0E;AAC1E,MAAM,UAAU,YAAY;IACxB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BV,CAAC;AACF,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,UAAU;IACtB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;CAwBV,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Vector — Prisma schema + DB tool templates
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
/** Generate `prisma/schema.prisma` */
|
|
6
|
+
export declare function prismaSchema(): string;
|
|
7
|
+
/** Generate `src/tools/db/users.ts` */
|
|
8
|
+
export declare function dbUsersToolTs(): string;
|
|
9
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../../src/cli/templates/vectors/database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,sCAAsC;AACtC,wBAAgB,YAAY,IAAI,MAAM,CAgDrC;AAED,uCAAuC;AACvC,wBAAgB,aAAa,IAAI,MAAM,CA8BtC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Vector — Prisma schema + DB tool templates
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
/** Generate `prisma/schema.prisma` */
|
|
6
|
+
export function prismaSchema() {
|
|
7
|
+
return `// Prisma Schema — Database-Driven MCP Server
|
|
8
|
+
//
|
|
9
|
+
// The mcp-fusion-prisma-gen generator reads annotations
|
|
10
|
+
// and auto-generates Presenters + ToolBuilders with:
|
|
11
|
+
// - Field-level security (/// @fusion.hide)
|
|
12
|
+
// - Tenant isolation
|
|
13
|
+
// - OOM protection
|
|
14
|
+
|
|
15
|
+
generator client {
|
|
16
|
+
provider = "prisma-client-js"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
generator fusion {
|
|
20
|
+
provider = "mcp-fusion-prisma-gen"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
datasource db {
|
|
24
|
+
provider = "postgresql"
|
|
25
|
+
url = env("DATABASE_URL")
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
model User {
|
|
29
|
+
id String @id @default(cuid())
|
|
30
|
+
email String @unique
|
|
31
|
+
name String
|
|
32
|
+
|
|
33
|
+
/// @fusion.hide — Stripped by the Egress Firewall before reaching the LLM
|
|
34
|
+
password String
|
|
35
|
+
|
|
36
|
+
role String @default("USER")
|
|
37
|
+
createdAt DateTime @default(now())
|
|
38
|
+
updatedAt DateTime @updatedAt
|
|
39
|
+
|
|
40
|
+
posts Post[]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
model Post {
|
|
44
|
+
id String @id @default(cuid())
|
|
45
|
+
title String
|
|
46
|
+
content String?
|
|
47
|
+
published Boolean @default(false)
|
|
48
|
+
createdAt DateTime @default(now())
|
|
49
|
+
|
|
50
|
+
author User @relation(fields: [authorId], references: [id])
|
|
51
|
+
authorId String
|
|
52
|
+
}
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
/** Generate `src/tools/db/users.ts` */
|
|
56
|
+
export function dbUsersToolTs() {
|
|
57
|
+
return `/**
|
|
58
|
+
* Database Users Tool — Prisma-Driven CRUD
|
|
59
|
+
*
|
|
60
|
+
* Example tool that queries the database via Prisma.
|
|
61
|
+
* The Presenter strips the 'password' field before
|
|
62
|
+
* it reaches the LLM context.
|
|
63
|
+
*/
|
|
64
|
+
import { f } from '../../fusion.js';
|
|
65
|
+
import { success } from '@vinkius-core/mcp-fusion';
|
|
66
|
+
|
|
67
|
+
export default f.tool({
|
|
68
|
+
name: 'db.list_users',
|
|
69
|
+
description: 'List users from the database',
|
|
70
|
+
readOnly: true,
|
|
71
|
+
input: {
|
|
72
|
+
take: { type: 'number', min: 1, max: 50, optional: true, description: 'Max results' },
|
|
73
|
+
},
|
|
74
|
+
handler: async ({ input, ctx }) => {
|
|
75
|
+
// TODO: Replace with your Prisma client
|
|
76
|
+
// const users = await ctx.db.user.findMany({ take: input.take ?? 10 });
|
|
77
|
+
// return users;
|
|
78
|
+
|
|
79
|
+
return success({
|
|
80
|
+
hint: 'Connect your Prisma client in src/context.ts to enable database queries.',
|
|
81
|
+
example: 'const users = await ctx.db.user.findMany({ take: 10 })',
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
`;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../../src/cli/templates/vectors/database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,sCAAsC;AACtC,MAAM,UAAU,YAAY;IACxB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CV,CAAC;AACF,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,aAAa;IACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BV,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vector Templates — Barrel Export
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
export { prismaSchema, dbUsersToolTs } from './database.js';
|
|
6
|
+
export { n8nConnectorTs } from './workflow.js';
|
|
7
|
+
export { openapiYaml, openapiSetupMd } from './openapi.js';
|
|
8
|
+
export { oauthSetupTs, oauthMiddlewareTs } from './oauth.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/templates/vectors/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vector Templates — Barrel Export
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
export { prismaSchema, dbUsersToolTs } from './database.js';
|
|
6
|
+
export { n8nConnectorTs } from './workflow.js';
|
|
7
|
+
export { openapiYaml, openapiSetupMd } from './openapi.js';
|
|
8
|
+
export { oauthSetupTs, oauthMiddlewareTs } from './oauth.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cli/templates/vectors/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Vector — Device Flow Authentication templates
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import type { ProjectConfig } from '../../types.js';
|
|
6
|
+
/** Generate `src/auth.ts` — OAuth Device Flow setup */
|
|
7
|
+
export declare function oauthSetupTs(config: ProjectConfig): string;
|
|
8
|
+
/** Generate `src/middleware/auth.ts` — requireAuth middleware */
|
|
9
|
+
export declare function oauthMiddlewareTs(): string;
|
|
10
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../../src/cli/templates/vectors/oauth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAsC1D;AAED,iEAAiE;AACjE,wBAAgB,iBAAiB,IAAI,MAAM,CA8B1C"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Vector — Device Flow Authentication templates
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
/** Generate `src/auth.ts` — OAuth Device Flow setup */
|
|
6
|
+
export function oauthSetupTs(config) {
|
|
7
|
+
return `/**
|
|
8
|
+
* OAuth Setup — Device Flow Authentication (RFC 8628)
|
|
9
|
+
*
|
|
10
|
+
* Pre-configured \`createAuthTool()\` with login, complete, status, logout actions.
|
|
11
|
+
* The \`requireAuth()\` middleware protects any tool with one line.
|
|
12
|
+
*
|
|
13
|
+
* 1. Set CLIENT_ID and AUTH endpoints in .env
|
|
14
|
+
* 2. Register the auth tool in server.ts
|
|
15
|
+
* 3. Use \`requireAuth()\` on protected tools
|
|
16
|
+
*/
|
|
17
|
+
import { createAuthTool, TokenManager } from '@vinkius-core/mcp-fusion-oauth';
|
|
18
|
+
import type { ToolRegistry } from '@vinkius-core/mcp-fusion';
|
|
19
|
+
|
|
20
|
+
export function registerAuth<TContext>(registry: ToolRegistry<TContext>): void {
|
|
21
|
+
const clientId = process.env['OAUTH_CLIENT_ID'];
|
|
22
|
+
const authEndpoint = process.env['OAUTH_AUTH_ENDPOINT'];
|
|
23
|
+
const tokenEndpoint = process.env['OAUTH_TOKEN_ENDPOINT'];
|
|
24
|
+
|
|
25
|
+
if (!clientId || !authEndpoint || !tokenEndpoint) {
|
|
26
|
+
console.error('⚠️ OAUTH_CLIENT_ID, OAUTH_AUTH_ENDPOINT, OAUTH_TOKEN_ENDPOINT are required in .env');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const auth = createAuthTool({
|
|
31
|
+
clientId,
|
|
32
|
+
authorizationEndpoint: authEndpoint,
|
|
33
|
+
tokenEndpoint,
|
|
34
|
+
tokenManager: {
|
|
35
|
+
configDir: '.${config.name}',
|
|
36
|
+
envVar: '${config.name.toUpperCase().replace(/-/g, '_')}_TOKEN',
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
registry.register(auth);
|
|
41
|
+
console.error('🔐 OAuth Device Flow registered (auth.login → auth.complete → auth.status)');
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
/** Generate `src/middleware/auth.ts` — requireAuth middleware */
|
|
46
|
+
export function oauthMiddlewareTs() {
|
|
47
|
+
return `/**
|
|
48
|
+
* Auth Middleware — Protect tools with requireAuth()
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* \`\`\`ts
|
|
52
|
+
* import { withAuth } from '../middleware/auth.js';
|
|
53
|
+
*
|
|
54
|
+
* export default f.tool({
|
|
55
|
+
* name: 'projects.list',
|
|
56
|
+
* middleware: [withAuth],
|
|
57
|
+
* handler: async ({ ctx }) => { /* authenticated */ },
|
|
58
|
+
* });
|
|
59
|
+
* \`\`\`
|
|
60
|
+
*/
|
|
61
|
+
import { requireAuth } from '@vinkius-core/mcp-fusion-oauth';
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Pre-configured auth middleware.
|
|
65
|
+
* Rejects unauthenticated requests with \`AUTH_REQUIRED\` + self-healing hints.
|
|
66
|
+
*/
|
|
67
|
+
export const withAuth = requireAuth({
|
|
68
|
+
extractToken: (ctx: unknown) => {
|
|
69
|
+
const obj = ctx as Record<string, unknown>;
|
|
70
|
+
return typeof obj['token'] === 'string' ? obj['token'] : null;
|
|
71
|
+
},
|
|
72
|
+
recoveryHint: 'Call auth action=login to authenticate via browser',
|
|
73
|
+
recoveryAction: 'auth',
|
|
74
|
+
});
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../../../src/cli/templates/vectors/oauth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,uDAAuD;AACvD,MAAM,UAAU,YAAY,CAAC,MAAqB;IAC9C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BA4BgB,MAAM,CAAC,IAAI;uBACf,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;;;;;;;CAOlE,CAAC;AACF,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,iBAAiB;IAC7B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BV,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI Vector — Spec + setup templates
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import type { ProjectConfig } from '../../types.js';
|
|
6
|
+
/** Generate `openapi.yaml` — Sample OpenAPI spec */
|
|
7
|
+
export declare function openapiYaml(config: ProjectConfig): string;
|
|
8
|
+
/** Generate `SETUP.md` — OpenAPI generation instructions */
|
|
9
|
+
export declare function openapiSetupMd(): string;
|
|
10
|
+
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../../../src/cli/templates/vectors/openapi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAwEzD;AAED,4DAA4D;AAC5D,wBAAgB,cAAc,IAAI,MAAM,CA6BvC"}
|