@vurb/core 3.12.7 → 3.12.8

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.
@@ -1,113 +1,113 @@
1
1
  /** Generate `src/vurb.ts` — The one-file context center */
2
2
  export function vurbTs() {
3
- return `/**
4
- * Vurb 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 { initVurb } from '@vurb/core';
11
- import type { AppContext } from './context.js';
12
-
13
- export const f = initVurb<AppContext>();
3
+ return `/**
4
+ * Vurb 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 { initVurb } from '@vurb/core';
11
+ import type { AppContext } from './context.js';
12
+
13
+ export const f = initVurb<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 — Vurb
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 '@vurb/core';
60
- import { createContext } from './context.js';
61
- import { f } from './vurb.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 — Vurb
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 '@vurb/core';
60
+ import { createContext } from './context.js';
61
+ import { f } from './vurb.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
  // Streamable HTTP transport — startServer handles all HTTP plumbing
82
- return `/**
83
- * Server Bootstrap — Vurb with Streamable HTTP 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 { autoDiscover, PromptRegistry, startServer } from '@vurb/core';
90
- import { createContext } from './context.js';
91
- import { f } from './vurb.js';
92
- import { GreetPrompt } from './prompts/greet.js';
93
-
94
- // ── Registry ─────────────────────────────────────────────
95
- const registry = f.registry();
96
- const prompts = new PromptRegistry();
97
-
98
- // ── Auto-Discover & Register ─────────────────────────────
99
- await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
100
- prompts.register(GreetPrompt);
101
-
102
- // ── Start ────────────────────────────────────────────────
103
- await startServer({
104
- name: '${config.name}',
105
- registry,
106
- prompts,
107
- contextFactory: () => createContext(),
108
- transport: 'http',
109
- port: Number(process.env['PORT'] ?? 3001),
110
- });
82
+ return `/**
83
+ * Server Bootstrap — Vurb with Streamable HTTP 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 { autoDiscover, PromptRegistry, startServer } from '@vurb/core';
90
+ import { createContext } from './context.js';
91
+ import { f } from './vurb.js';
92
+ import { GreetPrompt } from './prompts/greet.js';
93
+
94
+ // ── Registry ─────────────────────────────────────────────
95
+ const registry = f.registry();
96
+ const prompts = new PromptRegistry();
97
+
98
+ // ── Auto-Discover & Register ─────────────────────────────
99
+ await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
100
+ prompts.register(GreetPrompt);
101
+
102
+ // ── Start ────────────────────────────────────────────────
103
+ await startServer({
104
+ name: '${config.name}',
105
+ registry,
106
+ prompts,
107
+ contextFactory: () => createContext(),
108
+ transport: 'http',
109
+ port: Number(process.env['PORT'] ?? 3001),
110
+ });
111
111
  `;
112
112
  }
113
113
  //# 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 '../vurb.js';
24
- import { error } from '@vurb/core';
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 '../vurb.js';
24
+ import { error } from '@vurb/core';
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
@@ -4,28 +4,28 @@
4
4
  */
5
5
  /** Generate `src/models/SystemModel.ts` */
6
6
  export function systemModelTs() {
7
- return `/**
8
- * System Model — MVA Domain Layer (defineModel)
9
- *
10
- * Defines the shape of system health data using defineModel().
11
- * The Model provides:
12
- * - Field types with m.string(), m.number(), etc.
13
- * - .describe() annotations that become JIT system rules
14
- * - Validation and casting for the domain entity
15
- *
16
- * The Presenter references this Model instead of raw z.object(),
17
- * keeping a single source of truth for the data shape.
18
- */
19
- import { defineModel } from '@vurb/core';
20
-
21
- export const SystemModel = defineModel('SystemHealth', m => {
22
- m.casts({
23
- status: m.string('Server operational status'),
24
- uptime: m.number('Uptime in seconds since process start'),
25
- version: m.string('Server version string'),
26
- timestamp: m.string('ISO 8601 timestamp of this check'),
27
- });
28
- });
7
+ return `/**
8
+ * System Model — MVA Domain Layer (defineModel)
9
+ *
10
+ * Defines the shape of system health data using defineModel().
11
+ * The Model provides:
12
+ * - Field types with m.string(), m.number(), etc.
13
+ * - .describe() annotations that become JIT system rules
14
+ * - Validation and casting for the domain entity
15
+ *
16
+ * The Presenter references this Model instead of raw z.object(),
17
+ * keeping a single source of truth for the data shape.
18
+ */
19
+ import { defineModel } from '@vurb/core';
20
+
21
+ export const SystemModel = defineModel('SystemHealth', m => {
22
+ m.casts({
23
+ status: m.string('Server operational status'),
24
+ uptime: m.number('Uptime in seconds since process start'),
25
+ version: m.string('Server version string'),
26
+ timestamp: m.string('ISO 8601 timestamp of this check'),
27
+ });
28
+ });
29
29
  `;
30
30
  }
31
31
  //# sourceMappingURL=model.js.map
@@ -11,162 +11,162 @@ export function readme(config) {
11
11
  const sseNote = config.transport === 'sse'
12
12
  ? `\n> **Note:** Streamable HTTP 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 [Vurb.ts](https://vurb.vinkius.com/) — the TypeScript framework for MCP servers.
17
-
18
- ## Quick Start
19
-
20
- \`\`\`bash
21
- npm install
22
- vurb dev
23
- \`\`\`
24
- ${config.testing ? `
25
- ## Testing
26
-
27
- \`\`\`bash
28
- npm test
29
- \`\`\`
30
- ` : ''}
31
- ## Project Structure
32
-
33
- \`\`\`
34
- src/
35
- ├── vurb.ts # initVurb<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
- ├── models/ # MVA Model Layer (defineModel)
43
- │ └── SystemModel.ts
44
- ├── presenters/ # MVA View Layer (Egress Firewall)
45
- │ └── SystemPresenter.ts
46
- ├── prompts/ # MCP Prompt Engine
47
- │ └── greet.ts
48
- └── middleware/ # RBAC guards
49
- └── auth.ts
50
- \`\`\`
51
-
52
- ## Client Configuration
53
-
54
- ### Cursor Editor
55
-
56
- > **Already configured!** The \`.cursor/mcp.json\` file was generated automatically.
57
- > Just open this folder in Cursor and the server connects instantly.
58
- ${sseNote}
59
-
60
- ### Claude Desktop
61
-
62
- Add to your \`claude_desktop_config.json\`:
63
-
64
- \`\`\`json
65
- ${clientConfig}
66
- \`\`\`
67
- ${vectorReadmeSection(config)}
68
- ## Adding New Tools
69
-
70
- Create a new file in \`src/tools/\`. It's automatically discovered:
71
-
72
- \`\`\`typescript
73
- // src/tools/my-domain/my-tool.ts
74
- import { f } from '../../vurb.js';
75
-
76
- export default f.query('my_domain.my_tool')
77
- .describe('What this tool does')
78
- .withString('query', 'Search query')
79
- .handle(async (input, ctx) => {
80
- return { result: input.query };
81
- });
82
- \`\`\`
83
-
84
- No registration needed. The \`autoDiscover()\` system picks it up automatically.
85
-
86
- ## Documentation
87
-
88
- - [Vurb Docs](https://vurb.vinkius.com/)
89
- - [Presenter — Egress Firewall](https://vurb.vinkius.com/presenter)
90
- - [DX Guide — initVurb()](https://vurb.vinkius.com/dx-guide)
91
- - [Testing](https://vurb.vinkius.com/testing)
14
+ return `# ${config.name}
15
+
16
+ MCP Server built with [Vurb.ts](https://vurb.vinkius.com/) — the TypeScript framework for MCP servers.
17
+
18
+ ## Quick Start
19
+
20
+ \`\`\`bash
21
+ npm install
22
+ vurb dev
23
+ \`\`\`
24
+ ${config.testing ? `
25
+ ## Testing
26
+
27
+ \`\`\`bash
28
+ npm test
29
+ \`\`\`
30
+ ` : ''}
31
+ ## Project Structure
32
+
33
+ \`\`\`
34
+ src/
35
+ ├── vurb.ts # initVurb<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
+ ├── models/ # MVA Model Layer (defineModel)
43
+ │ └── SystemModel.ts
44
+ ├── presenters/ # MVA View Layer (Egress Firewall)
45
+ │ └── SystemPresenter.ts
46
+ ├── prompts/ # MCP Prompt Engine
47
+ │ └── greet.ts
48
+ └── middleware/ # RBAC guards
49
+ └── auth.ts
50
+ \`\`\`
51
+
52
+ ## Client Configuration
53
+
54
+ ### Cursor Editor
55
+
56
+ > **Already configured!** The \`.cursor/mcp.json\` file was generated automatically.
57
+ > Just open this folder in Cursor and the server connects instantly.
58
+ ${sseNote}
59
+
60
+ ### Claude Desktop
61
+
62
+ Add to your \`claude_desktop_config.json\`:
63
+
64
+ \`\`\`json
65
+ ${clientConfig}
66
+ \`\`\`
67
+ ${vectorReadmeSection(config)}
68
+ ## Adding New Tools
69
+
70
+ Create a new file in \`src/tools/\`. It's automatically discovered:
71
+
72
+ \`\`\`typescript
73
+ // src/tools/my-domain/my-tool.ts
74
+ import { f } from '../../vurb.js';
75
+
76
+ export default f.query('my_domain.my_tool')
77
+ .describe('What this tool does')
78
+ .withString('query', 'Search query')
79
+ .handle(async (input, ctx) => {
80
+ return { result: input.query };
81
+ });
82
+ \`\`\`
83
+
84
+ No registration needed. The \`autoDiscover()\` system picks it up automatically.
85
+
86
+ ## Documentation
87
+
88
+ - [Vurb Docs](https://vurb.vinkius.com/)
89
+ - [Presenter — Egress Firewall](https://vurb.vinkius.com/presenter)
90
+ - [DX Guide — initVurb()](https://vurb.vinkius.com/dx-guide)
91
+ - [Testing](https://vurb.vinkius.com/testing)
92
92
  `;
93
93
  }
94
94
  /** Vector-specific README section */
95
95
  function vectorReadmeSection(config) {
96
96
  switch (config.vector) {
97
97
  case 'prisma':
98
- return `
99
- ## Database Setup (Prisma)
100
-
101
- 1. Configure your database URL in \`.env\`:
102
- \`\`\`
103
- DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
104
- \`\`\`
105
-
106
- 2. Edit \`prisma/schema.prisma\` to define your models
107
-
108
- 3. Generate the Prisma client and Vurb tools:
109
- \`\`\`bash
110
- npm run db:generate
111
- \`\`\`
112
-
113
- 4. Push the schema to your database:
114
- \`\`\`bash
115
- npm run db:push
116
- \`\`\`
117
-
118
- Use \`/// @vurb.hide\` on sensitive fields to strip them from the Egress Firewall.
98
+ return `
99
+ ## Database Setup (Prisma)
100
+
101
+ 1. Configure your database URL in \`.env\`:
102
+ \`\`\`
103
+ DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
104
+ \`\`\`
105
+
106
+ 2. Edit \`prisma/schema.prisma\` to define your models
107
+
108
+ 3. Generate the Prisma client and Vurb tools:
109
+ \`\`\`bash
110
+ npm run db:generate
111
+ \`\`\`
112
+
113
+ 4. Push the schema to your database:
114
+ \`\`\`bash
115
+ npm run db:push
116
+ \`\`\`
117
+
118
+ Use \`/// @vurb.hide\` on sensitive fields to strip them from the Egress Firewall.
119
119
  `;
120
120
  case 'n8n':
121
- return `
122
- ## n8n Workflow Setup
123
-
124
- 1. Configure your n8n instance in \`.env\`:
125
- \`\`\`
126
- N8N_BASE_URL=http://localhost:5678
127
- N8N_API_KEY=your-api-key
128
- \`\`\`
129
-
130
- 2. The connector in \`src/n8n.ts\` auto-discovers webhook workflows
131
- and registers them as MCP tools.
121
+ return `
122
+ ## n8n Workflow Setup
123
+
124
+ 1. Configure your n8n instance in \`.env\`:
125
+ \`\`\`
126
+ N8N_BASE_URL=http://localhost:5678
127
+ N8N_API_KEY=your-api-key
128
+ \`\`\`
129
+
130
+ 2. The connector in \`src/n8n.ts\` auto-discovers webhook workflows
131
+ and registers them as MCP tools.
132
132
  `;
133
133
  case 'openapi':
134
- return `
135
- ## OpenAPI Generator Setup
136
-
137
- 1. Replace \`openapi.yaml\` with your actual OpenAPI 3.x spec
138
-
139
- 2. Generate the MCP server from the spec:
140
- \`\`\`bash
141
- npx @vurb/openapi-gen ./openapi.yaml --outDir ./src/generated
142
- \`\`\`
143
-
144
- 3. Import and register the generated tools in \`src/server.ts\`
134
+ return `
135
+ ## OpenAPI Generator Setup
136
+
137
+ 1. Replace \`openapi.yaml\` with your actual OpenAPI 3.x spec
138
+
139
+ 2. Generate the MCP server from the spec:
140
+ \`\`\`bash
141
+ npx @vurb/openapi-gen ./openapi.yaml --outDir ./src/generated
142
+ \`\`\`
143
+
144
+ 3. Import and register the generated tools in \`src/server.ts\`
145
145
  `;
146
146
  case 'oauth':
147
- return `
148
- ## OAuth Device Flow Setup
149
-
150
- 1. Configure your OAuth provider in \`.env\`:
151
- \`\`\`
152
- OAUTH_CLIENT_ID=your-client-id
153
- OAUTH_AUTH_ENDPOINT=https://api.example.com/oauth/device/code
154
- OAUTH_TOKEN_ENDPOINT=https://api.example.com/oauth/device/token
155
- \`\`\`
156
-
157
- 2. The auth tool in \`src/auth.ts\` is pre-configured with login, complete, status, and logout actions.
158
-
159
- 3. Protect any tool with the \`withAuth\` middleware from \`src/middleware/auth.ts\`:
160
- \`\`\`ts
161
- import { withAuth } from '../middleware/auth.js';
162
-
163
- export default f.query('protected.action')
164
- .describe('A protected query')
165
- .use(withAuth)
166
- .handle(async (input, ctx) => {
167
- // ctx is authenticated
168
- });
169
- \`\`\`
147
+ return `
148
+ ## OAuth Device Flow Setup
149
+
150
+ 1. Configure your OAuth provider in \`.env\`:
151
+ \`\`\`
152
+ OAUTH_CLIENT_ID=your-client-id
153
+ OAUTH_AUTH_ENDPOINT=https://api.example.com/oauth/device/code
154
+ OAUTH_TOKEN_ENDPOINT=https://api.example.com/oauth/device/token
155
+ \`\`\`
156
+
157
+ 2. The auth tool in \`src/auth.ts\` is pre-configured with login, complete, status, and logout actions.
158
+
159
+ 3. Protect any tool with the \`withAuth\` middleware from \`src/middleware/auth.ts\`:
160
+ \`\`\`ts
161
+ import { withAuth } from '../middleware/auth.js';
162
+
163
+ export default f.query('protected.action')
164
+ .describe('A protected query')
165
+ .use(withAuth)
166
+ .handle(async (input, ctx) => {
167
+ // ctx is authenticated
168
+ });
169
+ \`\`\`
170
170
  `;
171
171
  default:
172
172
  return '';