• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb-js / mongodb-mcp-server / 16876636630

11 Aug 2025 09:51AM UTC coverage: 81.999% (+0.6%) from 81.362%
16876636630

Pull #424

github

web-flow
Merge 602f1c199 into 7572ec5d6
Pull Request #424: feat: adds an export tool and exported-data resource MCP-16

784 of 1003 branches covered (78.17%)

Branch coverage included in aggregate %.

592 of 659 new or added lines in 13 files covered. (89.83%)

18 existing lines in 3 files now uncovered.

4072 of 4919 relevant lines covered (82.78%)

66.27 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.92
/src/resources/common/exportedData.ts
1
import {
2✔
2
    CompleteResourceTemplateCallback,
3
    ListResourcesCallback,
4
    ReadResourceTemplateCallback,
5
    ResourceTemplate,
6
} from "@modelcontextprotocol/sdk/server/mcp.js";
7
import { Server } from "../../server.js";
8
import { LogId } from "../../common/logger.js";
2✔
9
import { Session } from "../../common/session.js";
10

11
export class ExportedData {
2✔
12
    private readonly name = "exported-data";
2✔
13
    private readonly description = "Data files exported in the current session.";
2✔
14
    private readonly uri = "exported-data://{exportName}";
2✔
15
    private server?: Server;
16

17
    constructor(private readonly session: Session) {}
2✔
18

19
    public register(server: Server): void {
74✔
20
        this.server = server;
74✔
21
        this.server.mcpServer.registerResource(
74✔
22
            this.name,
74✔
23
            new ResourceTemplate(this.uri, {
74✔
24
                /**
25
                 * A few clients have the capability of listing templated
26
                 * resources as well and this callback provides support for that
27
                 * */
28
                list: this.listResourcesCallback,
74✔
29
                /**
30
                 * This is to provide auto completion when user starts typing in
31
                 * value for template variable, in our case, exportName */
32
                complete: {
74✔
33
                    exportName: this.autoCompleteExportName,
74✔
34
                },
74✔
35
            }),
74✔
36
            { description: this.description },
74✔
37
            this.readResourceCallback
74✔
38
        );
74✔
39
        this.session.exportsManager.on("export-available", (uri: string): void => {
74✔
40
            server.sendResourceListChanged();
38✔
41
            server.sendResourceUpdated(uri);
38✔
42
        });
74✔
43
        this.session.exportsManager.on("export-expired", (): void => {
74✔
44
            server.sendResourceListChanged();
2✔
45
        });
74✔
46
    }
74✔
47

48
    private listResourcesCallback: ListResourcesCallback = () => {
74✔
NEW
49
        try {
×
NEW
50
            return {
×
NEW
51
                resources: this.session.exportsManager.availableExports.map(
×
NEW
52
                    ({ exportName, exportTitle, exportURI }) => ({
×
NEW
53
                        name: exportName,
×
NEW
54
                        description: exportTitle,
×
NEW
55
                        uri: exportURI,
×
NEW
56
                        mimeType: "application/json",
×
NEW
57
                    })
×
NEW
58
                ),
×
NEW
59
            };
×
NEW
60
        } catch (error) {
×
NEW
61
            this.session.logger.error({
×
NEW
62
                id: LogId.exportedDataListError,
×
NEW
63
                context: "Error when listing exported data resources",
×
NEW
64
                message: error instanceof Error ? error.message : String(error),
×
NEW
65
            });
×
NEW
66
            return {
×
NEW
67
                resources: [],
×
NEW
68
            };
×
NEW
69
        }
×
NEW
70
    };
×
71

72
    private autoCompleteExportName: CompleteResourceTemplateCallback = (value) => {
74✔
73
        try {
2✔
74
            return this.session.exportsManager.availableExports
2✔
75
                .filter(({ exportName }) => exportName.startsWith(value))
2✔
76
                .map(({ exportName }) => exportName);
2✔
77
        } catch (error) {
2!
NEW
78
            this.session.logger.error({
×
NEW
79
                id: LogId.exportedDataAutoCompleteError,
×
NEW
80
                context: "Error when autocompleting exported data",
×
NEW
81
                message: error instanceof Error ? error.message : String(error),
×
NEW
82
            });
×
NEW
83
            return [];
×
NEW
84
        }
×
85
    };
2✔
86

87
    private readResourceCallback: ReadResourceTemplateCallback = async (url, { exportName }) => {
74✔
88
        try {
6✔
89
            if (typeof exportName !== "string") {
6!
NEW
90
                throw new Error("Cannot retrieve exported data, exportName not provided.");
×
NEW
91
            }
×
92

93
            const content = await this.session.exportsManager.readExport(exportName);
6✔
94

95
            return {
2✔
96
                contents: [
2✔
97
                    {
2✔
98
                        uri: url.href,
2✔
99
                        text: content,
2✔
100
                        mimeType: "application/json",
2✔
101
                    },
2✔
102
                ],
2✔
103
            };
2✔
104
        } catch (error) {
6✔
105
            return {
4✔
106
                contents: [
4✔
107
                    {
4✔
108
                        uri: url.href,
4✔
109
                        text: `Error reading ${url.href}: ${error instanceof Error ? error.message : String(error)}`,
4!
110
                    },
4✔
111
                ],
4✔
112
                isError: true,
4✔
113
            };
4✔
114
        }
4✔
115
    };
6✔
116
}
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc