salesflare-mcp-server 1.0.0
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/API.md +691 -0
- package/CHANGELOG.md +49 -0
- package/CLAUDE.md +117 -0
- package/CONTRIBUTING.md +399 -0
- package/FIX_PLAN.md +70 -0
- package/INSPECTOR.md +191 -0
- package/LICENSE +21 -0
- package/PUBLISH.md +73 -0
- package/README.md +383 -0
- package/dist/auth/api-key-auth.d.ts +75 -0
- package/dist/auth/api-key-auth.d.ts.map +1 -0
- package/dist/auth/api-key-auth.js +103 -0
- package/dist/auth/oauth-auth.d.ts +81 -0
- package/dist/auth/oauth-auth.d.ts.map +1 -0
- package/dist/auth/oauth-auth.js +123 -0
- package/dist/auth/token-manager.d.ts +105 -0
- package/dist/auth/token-manager.d.ts.map +1 -0
- package/dist/auth/token-manager.js +87 -0
- package/dist/client/salesflare-client.d.ts +219 -0
- package/dist/client/salesflare-client.d.ts.map +1 -0
- package/dist/client/salesflare-client.js +484 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/server.d.ts +39 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +140 -0
- package/dist/tools/companies.d.ts +45 -0
- package/dist/tools/companies.d.ts.map +1 -0
- package/dist/tools/companies.js +392 -0
- package/dist/tools/contacts.d.ts +45 -0
- package/dist/tools/contacts.d.ts.map +1 -0
- package/dist/tools/contacts.js +290 -0
- package/dist/tools/deals.d.ts +46 -0
- package/dist/tools/deals.d.ts.map +1 -0
- package/dist/tools/deals.js +442 -0
- package/dist/tools/pipeline.d.ts +43 -0
- package/dist/tools/pipeline.d.ts.map +1 -0
- package/dist/tools/pipeline.js +328 -0
- package/dist/tools/tasks.d.ts +44 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +406 -0
- package/dist/transport/http-transport.d.ts +36 -0
- package/dist/transport/http-transport.d.ts.map +1 -0
- package/dist/transport/http-transport.js +173 -0
- package/dist/transport/stdio-transport.d.ts +37 -0
- package/dist/transport/stdio-transport.d.ts.map +1 -0
- package/dist/transport/stdio-transport.js +129 -0
- package/dist/types/company.d.ts +223 -0
- package/dist/types/company.d.ts.map +1 -0
- package/dist/types/company.js +8 -0
- package/dist/types/contact.d.ts +166 -0
- package/dist/types/contact.d.ts.map +1 -0
- package/dist/types/contact.js +8 -0
- package/dist/types/deal.d.ts +203 -0
- package/dist/types/deal.d.ts.map +1 -0
- package/dist/types/deal.js +8 -0
- package/dist/types/pipeline.d.ts +116 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +8 -0
- package/dist/types/task.d.ts +154 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +8 -0
- package/dist/utils/errors.d.ts +128 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +205 -0
- package/dist/utils/validation.d.ts +354 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +716 -0
- package/package.json +49 -0
- package/test-tasks-debug.js +21 -0
- package/test-tasks-params.js +52 -0
- package/test-tools.js +171 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Salesflare MCP Server - Main entry point
|
|
4
|
+
*
|
|
5
|
+
* Entry point for the Salesflare MCP Server application.
|
|
6
|
+
* Reads TRANSPORT environment variable, creates and configures the server,
|
|
7
|
+
* and starts the appropriate transport.
|
|
8
|
+
*
|
|
9
|
+
* Per D-09: Transport selection via TRANSPORT environment variable.
|
|
10
|
+
* Per D-06: Exits with code 1 on initialization failure.
|
|
11
|
+
*
|
|
12
|
+
* @module index
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Salesflare MCP Server - Main entry point
|
|
4
|
+
*
|
|
5
|
+
* Entry point for the Salesflare MCP Server application.
|
|
6
|
+
* Reads TRANSPORT environment variable, creates and configures the server,
|
|
7
|
+
* and starts the appropriate transport.
|
|
8
|
+
*
|
|
9
|
+
* Per D-09: Transport selection via TRANSPORT environment variable.
|
|
10
|
+
* Per D-06: Exits with code 1 on initialization failure.
|
|
11
|
+
*
|
|
12
|
+
* @module index
|
|
13
|
+
*/
|
|
14
|
+
import { createServer } from './server.js';
|
|
15
|
+
import { startStdioServer } from './transport/stdio-transport.js';
|
|
16
|
+
import { createHttpTransport } from './transport/http-transport.js';
|
|
17
|
+
import { SalesflareError, formatErrorResponse, ErrorCode } from './utils/errors.js';
|
|
18
|
+
/**
|
|
19
|
+
* Main entry point for the Salesflare MCP Server
|
|
20
|
+
*
|
|
21
|
+
* 1. Reads TRANSPORT environment variable (default: stdio)
|
|
22
|
+
* 2. Creates and configures the MCP server
|
|
23
|
+
* 3. Starts the appropriate transport
|
|
24
|
+
* 4. Handles errors gracefully with exit code 1 on failure
|
|
25
|
+
*/
|
|
26
|
+
async function main() {
|
|
27
|
+
try {
|
|
28
|
+
// Read TRANSPORT environment variable (default: stdio)
|
|
29
|
+
const transport = process.env.TRANSPORT || 'stdio';
|
|
30
|
+
// Log startup messages to stderr (never stdout to avoid protocol corruption)
|
|
31
|
+
console.error('Starting Salesflare MCP server...');
|
|
32
|
+
console.error(`Transport: ${transport}`);
|
|
33
|
+
// Create the MCP server
|
|
34
|
+
// This will validate auth and crash on startup if SALESFLARE_API_KEY is missing
|
|
35
|
+
const server = createServer({ transport: transport });
|
|
36
|
+
// Start the appropriate transport
|
|
37
|
+
if (transport === 'stdio') {
|
|
38
|
+
await startStdioServer({ server });
|
|
39
|
+
}
|
|
40
|
+
else if (transport === 'http') {
|
|
41
|
+
// HTTP transport with Express
|
|
42
|
+
await createHttpTransport({
|
|
43
|
+
port: parseInt(process.env.PORT || '3000', 10),
|
|
44
|
+
host: process.env.HOST || 'localhost',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Unknown transport
|
|
49
|
+
throw new SalesflareError({
|
|
50
|
+
code: ErrorCode.CONFIG_ERROR,
|
|
51
|
+
message: `Unknown transport: ${transport}`,
|
|
52
|
+
fix: 'Use "stdio" for CLI/inspector mode or "http" for HTTP transport (Phase 2)',
|
|
53
|
+
retryable: false,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
// Log full error to stderr
|
|
59
|
+
if (error instanceof SalesflareError) {
|
|
60
|
+
console.error(`\nError: ${error.message}`);
|
|
61
|
+
if (error.fix) {
|
|
62
|
+
console.error(`Fix: ${error.fix}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (error instanceof Error) {
|
|
66
|
+
console.error(`\nError: ${error.message}`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.error('\nAn unknown error occurred');
|
|
70
|
+
}
|
|
71
|
+
// Format user-friendly error message
|
|
72
|
+
const errorResponse = formatErrorResponse(error);
|
|
73
|
+
console.error(`\n[${errorResponse.code}] ${errorResponse.message}`);
|
|
74
|
+
if (errorResponse.fix) {
|
|
75
|
+
console.error(`Fix: ${errorResponse.fix}`);
|
|
76
|
+
}
|
|
77
|
+
// Exit with code 1 on failure
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Run the main function
|
|
82
|
+
main();
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server setup for Salesflare MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Creates and configures the MCP server with all tool registrations.
|
|
5
|
+
* Follows the server setup flow per D-19, D-20.
|
|
6
|
+
*
|
|
7
|
+
* @module server
|
|
8
|
+
*/
|
|
9
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* Server configuration options
|
|
12
|
+
*/
|
|
13
|
+
export interface ServerConfig {
|
|
14
|
+
/** Transport mode for the server (stdio or http) */
|
|
15
|
+
transport?: 'stdio' | 'http';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create and configure the MCP server with all tools
|
|
19
|
+
*
|
|
20
|
+
* Initializes the server with:
|
|
21
|
+
* 1. Auth provider (API key from environment)
|
|
22
|
+
* 2. Salesflare API client
|
|
23
|
+
* 3. MCP server instance with tool capabilities
|
|
24
|
+
* 4. Registration of all entity tools
|
|
25
|
+
*
|
|
26
|
+
* Per D-06: Crashes on startup if SALESFLARE_API_KEY is missing.
|
|
27
|
+
*
|
|
28
|
+
* @param config - Optional server configuration
|
|
29
|
+
* @returns Configured MCP Server instance
|
|
30
|
+
* @throws {SalesflareError} If initialization fails or auth is missing
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const server = createServer({ transport: 'stdio' });
|
|
35
|
+
* await server.connect(transport);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function createServer(config?: ServerConfig): Server;
|
|
39
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAWnE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,CA0G1D"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server setup for Salesflare MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Creates and configures the MCP server with all tool registrations.
|
|
5
|
+
* Follows the server setup flow per D-19, D-20.
|
|
6
|
+
*
|
|
7
|
+
* @module server
|
|
8
|
+
*/
|
|
9
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
|
+
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
+
import { createApiKeyAuth } from './auth/api-key-auth.js';
|
|
12
|
+
import { createSalesflareClient } from './client/salesflare-client.js';
|
|
13
|
+
import { contactTools, handleContactsTool } from './tools/contacts.js';
|
|
14
|
+
import { companyTools, handleCompaniesTool } from './tools/companies.js';
|
|
15
|
+
import { dealTools, handleDealsTool } from './tools/deals.js';
|
|
16
|
+
import { taskTools, handleTasksTool } from './tools/tasks.js';
|
|
17
|
+
import { pipelineTools, handlePipelineTool } from './tools/pipeline.js';
|
|
18
|
+
import { SalesflareError, formatErrorResponse, ErrorCode } from './utils/errors.js';
|
|
19
|
+
/**
|
|
20
|
+
* Create and configure the MCP server with all tools
|
|
21
|
+
*
|
|
22
|
+
* Initializes the server with:
|
|
23
|
+
* 1. Auth provider (API key from environment)
|
|
24
|
+
* 2. Salesflare API client
|
|
25
|
+
* 3. MCP server instance with tool capabilities
|
|
26
|
+
* 4. Registration of all entity tools
|
|
27
|
+
*
|
|
28
|
+
* Per D-06: Crashes on startup if SALESFLARE_API_KEY is missing.
|
|
29
|
+
*
|
|
30
|
+
* @param config - Optional server configuration
|
|
31
|
+
* @returns Configured MCP Server instance
|
|
32
|
+
* @throws {SalesflareError} If initialization fails or auth is missing
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const server = createServer({ transport: 'stdio' });
|
|
37
|
+
* await server.connect(transport);
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function createServer(config) {
|
|
41
|
+
try {
|
|
42
|
+
// Step 1: Create auth provider (reads SALESFLARE_API_KEY from env)
|
|
43
|
+
// Per D-06: This will throw if API key is missing
|
|
44
|
+
const auth = createApiKeyAuth();
|
|
45
|
+
// Step 2: Create API client with auth provider
|
|
46
|
+
const client = createSalesflareClient({ authProvider: auth });
|
|
47
|
+
// Step 3: Create MCP server instance
|
|
48
|
+
const server = new Server({
|
|
49
|
+
name: 'salesflare-mcp',
|
|
50
|
+
version: '1.0.0',
|
|
51
|
+
}, {
|
|
52
|
+
capabilities: {
|
|
53
|
+
tools: {},
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
// Step 4: Combine all tools
|
|
57
|
+
const allTools = [
|
|
58
|
+
...contactTools,
|
|
59
|
+
...companyTools,
|
|
60
|
+
...dealTools,
|
|
61
|
+
...taskTools,
|
|
62
|
+
...pipelineTools,
|
|
63
|
+
];
|
|
64
|
+
// Step 5: Register unified tool list handler
|
|
65
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
66
|
+
return { tools: allTools };
|
|
67
|
+
});
|
|
68
|
+
// Step 6: Register unified tool call handler
|
|
69
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
70
|
+
const { name, arguments: args } = request.params;
|
|
71
|
+
try {
|
|
72
|
+
// Dispatch to appropriate handler based on tool name prefix
|
|
73
|
+
if (name.startsWith('salesflare_contacts_')) {
|
|
74
|
+
return await handleContactsTool(client, name, args);
|
|
75
|
+
}
|
|
76
|
+
else if (name.startsWith('salesflare_companies_')) {
|
|
77
|
+
return await handleCompaniesTool(client, name, args);
|
|
78
|
+
}
|
|
79
|
+
else if (name.startsWith('salesflare_deals_')) {
|
|
80
|
+
return await handleDealsTool(client, name, args);
|
|
81
|
+
}
|
|
82
|
+
else if (name.startsWith('salesflare_tasks_')) {
|
|
83
|
+
return await handleTasksTool(client, name, args);
|
|
84
|
+
}
|
|
85
|
+
else if (name.startsWith('salesflare_pipeline_')) {
|
|
86
|
+
return await handlePipelineTool(client, name, args);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
throw new SalesflareError({
|
|
90
|
+
code: ErrorCode.INVALID_INPUT,
|
|
91
|
+
message: `Unknown tool: ${name}`,
|
|
92
|
+
retryable: false,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (error instanceof SalesflareError) {
|
|
98
|
+
return { content: [{ type: 'text', text: error.toToolResponse() }] };
|
|
99
|
+
}
|
|
100
|
+
const formattedError = formatErrorResponse(error);
|
|
101
|
+
return { content: [{ type: 'text', text: formattedError.message }] };
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
// Step 7: Set up error handler
|
|
105
|
+
server.onerror = (error) => {
|
|
106
|
+
console.error('MCP Server error:', error);
|
|
107
|
+
};
|
|
108
|
+
return server;
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
// Handle SalesflareError - re-throw with context
|
|
112
|
+
if (error instanceof SalesflareError) {
|
|
113
|
+
console.error(`Server initialization failed: ${error.message}`);
|
|
114
|
+
if (error.fix) {
|
|
115
|
+
console.error(`Fix: ${error.fix}`);
|
|
116
|
+
}
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
// Handle generic errors - wrap in SalesflareError
|
|
120
|
+
if (error instanceof Error) {
|
|
121
|
+
const wrappedError = new SalesflareError({
|
|
122
|
+
code: ErrorCode.SERVER_ERROR,
|
|
123
|
+
message: `Failed to initialize MCP server: ${error.message}`,
|
|
124
|
+
fix: 'Check server configuration and ensure all dependencies are properly set up',
|
|
125
|
+
retryable: false,
|
|
126
|
+
});
|
|
127
|
+
console.error(wrappedError.message);
|
|
128
|
+
throw wrappedError;
|
|
129
|
+
}
|
|
130
|
+
// Handle unknown errors
|
|
131
|
+
const unknownError = new SalesflareError({
|
|
132
|
+
code: ErrorCode.SERVER_ERROR,
|
|
133
|
+
message: 'Failed to initialize MCP server: Unknown error occurred',
|
|
134
|
+
fix: 'Check server logs for details',
|
|
135
|
+
retryable: false,
|
|
136
|
+
});
|
|
137
|
+
console.error(unknownError.message);
|
|
138
|
+
throw unknownError;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Company tools for Salesflare MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Implements CRUD operations for companies:
|
|
5
|
+
* - salesflare_companies_list: List companies with filtering and pagination
|
|
6
|
+
* - salesflare_companies_create: Create new companies
|
|
7
|
+
* - salesflare_companies_update: Update existing companies
|
|
8
|
+
* - salesflare_companies_delete: Delete companies
|
|
9
|
+
*
|
|
10
|
+
* @module tools/companies
|
|
11
|
+
*/
|
|
12
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
13
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
14
|
+
import { SalesflareClient } from '../client/salesflare-client.js';
|
|
15
|
+
/**
|
|
16
|
+
* Company tool definitions with JSON schemas
|
|
17
|
+
*/
|
|
18
|
+
declare const companyTools: Tool[];
|
|
19
|
+
/**
|
|
20
|
+
* Exported company tools array for unified registration
|
|
21
|
+
*/
|
|
22
|
+
export { companyTools };
|
|
23
|
+
/**
|
|
24
|
+
* Handle company tool calls
|
|
25
|
+
*
|
|
26
|
+
* @param client - Salesflare API client
|
|
27
|
+
* @param name - Tool name
|
|
28
|
+
* @param args - Tool arguments
|
|
29
|
+
* @returns Tool response
|
|
30
|
+
*/
|
|
31
|
+
export declare function handleCompaniesTool(client: SalesflareClient, name: string, args: unknown): Promise<{
|
|
32
|
+
content: Array<{
|
|
33
|
+
type: string;
|
|
34
|
+
text: string;
|
|
35
|
+
}>;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Register company-related tools with the MCP server
|
|
39
|
+
*
|
|
40
|
+
* @deprecated Use handleCompaniesTool instead for unified registration
|
|
41
|
+
* @param server - MCP Server instance
|
|
42
|
+
* @param client - Salesflare API client
|
|
43
|
+
*/
|
|
44
|
+
export declare function registerCompaniesTools(server: Server, client: SalesflareClient): void;
|
|
45
|
+
//# sourceMappingURL=companies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companies.d.ts","sourceRoot":"","sources":["../../src/tools/companies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAGL,IAAI,EACL,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AASlE;;GAEG;AACH,QAAA,MAAM,YAAY,EAAE,IAAI,EA6GvB,CAAC;AAEF;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAqB7D;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAGrF"}
|