@salesforce/mcp 0.17.1-dev.0 → 0.17.2-dev.1
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/lib/index.d.ts +1 -1
- package/lib/index.js +7 -88
- package/lib/main-server-provider.d.ts +7 -0
- package/lib/main-server-provider.js +31 -0
- package/lib/registry.d.ts +3 -0
- package/lib/{tools/core/index.js → registry.js} +11 -4
- package/lib/scripts/build-index.js +1 -1
- package/lib/services.d.ts +12 -0
- package/lib/services.js +34 -0
- package/lib/sf-mcp-server.d.ts +12 -7
- package/lib/sf-mcp-server.js +6 -20
- package/lib/telemetry.d.ts +2 -1
- package/lib/tools/sf-enable-tools.d.ts +23 -0
- package/lib/tools/sf-enable-tools.js +77 -0
- package/lib/tools/sf-list-tools.d.ts +8 -0
- package/lib/tools/{dynamic/sf-list-tools.js → sf-list-tools.js} +33 -9
- package/lib/tools/sf-suggest-cli-command.d.ts +25 -0
- package/lib/tools/{core/sf-suggest-cli-command.js → sf-suggest-cli-command.js} +46 -18
- package/lib/utils/assets.d.ts +21 -0
- package/lib/{assets.js → utils/assets.js} +23 -33
- package/lib/{shared → utils}/auth.d.ts +3 -8
- package/lib/{shared → utils}/auth.js +2 -42
- package/lib/utils/registry-utils.d.ts +4 -0
- package/lib/utils/registry-utils.js +87 -0
- package/lib/utils/tools.d.ts +41 -0
- package/lib/{shared → utils}/tools.js +0 -69
- package/lib/utils/types.d.ts +5 -0
- package/package.json +8 -6
- package/README.md +0 -263
- package/lib/assets.d.ts +0 -44
- package/lib/shared/params.d.ts +0 -5
- package/lib/shared/params.js +0 -46
- package/lib/shared/tools.d.ts +0 -68
- package/lib/shared/types.d.ts +0 -33
- package/lib/shared/utils.d.ts +0 -11
- package/lib/shared/utils.js +0 -71
- package/lib/tools/core/index.d.ts +0 -3
- package/lib/tools/core/sf-get-username.d.ts +0 -17
- package/lib/tools/core/sf-get-username.js +0 -109
- package/lib/tools/core/sf-resume.d.ts +0 -20
- package/lib/tools/core/sf-resume.js +0 -149
- package/lib/tools/core/sf-suggest-cli-command.d.ts +0 -5
- package/lib/tools/data/index.d.ts +0 -1
- package/lib/tools/data/index.js +0 -17
- package/lib/tools/data/sf-query-org.d.ts +0 -20
- package/lib/tools/data/sf-query-org.js +0 -66
- package/lib/tools/dynamic/index.d.ts +0 -2
- package/lib/tools/dynamic/index.js +0 -18
- package/lib/tools/dynamic/sf-enable-tools.d.ts +0 -2
- package/lib/tools/dynamic/sf-enable-tools.js +0 -42
- package/lib/tools/dynamic/sf-list-tools.d.ts +0 -2
- package/lib/tools/metadata/index.d.ts +0 -2
- package/lib/tools/metadata/index.js +0 -18
- package/lib/tools/metadata/sf-deploy-metadata.d.ts +0 -27
- package/lib/tools/metadata/sf-deploy-metadata.js +0 -164
- package/lib/tools/metadata/sf-retrieve-metadata.d.ts +0 -2
- package/lib/tools/metadata/sf-retrieve-metadata.js +0 -128
- package/lib/tools/orgs/index.d.ts +0 -5
- package/lib/tools/orgs/index.js +0 -21
- package/lib/tools/orgs/sf-create-org-snapshot.d.ts +0 -23
- package/lib/tools/orgs/sf-create-org-snapshot.js +0 -88
- package/lib/tools/orgs/sf-create-scratch-org.d.ts +0 -50
- package/lib/tools/orgs/sf-create-scratch-org.js +0 -132
- package/lib/tools/orgs/sf-delete-org.d.ts +0 -14
- package/lib/tools/orgs/sf-delete-org.js +0 -65
- package/lib/tools/orgs/sf-list-all-orgs.d.ts +0 -11
- package/lib/tools/orgs/sf-list-all-orgs.js +0 -59
- package/lib/tools/orgs/sf-org-open.d.ts +0 -17
- package/lib/tools/orgs/sf-org-open.js +0 -57
- package/lib/tools/testing/index.d.ts +0 -2
- package/lib/tools/testing/index.js +0 -18
- package/lib/tools/testing/sf-test-agents.d.ts +0 -21
- package/lib/tools/testing/sf-test-agents.js +0 -84
- package/lib/tools/testing/sf-test-apex.d.ts +0 -40
- package/lib/tools/testing/sf-test-apex.js +0 -132
- package/lib/tools/users/index.d.ts +0 -1
- package/lib/tools/users/index.js +0 -17
- package/lib/tools/users/sf-assign-permission-set.d.ts +0 -20
- package/lib/tools/users/sf-assign-permission-set.js +0 -89
- package/lib/tsconfig.tsbuildinfo +0 -1
- package/npm-shrinkwrap.json +0 -18827
- /package/lib/{shared → utils}/cache.d.ts +0 -0
- /package/lib/{shared → utils}/cache.js +0 -0
- /package/lib/{shared → utils}/rate-limiter.d.ts +0 -0
- /package/lib/{shared → utils}/rate-limiter.js +0 -0
- /package/lib/{shared → utils}/types.js +0 -0
package/lib/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export default class McpServerCommand extends Command {
|
|
|
4
4
|
static description: string;
|
|
5
5
|
static flags: {
|
|
6
6
|
orgs: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
toolsets: import("@oclif/core/interfaces").OptionFlag<("
|
|
7
|
+
toolsets: import("@oclif/core/interfaces").OptionFlag<(import("@salesforce/mcp-provider-api/src/toolset.js").Toolset | "all")[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
8
|
version: import("@oclif/core/interfaces").BooleanFlag<void>;
|
|
9
9
|
'no-telemetry': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
package/lib/index.js
CHANGED
|
@@ -14,20 +14,15 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
/* eslint-disable no-console */
|
|
17
|
+
import { TOOLSETS } from '@salesforce/mcp-provider-api';
|
|
17
18
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
18
19
|
import { Command, Flags, ux } from '@oclif/core';
|
|
19
|
-
import
|
|
20
|
-
import * as orgs from './tools/orgs/index.js';
|
|
21
|
-
import * as data from './tools/data/index.js';
|
|
22
|
-
import * as users from './tools/users/index.js';
|
|
23
|
-
import * as testing from './tools/testing/index.js';
|
|
24
|
-
import * as metadata from './tools/metadata/index.js';
|
|
25
|
-
import * as dynamic from './tools/dynamic/index.js';
|
|
26
|
-
import Cache from './shared/cache.js';
|
|
20
|
+
import Cache from './utils/cache.js';
|
|
27
21
|
import { Telemetry } from './telemetry.js';
|
|
28
22
|
import { SfMcpServer } from './sf-mcp-server.js';
|
|
29
|
-
import { maybeBuildIndex } from './assets.js';
|
|
30
|
-
import {
|
|
23
|
+
import { maybeBuildIndex } from './utils/assets.js';
|
|
24
|
+
import { registerToolsets } from './utils/registry-utils.js';
|
|
25
|
+
import { Services } from './services.js';
|
|
31
26
|
/**
|
|
32
27
|
* Sanitizes an array of org usernames by replacing specific orgs with a placeholder.
|
|
33
28
|
* Special values (DEFAULT_TARGET_ORG, DEFAULT_TARGET_DEV_HUB, ALLOW_ALL_ORGS) are preserved.
|
|
@@ -137,86 +132,10 @@ You can also use special values to control access to orgs:
|
|
|
137
132
|
},
|
|
138
133
|
}, {
|
|
139
134
|
telemetry: this.telemetry,
|
|
140
|
-
dynamicTools: flags['dynamic-tools'] ?? false,
|
|
141
135
|
});
|
|
142
136
|
await maybeBuildIndex(this.config.dataDir);
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
// CORE TOOLS (always on)
|
|
146
|
-
// If you're adding a new tool to the core toolset, you MUST add it to the `CORE_TOOLS` array in shared/tools.ts
|
|
147
|
-
// otherwise SfMcpServer will not register it.
|
|
148
|
-
//
|
|
149
|
-
// Long term, we will want to consider a more elegant solution for registering core tools.
|
|
150
|
-
// ************************
|
|
151
|
-
this.logToStderr('Registering core tools');
|
|
152
|
-
// get username
|
|
153
|
-
core.registerToolGetUsername(server);
|
|
154
|
-
core.registerToolResume(server);
|
|
155
|
-
core.registerToolSuggestCliCommand(server);
|
|
156
|
-
// DYNAMIC TOOLSETS
|
|
157
|
-
// ************************
|
|
158
|
-
if (toolsetsToEnable.dynamic) {
|
|
159
|
-
this.logToStderr('Registering dynamic tools');
|
|
160
|
-
// Individual tool management
|
|
161
|
-
dynamic.registerToolEnableTools(server);
|
|
162
|
-
dynamic.registerToolListTools(server);
|
|
163
|
-
}
|
|
164
|
-
// ************************
|
|
165
|
-
// ORG TOOLS
|
|
166
|
-
// ************************
|
|
167
|
-
if (toolsetsToEnable.orgs) {
|
|
168
|
-
this.logToStderr('Registering org tools');
|
|
169
|
-
// list all orgs
|
|
170
|
-
orgs.registerToolListAllOrgs(server);
|
|
171
|
-
}
|
|
172
|
-
// ************************
|
|
173
|
-
// DATA TOOLS
|
|
174
|
-
// ************************
|
|
175
|
-
if (toolsetsToEnable.data) {
|
|
176
|
-
this.logToStderr('Registering data tools');
|
|
177
|
-
// query org
|
|
178
|
-
data.registerToolQueryOrg(server);
|
|
179
|
-
}
|
|
180
|
-
// ************************
|
|
181
|
-
// USER TOOLS
|
|
182
|
-
// ************************
|
|
183
|
-
if (toolsetsToEnable.users) {
|
|
184
|
-
this.logToStderr('Registering user tools');
|
|
185
|
-
// assign permission set
|
|
186
|
-
users.registerToolAssignPermissionSet(server);
|
|
187
|
-
}
|
|
188
|
-
// ************************
|
|
189
|
-
// testing TOOLS
|
|
190
|
-
// ************************
|
|
191
|
-
if (toolsetsToEnable.testing) {
|
|
192
|
-
this.logToStderr('Registering testing tools');
|
|
193
|
-
testing.registerToolTestApex(server);
|
|
194
|
-
testing.registerToolTestAgent(server);
|
|
195
|
-
}
|
|
196
|
-
// ************************
|
|
197
|
-
// METADATA TOOLS
|
|
198
|
-
// ************************
|
|
199
|
-
if (toolsetsToEnable.metadata) {
|
|
200
|
-
this.logToStderr('Registering metadata tools');
|
|
201
|
-
// deploy metadata
|
|
202
|
-
metadata.registerToolDeployMetadata(server);
|
|
203
|
-
// retrieve metadata
|
|
204
|
-
metadata.registerToolRetrieveMetadata(server);
|
|
205
|
-
}
|
|
206
|
-
// ************************
|
|
207
|
-
// EXPERIMENTAL TOOLS
|
|
208
|
-
//
|
|
209
|
-
// This toolset needs to be explicitly enabled ('all' will not include it)
|
|
210
|
-
// Tools don't need to be in an 'experimental' directory, only registered here
|
|
211
|
-
// ************************
|
|
212
|
-
if (toolsetsToEnable.experimental) {
|
|
213
|
-
this.logToStderr('Registering experimental tools');
|
|
214
|
-
orgs.registerToolOrgOpen(server);
|
|
215
|
-
// Add any experimental tools here
|
|
216
|
-
orgs.registerToolCreateScratchOrg(server);
|
|
217
|
-
orgs.registerToolDeleteOrg(server);
|
|
218
|
-
orgs.registerToolCreateOrgSnapshot(server);
|
|
219
|
-
}
|
|
137
|
+
const services = new Services({ telemetry: this.telemetry, dataDir: this.config.dataDir });
|
|
138
|
+
await registerToolsets(flags.toolsets ?? ['all'], flags['dynamic-tools'] ?? false, server, services);
|
|
220
139
|
const transport = new StdioServerTransport();
|
|
221
140
|
await server.connect(transport);
|
|
222
141
|
console.error(`✅ Salesforce MCP Server v${this.config.version} running on stdio`);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { McpProvider, McpTool, Services } from '@salesforce/mcp-provider-api';
|
|
2
|
+
import { SfMcpServer } from './sf-mcp-server.js';
|
|
3
|
+
export declare function createDynamicServerTools(server: SfMcpServer): McpTool[];
|
|
4
|
+
export declare class MainServerProvider extends McpProvider {
|
|
5
|
+
getName(): string;
|
|
6
|
+
provideTools(services: Services): Promise<McpTool[]>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025, Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { McpProvider } from '@salesforce/mcp-provider-api';
|
|
17
|
+
import { EnableToolsMcpTool } from './tools/sf-enable-tools.js';
|
|
18
|
+
import { ListToolsMcpTool } from './tools/sf-list-tools.js';
|
|
19
|
+
import { SuggestCliCommandMcpTool } from './tools/sf-suggest-cli-command.js';
|
|
20
|
+
export function createDynamicServerTools(server) {
|
|
21
|
+
return [new EnableToolsMcpTool(server), new ListToolsMcpTool()];
|
|
22
|
+
}
|
|
23
|
+
export class MainServerProvider extends McpProvider {
|
|
24
|
+
getName() {
|
|
25
|
+
return 'MainServerProvider';
|
|
26
|
+
}
|
|
27
|
+
async provideTools(services) {
|
|
28
|
+
return Promise.resolve([new SuggestCliCommandMcpTool(services)]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=main-server-provider.js.map
|
|
@@ -13,7 +13,14 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
import { DxCoreMcpProvider } from '@salesforce/mcp-provider-dx-core';
|
|
17
|
+
import { CodeAnalyzerMcpProvider } from '@salesforce/mcp-provider-code-analyzer';
|
|
18
|
+
import { MainServerProvider } from './main-server-provider.js';
|
|
19
|
+
/** -------- ADD McpProvider INSTANCES HERE ------------------------------------------------------------------------- */
|
|
20
|
+
export const MCP_PROVIDER_REGISTRY = [
|
|
21
|
+
new MainServerProvider(),
|
|
22
|
+
new DxCoreMcpProvider(),
|
|
23
|
+
new CodeAnalyzerMcpProvider(),
|
|
24
|
+
// Add new instances here
|
|
25
|
+
];
|
|
26
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -36,7 +36,7 @@ const main = async () => {
|
|
|
36
36
|
}
|
|
37
37
|
// Define the output file paths
|
|
38
38
|
const commandsPath = path.join(outputDir, 'sf-commands.json');
|
|
39
|
-
const faissIndexPath = path.join(outputDir, '
|
|
39
|
+
const faissIndexPath = path.join(outputDir, 'commands-index.bin');
|
|
40
40
|
ux.stderr('Starting offline data preparation...');
|
|
41
41
|
// 1. Ensure output directory exists
|
|
42
42
|
if (!fs.existsSync(outputDir)) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Services as IServices, TelemetryService, OrgService, ConfigService } from '@salesforce/mcp-provider-api';
|
|
2
|
+
export declare class Services implements IServices {
|
|
3
|
+
private readonly telemetry;
|
|
4
|
+
private readonly dataDir;
|
|
5
|
+
constructor(opts: {
|
|
6
|
+
telemetry: TelemetryService | undefined;
|
|
7
|
+
dataDir: string;
|
|
8
|
+
});
|
|
9
|
+
getTelemetryService(): TelemetryService;
|
|
10
|
+
getConfigService(): ConfigService;
|
|
11
|
+
getOrgService(): OrgService;
|
|
12
|
+
}
|
package/lib/services.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Cache from './utils/cache.js';
|
|
2
|
+
import { getConnection, getDefaultTargetOrg, getDefaultTargetDevHub, getAllAllowedOrgs, findOrgByUsernameOrAlias, } from './utils/auth.js';
|
|
3
|
+
export class Services {
|
|
4
|
+
telemetry;
|
|
5
|
+
dataDir;
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
this.telemetry = opts.telemetry ? opts.telemetry : new NoopTelemetryService();
|
|
8
|
+
this.dataDir = opts.dataDir;
|
|
9
|
+
}
|
|
10
|
+
getTelemetryService() {
|
|
11
|
+
return this.telemetry;
|
|
12
|
+
}
|
|
13
|
+
getConfigService() {
|
|
14
|
+
return {
|
|
15
|
+
getDataDir: () => this.dataDir,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
getOrgService() {
|
|
19
|
+
return {
|
|
20
|
+
getAllowedOrgUsernames: async () => Cache.safeGet('allowedOrgs'),
|
|
21
|
+
getAllowedOrgs: () => getAllAllowedOrgs(),
|
|
22
|
+
getConnection: (username) => getConnection(username),
|
|
23
|
+
getDefaultTargetOrg: () => getDefaultTargetOrg(),
|
|
24
|
+
getDefaultTargetDevHub: () => getDefaultTargetDevHub(),
|
|
25
|
+
findOrgByUsernameOrAlias: (allOrgs, usernameOrAlias) => findOrgByUsernameOrAlias(allOrgs, usernameOrAlias),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
class NoopTelemetryService {
|
|
30
|
+
sendEvent(_eventName, _event) {
|
|
31
|
+
// no-op
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=services.js.map
|
package/lib/sf-mcp-server.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { Implementation } from '@modelcontextprotocol/sdk/types.js';
|
|
1
|
+
import { McpServer, RegisteredTool, ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { Implementation, ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';
|
|
3
3
|
import { ServerOptions } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
+
import { ZodRawShape } from 'zod';
|
|
4
5
|
import { Telemetry } from './telemetry.js';
|
|
5
|
-
import { RateLimitConfig } from './
|
|
6
|
+
import { RateLimitConfig } from './utils/rate-limiter.js';
|
|
6
7
|
type ToolMethodSignatures = {
|
|
7
8
|
tool: McpServer['tool'];
|
|
8
9
|
connect: McpServer['connect'];
|
|
10
|
+
registerTool: McpServer['registerTool'];
|
|
9
11
|
};
|
|
10
12
|
/**
|
|
11
13
|
* Extended server options that include telemetry and rate limiting
|
|
@@ -15,8 +17,6 @@ export type SfMcpServerOptions = ServerOptions & {
|
|
|
15
17
|
telemetry?: Telemetry;
|
|
16
18
|
/** Optional rate limiting configuration */
|
|
17
19
|
rateLimit?: Partial<RateLimitConfig>;
|
|
18
|
-
/** Enable dynamic tool loading */
|
|
19
|
-
dynamicTools?: boolean;
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
22
|
* A server implementation that extends the base MCP server with telemetry and rate limiting capabilities.
|
|
@@ -30,7 +30,6 @@ export declare class SfMcpServer extends McpServer implements ToolMethodSignatur
|
|
|
30
30
|
private logger;
|
|
31
31
|
/** Optional telemetry instance for tracking server events */
|
|
32
32
|
private telemetry?;
|
|
33
|
-
private dynamicTools;
|
|
34
33
|
/** Rate limiter for controlling tool call frequency */
|
|
35
34
|
private rateLimiter?;
|
|
36
35
|
/**
|
|
@@ -41,6 +40,12 @@ export declare class SfMcpServer extends McpServer implements ToolMethodSignatur
|
|
|
41
40
|
*/
|
|
42
41
|
constructor(serverInfo: Implementation, options?: SfMcpServerOptions);
|
|
43
42
|
connect: McpServer['connect'];
|
|
44
|
-
|
|
43
|
+
registerTool<InputArgs extends ZodRawShape, OutputArgs extends ZodRawShape>(name: string, config: {
|
|
44
|
+
title?: string;
|
|
45
|
+
description?: string;
|
|
46
|
+
inputSchema?: InputArgs;
|
|
47
|
+
outputSchema?: OutputArgs;
|
|
48
|
+
annotations?: ToolAnnotations;
|
|
49
|
+
}, cb: ToolCallback<InputArgs>): RegisteredTool;
|
|
45
50
|
}
|
|
46
51
|
export {};
|
package/lib/sf-mcp-server.js
CHANGED
|
@@ -15,8 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
17
17
|
import { Logger } from '@salesforce/core';
|
|
18
|
-
import {
|
|
19
|
-
import { createRateLimiter } from './shared/rate-limiter.js';
|
|
18
|
+
import { createRateLimiter } from './utils/rate-limiter.js';
|
|
20
19
|
/**
|
|
21
20
|
* A server implementation that extends the base MCP server with telemetry and rate limiting capabilities.
|
|
22
21
|
*
|
|
@@ -29,7 +28,6 @@ export class SfMcpServer extends McpServer {
|
|
|
29
28
|
logger = Logger.childFromRoot('mcp-server');
|
|
30
29
|
/** Optional telemetry instance for tracking server events */
|
|
31
30
|
telemetry;
|
|
32
|
-
dynamicTools;
|
|
33
31
|
/** Rate limiter for controlling tool call frequency */
|
|
34
32
|
rateLimiter;
|
|
35
33
|
/**
|
|
@@ -41,7 +39,6 @@ export class SfMcpServer extends McpServer {
|
|
|
41
39
|
constructor(serverInfo, options) {
|
|
42
40
|
super(serverInfo, options);
|
|
43
41
|
this.telemetry = options?.telemetry;
|
|
44
|
-
this.dynamicTools = options?.dynamicTools ?? false;
|
|
45
42
|
// Initialize rate limiter if configuration is provided
|
|
46
43
|
if (options?.rateLimit !== undefined) {
|
|
47
44
|
this.rateLimiter = createRateLimiter(options.rateLimit);
|
|
@@ -74,10 +71,8 @@ export class SfMcpServer extends McpServer {
|
|
|
74
71
|
});
|
|
75
72
|
}
|
|
76
73
|
};
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const cb = rest[rest.length - 1];
|
|
80
|
-
const wrappedCb = async (args) => {
|
|
74
|
+
registerTool(name, config, cb) {
|
|
75
|
+
const wrappedCb = async (args, extra) => {
|
|
81
76
|
this.logger.debug(`Tool ${name} called`);
|
|
82
77
|
// Check rate limit before executing tool
|
|
83
78
|
if (this.rateLimiter) {
|
|
@@ -102,7 +97,7 @@ export class SfMcpServer extends McpServer {
|
|
|
102
97
|
this.logger.debug(`Tool ${name} rate check passed. Remaining: ${rateLimitResult.remaining}`);
|
|
103
98
|
}
|
|
104
99
|
const startTime = Date.now();
|
|
105
|
-
const result = await cb(args);
|
|
100
|
+
const result = await cb(args, extra);
|
|
106
101
|
const runtimeMs = Date.now() - startTime;
|
|
107
102
|
this.logger.debug(`Tool ${name} completed in ${runtimeMs}ms`);
|
|
108
103
|
if (result.isError)
|
|
@@ -114,17 +109,8 @@ export class SfMcpServer extends McpServer {
|
|
|
114
109
|
});
|
|
115
110
|
return result;
|
|
116
111
|
};
|
|
117
|
-
|
|
118
|
-
const tool = super.tool(name, ...rest.slice(0, -1), wrappedCb);
|
|
119
|
-
if (this.dynamicTools) {
|
|
120
|
-
// Only disable the tool if it's not a core tool
|
|
121
|
-
if (!CORE_TOOLS.includes(name))
|
|
122
|
-
tool.disable();
|
|
123
|
-
addTool(tool, name).catch((error) => {
|
|
124
|
-
this.logger.error(`Failed to add tool ${name}:`, error);
|
|
125
|
-
});
|
|
126
|
-
}
|
|
112
|
+
const tool = super.registerTool(name, config, wrappedCb);
|
|
127
113
|
return tool;
|
|
128
|
-
}
|
|
114
|
+
}
|
|
129
115
|
}
|
|
130
116
|
//# sourceMappingURL=sf-mcp-server.js.map
|
package/lib/telemetry.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Attributes } from '@salesforce/telemetry';
|
|
2
2
|
import { Config } from '@oclif/core';
|
|
3
|
-
|
|
3
|
+
import { TelemetryService } from '@salesforce/mcp-provider-api/src/index.js';
|
|
4
|
+
export declare class Telemetry implements TelemetryService {
|
|
4
5
|
private readonly config;
|
|
5
6
|
private attributes;
|
|
6
7
|
/**
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { McpTool, McpToolConfig, Toolset } from '@salesforce/mcp-provider-api';
|
|
3
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { SfMcpServer } from '../sf-mcp-server.js';
|
|
5
|
+
declare const enableToolsParamsSchema: z.ZodObject<{
|
|
6
|
+
tools: z.ZodArray<z.ZodString, "many">;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
tools: string[];
|
|
9
|
+
}, {
|
|
10
|
+
tools: string[];
|
|
11
|
+
}>;
|
|
12
|
+
type InputArgs = z.infer<typeof enableToolsParamsSchema>;
|
|
13
|
+
type InputArgsShapeType = typeof enableToolsParamsSchema.shape;
|
|
14
|
+
type OutputArgsShapeType = z.ZodRawShape;
|
|
15
|
+
export declare class EnableToolsMcpTool extends McpTool<InputArgsShapeType, OutputArgsShapeType> {
|
|
16
|
+
private readonly server;
|
|
17
|
+
constructor(server: SfMcpServer);
|
|
18
|
+
getToolsets(): Toolset[];
|
|
19
|
+
getName(): string;
|
|
20
|
+
getConfig(): McpToolConfig<InputArgsShapeType, OutputArgsShapeType>;
|
|
21
|
+
exec(input: InputArgs): Promise<CallToolResult>;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025, Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
import { McpTool, Toolset } from '@salesforce/mcp-provider-api';
|
|
18
|
+
import { enableTools as utilEnableTools } from '../utils/tools.js';
|
|
19
|
+
const enableToolsParamsSchema = z.object({
|
|
20
|
+
tools: z.array(z.string()).describe('The names of the tools to enable'),
|
|
21
|
+
});
|
|
22
|
+
export class EnableToolsMcpTool extends McpTool {
|
|
23
|
+
server;
|
|
24
|
+
constructor(server) {
|
|
25
|
+
super();
|
|
26
|
+
this.server = server;
|
|
27
|
+
}
|
|
28
|
+
getToolsets() {
|
|
29
|
+
return [Toolset.CORE];
|
|
30
|
+
}
|
|
31
|
+
getName() {
|
|
32
|
+
return 'sf-enable-tools';
|
|
33
|
+
}
|
|
34
|
+
getConfig() {
|
|
35
|
+
return {
|
|
36
|
+
title: 'Enable Salesforce MCP tools',
|
|
37
|
+
description: `Enable one or more of the tools the Salesforce MCP server provides.
|
|
38
|
+
|
|
39
|
+
AGENT INSTRUCTIONS:
|
|
40
|
+
Use sf-list-all-tools first to learn what tools are available for enabling.
|
|
41
|
+
Once you have enabled the tool, you MUST invoke that tool to accomplish the user's original request - DO NOT USE A DIFFERENT TOOL OR THE COMMAND LINE.`,
|
|
42
|
+
inputSchema: enableToolsParamsSchema.shape,
|
|
43
|
+
outputSchema: undefined,
|
|
44
|
+
annotations: {
|
|
45
|
+
title: 'Enable Salesforce MCP tools',
|
|
46
|
+
readOnlyHint: true,
|
|
47
|
+
openWorldHint: false,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async exec(input) {
|
|
52
|
+
if (input.tools.length === 0) {
|
|
53
|
+
return {
|
|
54
|
+
isError: true,
|
|
55
|
+
content: [
|
|
56
|
+
{
|
|
57
|
+
type: 'text',
|
|
58
|
+
text: 'No tools specified to enable.',
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const results = await utilEnableTools(input.tools);
|
|
64
|
+
this.server.sendToolListChanged();
|
|
65
|
+
const isError = results.some((result) => !result.success);
|
|
66
|
+
return {
|
|
67
|
+
isError,
|
|
68
|
+
content: [
|
|
69
|
+
{
|
|
70
|
+
type: 'text',
|
|
71
|
+
text: results.map((result) => result.message).join('\n'),
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=sf-enable-tools.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { McpTool, McpToolConfig, Toolset } from '@salesforce/mcp-provider-api';
|
|
2
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
export declare class ListToolsMcpTool extends McpTool {
|
|
4
|
+
getToolsets(): Toolset[];
|
|
5
|
+
getName(): string;
|
|
6
|
+
getConfig(): McpToolConfig;
|
|
7
|
+
exec(): Promise<CallToolResult>;
|
|
8
|
+
}
|
|
@@ -13,10 +13,19 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {
|
|
17
|
-
import { listAllTools } from '
|
|
18
|
-
export
|
|
19
|
-
|
|
16
|
+
import { McpTool, Toolset } from '@salesforce/mcp-provider-api';
|
|
17
|
+
import { listAllTools } from '../utils/tools.js';
|
|
18
|
+
export class ListToolsMcpTool extends McpTool {
|
|
19
|
+
getToolsets() {
|
|
20
|
+
return [Toolset.CORE];
|
|
21
|
+
}
|
|
22
|
+
getName() {
|
|
23
|
+
return 'sf-list-tools';
|
|
24
|
+
}
|
|
25
|
+
getConfig() {
|
|
26
|
+
return {
|
|
27
|
+
title: 'List all individual tools',
|
|
28
|
+
description: `List all available tools this Salesforce MCP server can offer, providing the enabled status and description of each.
|
|
20
29
|
|
|
21
30
|
AGENT INSTRUCTIONS:
|
|
22
31
|
DO NOT USE THIS TOOL if you already know what tool you need - try to call the tool directly first.
|
|
@@ -27,10 +36,25 @@ ONLY use this tool if:
|
|
|
27
36
|
|
|
28
37
|
If you find one or more tools you want to enable, call sf-enable-tools with all the tool names.
|
|
29
38
|
Once you have enabled a tool, you MUST invoke the tool to accomplish the user's original request - DO NOT USE A DIFFERENT TOOL OR THE COMMAND LINE.
|
|
30
|
-
Once a tool has been enabled, you do not need to call sf-list-tools again - instead, invoke the desired tool directly.`,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
Once a tool has been enabled, you do not need to call sf-list-tools again - instead, invoke the desired tool directly.`,
|
|
40
|
+
inputSchema: undefined,
|
|
41
|
+
outputSchema: undefined,
|
|
42
|
+
annotations: {
|
|
43
|
+
readOnlyHint: true,
|
|
44
|
+
openWorldHint: false,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async exec() {
|
|
49
|
+
return {
|
|
50
|
+
isError: false,
|
|
51
|
+
content: [
|
|
52
|
+
{
|
|
53
|
+
type: 'text',
|
|
54
|
+
text: JSON.stringify(await listAllTools(), null, 2),
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
35
59
|
}
|
|
36
60
|
//# sourceMappingURL=sf-list-tools.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { McpTool, McpToolConfig, Toolset, Services } from '@salesforce/mcp-provider-api';
|
|
3
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Suggest a Salesforce CLI (sf) command based on user input.
|
|
6
|
+
*/
|
|
7
|
+
declare const suggestCliCommandParamsSchema: z.ZodObject<{
|
|
8
|
+
query: z.ZodString;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
query: string;
|
|
11
|
+
}, {
|
|
12
|
+
query: string;
|
|
13
|
+
}>;
|
|
14
|
+
type InputArgs = z.infer<typeof suggestCliCommandParamsSchema>;
|
|
15
|
+
type InputArgsShape = typeof suggestCliCommandParamsSchema.shape;
|
|
16
|
+
type OutputArgsShape = z.ZodRawShape;
|
|
17
|
+
export declare class SuggestCliCommandMcpTool extends McpTool<InputArgsShape, OutputArgsShape> {
|
|
18
|
+
private readonly services;
|
|
19
|
+
constructor(services: Services);
|
|
20
|
+
getToolsets(): Toolset[];
|
|
21
|
+
getName(): string;
|
|
22
|
+
getConfig(): McpToolConfig<InputArgsShape, OutputArgsShape>;
|
|
23
|
+
exec(input: InputArgs): Promise<CallToolResult>;
|
|
24
|
+
}
|
|
25
|
+
export {};
|