@@ -62,12 +62,6 @@ describeWithMongoDB(
6262 type : "string" ,
6363 required : true ,
6464 } ,
65- {
66- name : "filter" ,
67- description : "The query filter, matching the syntax of the query argument of db.collection.find()" ,
68- type : "object" ,
69- required : false ,
70- } ,
7165 {
7266 name : "jsonExportFormat" ,
7367 description : [
@@ -79,24 +73,10 @@ describeWithMongoDB(
7973 required : false ,
8074 } ,
8175 {
82- name : "limit" ,
83- description : "The maximum number of documents to return" ,
84- type : "number" ,
85- required : false ,
86- } ,
87- {
88- name : "projection" ,
89- description :
90- "The projection, matching the syntax of the projection argument of db.collection.find()" ,
91- type : "object" ,
92- required : false ,
93- } ,
94- {
95- name : "sort" ,
96- description :
97- "A document, describing the sort order, matching the syntax of the sort argument of cursor.sort(). The keys of the object are the fields to sort on, while the values are the sort directions (1 for ascending, -1 for descending)." ,
98- type : "object" ,
99- required : false ,
76+ name : "exportTarget" ,
77+ type : "array" ,
78+ description : "The export target along with its arguments." ,
79+ required : true ,
10080 } ,
10181 ]
10282 ) ;
@@ -126,6 +106,14 @@ describeWithMongoDB(
126106 database : "non-existent" ,
127107 collection : "foos" ,
128108 exportTitle : "Export for non-existent.foos" ,
109+ exportTarget : [
110+ {
111+ name : "find" ,
112+ arguments : {
113+ filter : { } ,
114+ } ,
115+ } ,
116+ ] ,
129117 } ,
130118 } ) ;
131119 const content = response . content as CallToolResult [ "content" ] ;
@@ -165,6 +153,14 @@ describeWithMongoDB(
165153 database : integration . randomDbName ( ) ,
166154 collection : "foo" ,
167155 exportTitle : `Export for ${ integration . randomDbName ( ) } .foo` ,
156+ exportTarget : [
157+ {
158+ name : "find" ,
159+ arguments : {
160+ filter : { } ,
161+ } ,
162+ } ,
163+ ] ,
168164 } ,
169165 } ) ;
170166 const content = response . content as CallToolResult [ "content" ] ;
@@ -192,8 +188,15 @@ describeWithMongoDB(
192188 arguments : {
193189 database : integration . randomDbName ( ) ,
194190 collection : "foo" ,
195- filter : { name : "foo" } ,
196191 exportTitle : `Export for ${ integration . randomDbName ( ) } .foo` ,
192+ exportTarget : [
193+ {
194+ name : "find" ,
195+ arguments : {
196+ filter : { name : "foo" } ,
197+ } ,
198+ } ,
199+ ] ,
197200 } ,
198201 } ) ;
199202 const content = response . content as CallToolResult [ "content" ] ;
@@ -220,8 +223,16 @@ describeWithMongoDB(
220223 arguments : {
221224 database : integration . randomDbName ( ) ,
222225 collection : "foo" ,
223- limit : 1 ,
224226 exportTitle : `Export for ${ integration . randomDbName ( ) } .foo` ,
227+ exportTarget : [
228+ {
229+ name : "find" ,
230+ arguments : {
231+ filter : { } ,
232+ limit : 1 ,
233+ } ,
234+ } ,
235+ ] ,
225236 } ,
226237 } ) ;
227238 const content = response . content as CallToolResult [ "content" ] ;
@@ -248,9 +259,17 @@ describeWithMongoDB(
248259 arguments : {
249260 database : integration . randomDbName ( ) ,
250261 collection : "foo" ,
251- limit : 1 ,
252- sort : { longNumber : 1 } ,
253262 exportTitle : `Export for ${ integration . randomDbName ( ) } .foo` ,
263+ exportTarget : [
264+ {
265+ name : "find" ,
266+ arguments : {
267+ filter : { } ,
268+ limit : 1 ,
269+ sort : { longNumber : 1 } ,
270+ } ,
271+ } ,
272+ ] ,
254273 } ,
255274 } ) ;
256275 const content = response . content as CallToolResult [ "content" ] ;
@@ -277,9 +296,17 @@ describeWithMongoDB(
277296 arguments : {
278297 database : integration . randomDbName ( ) ,
279298 collection : "foo" ,
280- limit : 1 ,
281- projection : { _id : 0 , name : 1 } ,
282299 exportTitle : `Export for ${ integration . randomDbName ( ) } .foo` ,
300+ exportTarget : [
301+ {
302+ name : "find" ,
303+ arguments : {
304+ filter : { } ,
305+ limit : 1 ,
306+ projection : { _id : 0 , name : 1 } ,
307+ } ,
308+ } ,
309+ ] ,
283310 } ,
284311 } ) ;
285312 const content = response . content as CallToolResult [ "content" ] ;
@@ -309,10 +336,18 @@ describeWithMongoDB(
309336 arguments : {
310337 database : integration . randomDbName ( ) ,
311338 collection : "foo" ,
312- limit : 1 ,
313- projection : { _id : 0 } ,
314339 jsonExportFormat : "relaxed" ,
315340 exportTitle : `Export for ${ integration . randomDbName ( ) } .foo` ,
341+ exportTarget : [
342+ {
343+ name : "find" ,
344+ arguments : {
345+ filter : { } ,
346+ limit : 1 ,
347+ projection : { _id : 0 } ,
348+ } ,
349+ } ,
350+ ] ,
316351 } ,
317352 } ) ;
318353 const content = response . content as CallToolResult [ "content" ] ;
@@ -343,10 +378,18 @@ describeWithMongoDB(
343378 arguments : {
344379 database : integration . randomDbName ( ) ,
345380 collection : "foo" ,
346- limit : 1 ,
347- projection : { _id : 0 } ,
348381 jsonExportFormat : "canonical" ,
349382 exportTitle : `Export for ${ integration . randomDbName ( ) } .foo` ,
383+ exportTarget : [
384+ {
385+ name : "find" ,
386+ arguments : {
387+ filter : { } ,
388+ limit : 1 ,
389+ projection : { _id : 0 } ,
390+ } ,
391+ } ,
392+ ] ,
350393 } ,
351394 } ) ;
352395 const content = response . content as CallToolResult [ "content" ] ;
@@ -371,6 +414,48 @@ describeWithMongoDB(
371414 } ,
372415 ] ) ;
373416 } ) ;
417+
418+ it ( "should allow exporting an aggregation" , async ( ) => {
419+ await integration . connectMcpClient ( ) ;
420+ const response = await integration . mcpClient ( ) . callTool ( {
421+ name : "export" ,
422+ arguments : {
423+ database : integration . randomDbName ( ) ,
424+ collection : "foo" ,
425+ exportTitle : `Export for ${ integration . randomDbName ( ) } .foo` ,
426+ exportTarget : [
427+ {
428+ name : "aggregate" ,
429+ arguments : {
430+ pipeline : [
431+ {
432+ $match : { } ,
433+ } ,
434+ {
435+ $limit : 1 ,
436+ } ,
437+ ] ,
438+ } ,
439+ } ,
440+ ] ,
441+ } ,
442+ } ) ;
443+ const content = response . content as CallToolResult [ "content" ] ;
444+ const exportURI = contentWithResourceURILink ( content ) ?. uri as string ;
445+ await resourceChangedNotification ( integration . mcpClient ( ) , exportURI ) ;
446+
447+ const localPathPart = contentWithExportPath ( content ) ;
448+ expect ( localPathPart ) . toBeDefined ( ) ;
449+ const [ , localPath ] = / " ( .* ) " / . exec ( String ( localPathPart ?. text ) ) ?? [ ] ;
450+ expect ( localPath ) . toBeDefined ( ) ;
451+
452+ const exportedContent = JSON . parse ( await fs . readFile ( localPath as string , "utf8" ) ) as Record <
453+ string ,
454+ unknown
455+ > [ ] ;
456+ expect ( exportedContent ) . toHaveLength ( 1 ) ;
457+ expect ( exportedContent [ 0 ] ?. name ) . toEqual ( "foo" ) ;
458+ } ) ;
374459 } ) ;
375460 } ,
376461 ( ) => userConfig
0 commit comments