@vibesdotdev/mcp 1.0.0-rc.1 → 1.0.0-rc.5
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 +11 -11
- package/dist/adapters/index.d.ts +0 -2
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +0 -2
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/mcp/connection-identity.d.ts +18 -0
- package/dist/adapters/mcp/connection-identity.d.ts.map +1 -1
- package/dist/adapters/mcp/connection-identity.js +26 -0
- package/dist/adapters/mcp/connection-identity.js.map +1 -1
- package/dist/adapters/mcp/dual-era-handler.d.ts +22 -0
- package/dist/adapters/mcp/dual-era-handler.d.ts.map +1 -0
- package/dist/adapters/mcp/dual-era-handler.js +150 -0
- package/dist/adapters/mcp/dual-era-handler.js.map +1 -0
- package/dist/adapters/mcp/index.d.ts +0 -4
- package/dist/adapters/mcp/index.d.ts.map +1 -1
- package/dist/adapters/mcp/index.js +2 -10
- package/dist/adapters/mcp/index.js.map +1 -1
- package/dist/adapters/mcp/mcp-http-session.d.ts +1 -1
- package/dist/adapters/mcp/mcp-http-session.d.ts.map +1 -1
- package/dist/adapters/mcp/mcp-http-session.js +1 -1
- package/dist/adapters/mcp/mcp-http-session.js.map +1 -1
- package/dist/adapters/mcp/projection-doctor.d.ts.map +1 -1
- package/dist/adapters/mcp/projection-doctor.js +11 -4
- package/dist/adapters/mcp/projection-doctor.js.map +1 -1
- package/dist/adapters/mcp/projection.d.ts +1 -1
- package/dist/adapters/mcp/projection.d.ts.map +1 -1
- package/dist/adapters/mcp/projection.js.map +1 -1
- package/dist/adapters/mcp/sampling-context.d.ts.map +1 -1
- package/dist/adapters/mcp/sampling-context.js +1 -1
- package/dist/adapters/mcp/sampling-context.js.map +1 -1
- package/dist/adapters/mcp/sampling.d.ts +1 -1
- package/dist/adapters/mcp/sampling.d.ts.map +1 -1
- package/dist/adapters/mcp/server.consumer.d.ts +1 -1
- package/dist/adapters/mcp/server.consumer.d.ts.map +1 -1
- package/dist/adapters/mcp/server.consumer.js +59 -32
- package/dist/adapters/mcp/server.consumer.js.map +1 -1
- package/dist/adapters/mcp/server.d.ts +1 -22
- package/dist/adapters/mcp/server.d.ts.map +1 -1
- package/dist/adapters/mcp/server.js +232 -266
- package/dist/adapters/mcp/server.js.map +1 -1
- package/dist/adapters/mcp/startup-refusal.d.ts +2 -2
- package/dist/adapters/mcp/startup-refusal.d.ts.map +1 -1
- package/dist/adapters/mcp/startup-refusal.js +10 -10
- package/dist/adapters/mcp/startup-refusal.js.map +1 -1
- package/dist/adapters/mcp/stdio-relay.d.ts +1 -34
- package/dist/adapters/mcp/stdio-relay.d.ts.map +1 -1
- package/dist/adapters/mcp/stdio-relay.js +55 -71
- package/dist/adapters/mcp/stdio-relay.js.map +1 -1
- package/dist/adapters/mcp/tool-approval.d.ts +35 -0
- package/dist/adapters/mcp/tool-approval.d.ts.map +1 -0
- package/dist/adapters/mcp/tool-approval.js +156 -0
- package/dist/adapters/mcp/tool-approval.js.map +1 -0
- package/dist/adapters/mcp/tool-audit-live.d.ts +8 -12
- package/dist/adapters/mcp/tool-audit-live.d.ts.map +1 -1
- package/dist/adapters/mcp/tool-audit-live.js +9 -13
- package/dist/adapters/mcp/tool-audit-live.js.map +1 -1
- package/dist/adapters/mcp/tool-audit.d.ts +5 -0
- package/dist/adapters/mcp/tool-audit.d.ts.map +1 -1
- package/dist/adapters/mcp/tool-audit.js +73 -5
- package/dist/adapters/mcp/tool-audit.js.map +1 -1
- package/dist/adapters/mcp/trust-tag.d.ts.map +1 -1
- package/dist/adapters/mcp/trust-tag.js +5 -0
- package/dist/adapters/mcp/trust-tag.js.map +1 -1
- package/dist/adapters/mcp/web-handler.d.ts +6 -1
- package/dist/adapters/mcp/web-handler.d.ts.map +1 -1
- package/dist/adapters/mcp/web-handler.js +33 -13
- package/dist/adapters/mcp/web-handler.js.map +1 -1
- package/dist/adapters/transport-bun-http.d.ts +7 -3
- package/dist/adapters/transport-bun-http.d.ts.map +1 -1
- package/dist/adapters/transport-bun-http.js +5 -5
- package/dist/adapters/transport-bun-http.js.map +1 -1
- package/dist/adapters/types.d.ts +7 -9
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/zod-mcp.d.ts.map +1 -1
- package/dist/adapters/zod-mcp.js +4 -6
- package/dist/adapters/zod-mcp.js.map +1 -1
- package/dist/cli/mcp/audit/dev.audit.tools.impl.consumer.d.ts.map +1 -1
- package/dist/cli/mcp/audit/dev.audit.tools.impl.consumer.js +6 -1
- package/dist/cli/mcp/audit/dev.audit.tools.impl.consumer.js.map +1 -1
- package/dist/cli/surface-mcp/dev.mcp.serve.impl.consumer.d.ts.map +1 -1
- package/dist/cli/surface-mcp/dev.mcp.serve.impl.consumer.js +2 -0
- package/dist/cli/surface-mcp/dev.mcp.serve.impl.consumer.js.map +1 -1
- package/dist/config/mcp.config.descriptor.d.ts +28 -33
- package/dist/config/mcp.config.descriptor.d.ts.map +1 -1
- package/dist/config/mcp.config.descriptor.js +23 -19
- package/dist/config/mcp.config.descriptor.js.map +1 -1
- package/dist/docs/resources.docs.descriptor.d.ts.map +1 -1
- package/dist/docs/resources.docs.descriptor.js +43 -332
- package/dist/docs/resources.docs.descriptor.js.map +1 -1
- package/dist/docs/server.docs.descriptor.d.ts.map +1 -1
- package/dist/docs/server.docs.descriptor.js +71 -300
- package/dist/docs/server.docs.descriptor.js.map +1 -1
- package/dist/docs/tools.docs.descriptor.d.ts.map +1 -1
- package/dist/docs/tools.docs.descriptor.js +69 -244
- package/dist/docs/tools.docs.descriptor.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/mcp.runtime.plugin.d.ts.map +1 -1
- package/dist/mcp.runtime.plugin.js +3 -1
- package/dist/mcp.runtime.plugin.js.map +1 -1
- package/dist/svelte/tool-widgets/summary.d.ts +2 -2
- package/dist/svelte/tool-widgets/summary.d.ts.map +1 -1
- package/dist/svelte/tool-widgets/summary.js +9 -4
- package/dist/tools/vibes-context/schemas.d.ts +2 -1
- package/dist/tools/vibes-context/schemas.d.ts.map +1 -1
- package/dist/tools/vibes-context/schemas.js +22 -4
- package/dist/tools/vibes-context/schemas.js.map +1 -1
- package/dist/tools/vibes-context/vibes-context.descriptor.d.ts.map +1 -1
- package/dist/tools/vibes-context/vibes-context.descriptor.js +11 -1
- package/dist/tools/vibes-context/vibes-context.descriptor.js.map +1 -1
- package/dist/tools/vibes-context/vibes-context.impl.d.ts.map +1 -1
- package/dist/tools/vibes-context/vibes-context.impl.js +22 -11
- package/dist/tools/vibes-context/vibes-context.impl.js.map +1 -1
- package/dist/types.d.ts +0 -32
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/types.registry.d.ts +0 -59
- package/dist/types.registry.d.ts.map +1 -1
- package/dist/types.registry.js.map +1 -1
- package/package.json +62 -93
- package/dist/adapters/compatibility.d.ts +0 -20
- package/dist/adapters/compatibility.d.ts.map +0 -1
- package/dist/adapters/compatibility.js +0 -57
- package/dist/adapters/compatibility.js.map +0 -1
- package/dist/adapters/host-context.consumer.d.ts +0 -12
- package/dist/adapters/host-context.consumer.d.ts.map +0 -1
- package/dist/adapters/host-context.consumer.js +0 -10
- package/dist/adapters/host-context.consumer.js.map +0 -1
- package/dist/adapters/host-context.d.ts +0 -32
- package/dist/adapters/host-context.d.ts.map +0 -1
- package/dist/adapters/host-context.js +0 -17
- package/dist/adapters/host-context.js.map +0 -1
- package/dist/adapters/mcp/context.d.ts +0 -137
- package/dist/adapters/mcp/context.d.ts.map +0 -1
- package/dist/adapters/mcp/context.js +0 -230
- package/dist/adapters/mcp/context.js.map +0 -1
- package/dist/adapters/mcp/formatters.d.ts +0 -41
- package/dist/adapters/mcp/formatters.d.ts.map +0 -1
- package/dist/adapters/mcp/formatters.js +0 -102
- package/dist/adapters/mcp/formatters.js.map +0 -1
- package/dist/adapters/mcp/from-api-endpoint.d.ts +0 -59
- package/dist/adapters/mcp/from-api-endpoint.d.ts.map +0 -1
- package/dist/adapters/mcp/from-api-endpoint.js +0 -206
- package/dist/adapters/mcp/from-api-endpoint.js.map +0 -1
- package/dist/adapters/mcp/vibes-types.d.ts +0 -115
- package/dist/adapters/mcp/vibes-types.d.ts.map +0 -1
- package/dist/adapters/mcp/vibes-types.js +0 -7
- package/dist/adapters/mcp/vibes-types.js.map +0 -1
- package/dist/mcp/index.d.ts +0 -20
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.js +0 -19
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp.consumer.plugin.d.ts +0 -4
- package/dist/mcp.consumer.plugin.d.ts.map +0 -1
- package/dist/mcp.consumer.plugin.js +0 -19
- package/dist/mcp.consumer.plugin.js.map +0 -1
- package/dist/schemas/host-adapters.d.ts +0 -14
- package/dist/schemas/host-adapters.d.ts.map +0 -1
- package/dist/schemas/host-adapters.js +0 -7
- package/dist/schemas/host-adapters.js.map +0 -1
- package/dist/schemas/tool.d.ts +0 -8
- package/dist/schemas/tool.d.ts.map +0 -1
- package/dist/schemas/tool.js +0 -8
- package/dist/schemas/tool.js.map +0 -1
|
@@ -2,386 +2,97 @@ const descriptor = {
|
|
|
2
2
|
kind: 'docs/topic',
|
|
3
3
|
id: 'mcp.resources',
|
|
4
4
|
title: 'MCP Resources',
|
|
5
|
-
summary: '
|
|
5
|
+
summary: 'Read-only URI-addressed resources and the projection birth snapshot',
|
|
6
6
|
body: {
|
|
7
7
|
type: 'markdown',
|
|
8
8
|
sourceType: 'raw',
|
|
9
9
|
source: `---
|
|
10
10
|
title: MCP Resources
|
|
11
|
-
summary:
|
|
12
|
-
tags: [mcp, resources,
|
|
11
|
+
summary: Read-only URI-addressed resources and the projection birth snapshot
|
|
12
|
+
tags: [mcp, resources, uris, projection-birth]
|
|
13
13
|
parent: mcp
|
|
14
14
|
order: 3
|
|
15
15
|
surfaces: [cli, web, in-app]
|
|
16
16
|
hardware: [consumer, cloud]
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
MCP **resources**
|
|
19
|
+
MCP **resources** are read-only, URI-addressed data. They are not tools and they
|
|
20
|
+
are not a second copy of the tool catalog.
|
|
20
21
|
|
|
21
|
-
##
|
|
22
|
+
## The projection birth resource
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Fixed URI with static content:
|
|
26
|
-
|
|
27
|
-
\`\`\`ts
|
|
28
|
-
server.registerResource(
|
|
29
|
-
'workspace-files',
|
|
30
|
-
'file://workspace/README.md',
|
|
31
|
-
{
|
|
32
|
-
description: 'Workspace README file',
|
|
33
|
-
mimeType: 'text/markdown'
|
|
34
|
-
},
|
|
35
|
-
async (uri) => {
|
|
36
|
-
const content = await fs.read(uri.pathname);
|
|
37
|
-
return {
|
|
38
|
-
contents: [{
|
|
39
|
-
uri: uri.href,
|
|
40
|
-
mimeType: 'text/markdown',
|
|
41
|
-
text: content
|
|
42
|
-
}]
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
);
|
|
46
|
-
\`\`\`
|
|
47
|
-
|
|
48
|
-
### Resource templates
|
|
49
|
-
|
|
50
|
-
URI templates with variables:
|
|
51
|
-
|
|
52
|
-
\`\`\`ts
|
|
53
|
-
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
54
|
-
|
|
55
|
-
server.registerResource(
|
|
56
|
-
'file-content',
|
|
57
|
-
new ResourceTemplate('file://workspace/{path}', {
|
|
58
|
-
list: async (uri) => {
|
|
59
|
-
// List all matching files
|
|
60
|
-
const files = await fs.list('workspace/', { recursive: true });
|
|
61
|
-
return {
|
|
62
|
-
resources: files.map(f => ({
|
|
63
|
-
uri: \`file://workspace/\${f.path}\`,
|
|
64
|
-
name: f.name,
|
|
65
|
-
mimeType: getMimeType(f.name)
|
|
66
|
-
}))
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
}),
|
|
70
|
-
{
|
|
71
|
-
description: 'Workspace file contents',
|
|
72
|
-
mimeType: 'text/plain'
|
|
73
|
-
},
|
|
74
|
-
async (uri, variables) => {
|
|
75
|
-
const content = await fs.read(variables.path);
|
|
76
|
-
return {
|
|
77
|
-
contents: [{
|
|
78
|
-
uri: uri.href,
|
|
79
|
-
mimeType: getMimeType(variables.path),
|
|
80
|
-
text: content
|
|
81
|
-
}]
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
);
|
|
85
|
-
\`\`\`
|
|
86
|
-
|
|
87
|
-
**Template syntax:**
|
|
88
|
-
- \`{variable}\` — Path segment variable
|
|
89
|
-
- \`{variable*}\` — Multi-segment wildcard
|
|
90
|
-
- List function enumerates matching resources
|
|
91
|
-
|
|
92
|
-
## Descriptor-based resources
|
|
93
|
-
|
|
94
|
-
Tools can declare MCP resources in their descriptor:
|
|
95
|
-
|
|
96
|
-
\`\`\`ts
|
|
97
|
-
export const fsReadDescriptor = {
|
|
98
|
-
kind: 'tools/tool',
|
|
99
|
-
id: 'workspace-fs',
|
|
100
|
-
mcp: {
|
|
101
|
-
resource: {
|
|
102
|
-
uri: 'file://workspace/{path}',
|
|
103
|
-
name: 'workspace-file',
|
|
104
|
-
description: 'Read workspace file contents',
|
|
105
|
-
mimeType: 'text/plain',
|
|
106
|
-
cacheable: true,
|
|
107
|
-
subscriptions: ['file:changed']
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
} as const;
|
|
111
|
-
\`\`\`
|
|
112
|
-
|
|
113
|
-
MCP server auto-registers these:
|
|
114
|
-
|
|
115
|
-
\`\`\`ts
|
|
116
|
-
// Auto-registration in buildServer()
|
|
117
|
-
for (const descriptor of descriptors) {
|
|
118
|
-
if (descriptor.mcp?.resource) {
|
|
119
|
-
server.registerResource(
|
|
120
|
-
descriptor.mcp.resource.name,
|
|
121
|
-
descriptor.mcp.resource.uri,
|
|
122
|
-
{
|
|
123
|
-
description: descriptor.mcp.resource.description,
|
|
124
|
-
mimeType: descriptor.mcp.resource.mimeType,
|
|
125
|
-
_meta: {
|
|
126
|
-
vibes: {
|
|
127
|
-
toolId: descriptor.id,
|
|
128
|
-
cacheable: descriptor.mcp.resource.cacheable,
|
|
129
|
-
subscriptions: descriptor.mcp.resource.subscriptions
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
async (uri) => {
|
|
134
|
-
// Returns descriptor metadata (not live data)
|
|
135
|
-
return {
|
|
136
|
-
contents: [{
|
|
137
|
-
uri: uri.href,
|
|
138
|
-
mimeType: 'application/json',
|
|
139
|
-
text: buildResourceText(descriptor, uri.href)
|
|
140
|
-
}]
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
\`\`\`
|
|
147
|
-
|
|
148
|
-
## Resource URIs
|
|
149
|
-
|
|
150
|
-
### URI schemes
|
|
151
|
-
|
|
152
|
-
**file://** — Local filesystem
|
|
153
|
-
|
|
154
|
-
\`\`\`
|
|
155
|
-
file://workspace/src/index.ts
|
|
156
|
-
file://workspace/docs/api.md
|
|
157
|
-
\`\`\`
|
|
158
|
-
|
|
159
|
-
**vfs://** — Virtual filesystem
|
|
24
|
+
Every serving surface exposes one immutable startup snapshot:
|
|
160
25
|
|
|
161
26
|
\`\`\`
|
|
162
|
-
|
|
163
|
-
vfs://knowledge/base/articles
|
|
27
|
+
vibes://diagnostics/projection-birth
|
|
164
28
|
\`\`\`
|
|
165
29
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
data://secrets/requirements
|
|
171
|
-
\`\`\`
|
|
172
|
-
|
|
173
|
-
### URI resolution
|
|
174
|
-
|
|
175
|
-
URIs resolved by resource handlers:
|
|
30
|
+
It carries the build provenance, catalog hash, selected tool ids and registered
|
|
31
|
+
tool ids for the body that is actually serving. Its contents are bound by digest
|
|
32
|
+
at startup; it is the diagnostic source of truth when an agent and an operator
|
|
33
|
+
disagree about what was served.
|
|
176
34
|
|
|
177
|
-
|
|
178
|
-
server.registerResource(
|
|
179
|
-
'config',
|
|
180
|
-
'data://config/{domain}.{format}',
|
|
181
|
-
{ description: 'Configuration data' },
|
|
182
|
-
async (uri, variables) => {
|
|
183
|
-
const config = await runtime.query('config/domain')
|
|
184
|
-
.withId(variables.domain)
|
|
185
|
-
.resolve();
|
|
186
|
-
|
|
187
|
-
return {
|
|
188
|
-
contents: [{
|
|
189
|
-
uri: uri.href,
|
|
190
|
-
mimeType: \`application/\${variables.format}\`,
|
|
191
|
-
text: JSON.stringify(config, null, 2)
|
|
192
|
-
}]
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
);
|
|
196
|
-
\`\`\`
|
|
197
|
-
|
|
198
|
-
## Resource metadata
|
|
35
|
+
## Descriptor metadata is not a live resource
|
|
199
36
|
|
|
200
|
-
|
|
37
|
+
A tool descriptor may declare \`mcp.resource\` metadata. The MCP adapter projects
|
|
38
|
+
that as a **descriptor-metadata** payload, and the payload says so explicitly.
|
|
39
|
+
It does not read the underlying file, row or remote object.
|
|
201
40
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
description: 'Workspace file content',
|
|
207
|
-
mimeType: 'text/typescript',
|
|
208
|
-
_meta: {
|
|
209
|
-
vibes: {
|
|
210
|
-
toolId: 'workspace-fs',
|
|
211
|
-
cacheable: true, // Client can cache response
|
|
212
|
-
subscriptions: ['file:changed'] // Subscribe to updates
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
\`\`\`
|
|
41
|
+
Use \`mcp.resource\` only when descriptor metadata is the intended resource. If a
|
|
42
|
+
capability has live data, its owning package implements a real resource handler
|
|
43
|
+
and registers it through the MCP adapter; do not advertise a live URI that only
|
|
44
|
+
returns descriptor metadata.
|
|
217
45
|
|
|
218
|
-
##
|
|
46
|
+
## Templates
|
|
219
47
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
\`\`\`ts
|
|
223
|
-
// MCP protocol: resources/list
|
|
224
|
-
const resources = await mcpClient.listResources();
|
|
225
|
-
|
|
226
|
-
// Returns
|
|
227
|
-
[
|
|
228
|
-
{
|
|
229
|
-
uri: 'file://workspace/README.md',
|
|
230
|
-
name: 'workspace-file',
|
|
231
|
-
description: 'README file',
|
|
232
|
-
mimeType: 'text/markdown'
|
|
233
|
-
},
|
|
234
|
-
// ... more resources
|
|
235
|
-
]
|
|
236
|
-
\`\`\`
|
|
237
|
-
|
|
238
|
-
## Resource subscriptions
|
|
239
|
-
|
|
240
|
-
Clients can subscribe to resource updates:
|
|
241
|
-
|
|
242
|
-
\`\`\`ts
|
|
243
|
-
// MCP protocol: resources/subscribe
|
|
244
|
-
await mcpClient.subscribe('file://workspace/src/index.ts');
|
|
245
|
-
|
|
246
|
-
// Server sends notification when resource changes
|
|
247
|
-
mcpClient.on('resources/updated', (event) => {
|
|
248
|
-
console.log('Resource updated:', event.uri);
|
|
249
|
-
});
|
|
250
|
-
\`\`\`
|
|
251
|
-
|
|
252
|
-
Subscriptions tied to runtime events:
|
|
253
|
-
|
|
254
|
-
\`\`\`ts
|
|
255
|
-
runtime.on('fs-operation/write', (event) => {
|
|
256
|
-
// Notify subscribed clients
|
|
257
|
-
mcpServer.notify('resources/updated', {
|
|
258
|
-
uri: \`file://\${event.path}\`
|
|
259
|
-
});
|
|
260
|
-
});
|
|
261
|
-
\`\`\`
|
|
262
|
-
|
|
263
|
-
## Resource templates vs resources
|
|
264
|
-
|
|
265
|
-
**Resources:** Fixed URI, single resource
|
|
266
|
-
|
|
267
|
-
\`\`\`ts
|
|
268
|
-
mcp: {
|
|
269
|
-
resource: {
|
|
270
|
-
uri: 'file://workspace/README.md',
|
|
271
|
-
name: 'readme'
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
\`\`\`
|
|
275
|
-
|
|
276
|
-
**Templates:** URI pattern, multiple matches
|
|
48
|
+
URI templates are supported for descriptor metadata:
|
|
277
49
|
|
|
278
50
|
\`\`\`ts
|
|
279
51
|
mcp: {
|
|
280
52
|
resourceTemplates: [{
|
|
281
|
-
uriTemplate: '
|
|
282
|
-
name: '
|
|
53
|
+
uriTemplate: 'example://items/{id}',
|
|
54
|
+
name: 'Item metadata',
|
|
55
|
+
mimeType: 'application/json'
|
|
283
56
|
}]
|
|
284
57
|
}
|
|
285
58
|
\`\`\`
|
|
286
59
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
Cacheable resources include ETag:
|
|
290
|
-
|
|
291
|
-
\`\`\`ts
|
|
292
|
-
async (uri) => {
|
|
293
|
-
const stat = await fs.stat(uri.pathname);
|
|
294
|
-
const etag = \`\${stat.mtimeMs}-\${stat.size}\`;
|
|
295
|
-
|
|
296
|
-
return {
|
|
297
|
-
contents: [{
|
|
298
|
-
uri: uri.href,
|
|
299
|
-
mimeType: 'text/plain',
|
|
300
|
-
text: content,
|
|
301
|
-
_meta: { etag }
|
|
302
|
-
}]
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
\`\`\`
|
|
60
|
+
The template handler receives the URI and variables. It must return the same
|
|
61
|
+
descriptor-metadata contract as a static descriptor resource.
|
|
306
62
|
|
|
307
|
-
|
|
63
|
+
## List changes and subscriptions
|
|
308
64
|
|
|
309
|
-
|
|
65
|
+
The server advertises \`resources.listChanged\` only when the resource list can
|
|
66
|
+
actually change. The projection birth resource is immutable, so the default
|
|
67
|
+
surface does not need a resource subscription stream. A live resource owner
|
|
68
|
+
that changes must provide the change notification through its owning transport.
|
|
310
69
|
|
|
311
|
-
|
|
312
|
-
// ❌ NEVER — bypasses descriptor auto-discovery
|
|
313
|
-
server.registerResource('manual', 'data://manual', {...}, handler);
|
|
314
|
-
\`\`\`
|
|
315
|
-
|
|
316
|
-
## RIGHT: Descriptor-based
|
|
317
|
-
|
|
318
|
-
\`\`\`ts
|
|
319
|
-
// ✅ Declare in tool descriptor, auto-registered
|
|
320
|
-
export const descriptor = {
|
|
321
|
-
mcp: {
|
|
322
|
-
resource: { uri: '...', name: '...' }
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
\`\`\`
|
|
326
|
-
|
|
327
|
-
## Resource security
|
|
328
|
-
|
|
329
|
-
### URI containment
|
|
330
|
-
|
|
331
|
-
Validate URIs are within allowed paths:
|
|
332
|
-
|
|
333
|
-
\`\`\`ts
|
|
334
|
-
async (uri) => {
|
|
335
|
-
const allowed = await checkWorkspaceContainment({
|
|
336
|
-
path: uri.pathname,
|
|
337
|
-
operation: 'read'
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
if (!allowed) {
|
|
341
|
-
throw new McpResourceError('URI outside workspace');
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
return readResource(uri);
|
|
345
|
-
}
|
|
346
|
-
\`\`\`
|
|
347
|
-
|
|
348
|
-
### MIME type validation
|
|
349
|
-
|
|
350
|
-
Sanitize MIME types:
|
|
351
|
-
|
|
352
|
-
\`\`\`ts
|
|
353
|
-
const allowedMimes = ['text/plain', 'application/json', 'text/markdown'];
|
|
354
|
-
const mimeType = getMimeType(path);
|
|
355
|
-
|
|
356
|
-
if (!allowedMimes.includes(mimeType)) {
|
|
357
|
-
throw new McpResourceError('Unsupported MIME type');
|
|
358
|
-
}
|
|
359
|
-
\`\`\`
|
|
70
|
+
## Security
|
|
360
71
|
|
|
361
|
-
|
|
72
|
+
- Resolve every URI through the owning capability; never concatenate a caller
|
|
73
|
+
path onto a filesystem root.
|
|
74
|
+
- Return a MIME type and reject an unreadable or out-of-scope URI with a typed
|
|
75
|
+
refusal.
|
|
76
|
+
- Do not put credentials, tokens or raw provider errors in resource contents.
|
|
362
77
|
|
|
363
|
-
|
|
78
|
+
## Verify
|
|
364
79
|
|
|
365
80
|
\`\`\`bash
|
|
366
|
-
vibes dev
|
|
81
|
+
vibes dev audit tools --doctor # birth digest + canary
|
|
367
82
|
\`\`\`
|
|
368
83
|
|
|
369
|
-
|
|
370
|
-
- Registered resource URIs
|
|
371
|
-
- Template patterns
|
|
372
|
-
- Subscription counts
|
|
373
|
-
- Cache hit rates
|
|
84
|
+
Read the birth resource and compare its catalog hash with the live \`tools/list\`.
|
|
374
85
|
|
|
375
86
|
:::card{title="See also"}
|
|
376
87
|
- [\`mcp.server\`](mcp.server) — MCP server setup
|
|
377
88
|
- [\`mcp.tools\`](mcp.tools) — MCP tools
|
|
378
|
-
- [\`
|
|
89
|
+
- [\`mcp.prompts\`](mcp.prompts) — MCP prompts
|
|
379
90
|
:::
|
|
380
91
|
`
|
|
381
92
|
},
|
|
382
93
|
parent: 'mcp',
|
|
383
94
|
order: 3,
|
|
384
|
-
tags: ['mcp', 'resources', '
|
|
95
|
+
tags: ['mcp', 'resources', 'uris', 'projection-birth'],
|
|
385
96
|
surfaces: ['cli', 'web', 'in-app'],
|
|
386
97
|
hardware: ['consumer', 'cloud'],
|
|
387
98
|
enabled: true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resources.docs.descriptor.js","sourceRoot":"","sources":["../../src/docs/resources.docs.descriptor.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAwB;IACtC,IAAI,EAAE,YAAY;IAClB,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,eAAe;IACtB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"resources.docs.descriptor.js","sourceRoot":"","sources":["../../src/docs/resources.docs.descriptor.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAwB;IACtC,IAAI,EAAE,YAAY;IAClB,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,eAAe;IACtB,OAAO,EAAE,qEAAqE;IAC9E,IAAI,EAAE;QACJ,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,KAAK;QACjB,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkFX;KACE;IACD,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,CAAC;IACtD,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC;IAClC,QAAQ,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC;IAC/B,OAAO,EAAE,IAAI;CACd,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.docs.descriptor.d.ts","sourceRoot":"","sources":["../../src/docs/server.docs.descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,QAAA,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"server.docs.descriptor.d.ts","sourceRoot":"","sources":["../../src/docs/server.docs.descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,QAAA,MAAM,UAAU,EAAE,mBAuJjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
|