@codespar/mcp-rd-station 0.1.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/dist/index.js +210 -0
- package/package.json +29 -0
- package/src/index.ts +222 -0
- package/tsconfig.json +13 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Server for RD Station — Brazilian CRM and marketing automation.
|
|
4
|
+
*
|
|
5
|
+
* Tools:
|
|
6
|
+
* - create_contact: Create a contact in RD Station
|
|
7
|
+
* - update_contact: Update a contact by UUID
|
|
8
|
+
* - get_contact: Get contact details by UUID or email
|
|
9
|
+
* - list_contacts: List contacts with pagination
|
|
10
|
+
* - create_event: Create a conversion event
|
|
11
|
+
* - list_funnels: List sales funnels
|
|
12
|
+
* - get_funnel: Get funnel details with stages
|
|
13
|
+
* - create_opportunity: Create a sales opportunity
|
|
14
|
+
*
|
|
15
|
+
* Environment:
|
|
16
|
+
* RD_STATION_TOKEN — Bearer token from https://app.rdstation.com/
|
|
17
|
+
*/
|
|
18
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
19
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
20
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
21
|
+
const TOKEN = process.env.RD_STATION_TOKEN || "";
|
|
22
|
+
const BASE_URL = "https://api.rd.services";
|
|
23
|
+
async function rdStationRequest(method, path, body) {
|
|
24
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
25
|
+
method,
|
|
26
|
+
headers: {
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
"Authorization": `Bearer ${TOKEN}`,
|
|
29
|
+
},
|
|
30
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
31
|
+
});
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
const err = await res.text();
|
|
34
|
+
throw new Error(`RD Station API ${res.status}: ${err}`);
|
|
35
|
+
}
|
|
36
|
+
return res.json();
|
|
37
|
+
}
|
|
38
|
+
const server = new Server({ name: "mcp-rd-station", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
39
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
40
|
+
tools: [
|
|
41
|
+
{
|
|
42
|
+
name: "create_contact",
|
|
43
|
+
description: "Create a contact in RD Station CRM",
|
|
44
|
+
inputSchema: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
email: { type: "string", description: "Contact email" },
|
|
48
|
+
name: { type: "string", description: "Contact name" },
|
|
49
|
+
job_title: { type: "string", description: "Job title" },
|
|
50
|
+
phone: { type: "string", description: "Phone number" },
|
|
51
|
+
company: { type: "string", description: "Company name" },
|
|
52
|
+
tags: {
|
|
53
|
+
type: "array",
|
|
54
|
+
items: { type: "string" },
|
|
55
|
+
description: "Tags to assign",
|
|
56
|
+
},
|
|
57
|
+
cf_custom_fields: { type: "object", description: "Custom fields (key-value)" },
|
|
58
|
+
},
|
|
59
|
+
required: ["email"],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: "update_contact",
|
|
64
|
+
description: "Update a contact by UUID",
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: "object",
|
|
67
|
+
properties: {
|
|
68
|
+
uuid: { type: "string", description: "Contact UUID" },
|
|
69
|
+
name: { type: "string", description: "Updated name" },
|
|
70
|
+
email: { type: "string", description: "Updated email" },
|
|
71
|
+
job_title: { type: "string", description: "Updated job title" },
|
|
72
|
+
phone: { type: "string", description: "Updated phone" },
|
|
73
|
+
company: { type: "string", description: "Updated company" },
|
|
74
|
+
tags: { type: "array", items: { type: "string" }, description: "Updated tags" },
|
|
75
|
+
},
|
|
76
|
+
required: ["uuid"],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: "get_contact",
|
|
81
|
+
description: "Get contact details by UUID or email",
|
|
82
|
+
inputSchema: {
|
|
83
|
+
type: "object",
|
|
84
|
+
properties: {
|
|
85
|
+
uuid: { type: "string", description: "Contact UUID" },
|
|
86
|
+
email: { type: "string", description: "Contact email (alternative to UUID)" },
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "list_contacts",
|
|
92
|
+
description: "List contacts with pagination",
|
|
93
|
+
inputSchema: {
|
|
94
|
+
type: "object",
|
|
95
|
+
properties: {
|
|
96
|
+
page: { type: "number", description: "Page number (default 1)" },
|
|
97
|
+
limit: { type: "number", description: "Results per page (default 25)" },
|
|
98
|
+
query: { type: "string", description: "Search query" },
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "create_event",
|
|
104
|
+
description: "Create a conversion event for a contact",
|
|
105
|
+
inputSchema: {
|
|
106
|
+
type: "object",
|
|
107
|
+
properties: {
|
|
108
|
+
event_type: { type: "string", enum: ["CONVERSION", "OPPORTUNITY", "SALE", "OPPORTUNITY_LOST"], description: "Event type" },
|
|
109
|
+
event_family: { type: "string", enum: ["CDP"], description: "Event family" },
|
|
110
|
+
payload: {
|
|
111
|
+
type: "object",
|
|
112
|
+
description: "Event payload",
|
|
113
|
+
properties: {
|
|
114
|
+
conversion_identifier: { type: "string", description: "Conversion identifier (e.g. form name)" },
|
|
115
|
+
email: { type: "string", description: "Contact email" },
|
|
116
|
+
name: { type: "string", description: "Contact name" },
|
|
117
|
+
cf_custom_fields: { type: "object", description: "Custom fields" },
|
|
118
|
+
},
|
|
119
|
+
required: ["conversion_identifier", "email"],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
required: ["event_type", "event_family", "payload"],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "list_funnels",
|
|
127
|
+
description: "List all sales funnels",
|
|
128
|
+
inputSchema: { type: "object", properties: {} },
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: "get_funnel",
|
|
132
|
+
description: "Get funnel details with stages",
|
|
133
|
+
inputSchema: {
|
|
134
|
+
type: "object",
|
|
135
|
+
properties: {
|
|
136
|
+
id: { type: "string", description: "Funnel ID" },
|
|
137
|
+
},
|
|
138
|
+
required: ["id"],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "create_opportunity",
|
|
143
|
+
description: "Create a sales opportunity in a funnel",
|
|
144
|
+
inputSchema: {
|
|
145
|
+
type: "object",
|
|
146
|
+
properties: {
|
|
147
|
+
deal_stage_id: { type: "string", description: "Stage ID in the funnel" },
|
|
148
|
+
name: { type: "string", description: "Opportunity name" },
|
|
149
|
+
contact_uuid: { type: "string", description: "Contact UUID" },
|
|
150
|
+
amount: { type: "number", description: "Deal amount in cents" },
|
|
151
|
+
prediction_date: { type: "string", description: "Expected close date (YYYY-MM-DD)" },
|
|
152
|
+
},
|
|
153
|
+
required: ["deal_stage_id", "name"],
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
}));
|
|
158
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
159
|
+
const { name, arguments: args } = request.params;
|
|
160
|
+
try {
|
|
161
|
+
switch (name) {
|
|
162
|
+
case "create_contact":
|
|
163
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("POST", "/platform/contacts", args), null, 2) }] };
|
|
164
|
+
case "update_contact": {
|
|
165
|
+
const uuid = args?.uuid;
|
|
166
|
+
const body = { ...args };
|
|
167
|
+
delete body.uuid;
|
|
168
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("PATCH", `/platform/contacts/${uuid}`, body), null, 2) }] };
|
|
169
|
+
}
|
|
170
|
+
case "get_contact": {
|
|
171
|
+
if (args?.uuid) {
|
|
172
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("GET", `/platform/contacts/${args.uuid}`), null, 2) }] };
|
|
173
|
+
}
|
|
174
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("GET", `/platform/contacts/email:${args?.email}`), null, 2) }] };
|
|
175
|
+
}
|
|
176
|
+
case "list_contacts": {
|
|
177
|
+
const params = new URLSearchParams();
|
|
178
|
+
if (args?.page)
|
|
179
|
+
params.set("page", String(args.page));
|
|
180
|
+
if (args?.limit)
|
|
181
|
+
params.set("limit", String(args.limit));
|
|
182
|
+
if (args?.query)
|
|
183
|
+
params.set("query", String(args.query));
|
|
184
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("GET", `/platform/contacts?${params}`), null, 2) }] };
|
|
185
|
+
}
|
|
186
|
+
case "create_event":
|
|
187
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("POST", "/platform/events", args), null, 2) }] };
|
|
188
|
+
case "list_funnels":
|
|
189
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("GET", "/platform/deal_pipelines"), null, 2) }] };
|
|
190
|
+
case "get_funnel":
|
|
191
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("GET", `/platform/deal_pipelines/${args?.id}`), null, 2) }] };
|
|
192
|
+
case "create_opportunity":
|
|
193
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("POST", "/platform/deals", args), null, 2) }] };
|
|
194
|
+
default:
|
|
195
|
+
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
return { content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
async function main() {
|
|
203
|
+
if (!TOKEN) {
|
|
204
|
+
console.error("RD_STATION_TOKEN environment variable is required");
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
const transport = new StdioServerTransport();
|
|
208
|
+
await server.connect(transport);
|
|
209
|
+
}
|
|
210
|
+
main().catch(console.error);
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codespar/mcp-rd-station",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for RD Station — contacts, events, funnels, opportunities",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mcp-rd-station": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "^25.5.0",
|
|
19
|
+
"typescript": "^5.8.0"
|
|
20
|
+
},
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"keywords": [
|
|
23
|
+
"mcp",
|
|
24
|
+
"rd-station",
|
|
25
|
+
"crm",
|
|
26
|
+
"marketing",
|
|
27
|
+
"brazil"
|
|
28
|
+
]
|
|
29
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MCP Server for RD Station — Brazilian CRM and marketing automation.
|
|
5
|
+
*
|
|
6
|
+
* Tools:
|
|
7
|
+
* - create_contact: Create a contact in RD Station
|
|
8
|
+
* - update_contact: Update a contact by UUID
|
|
9
|
+
* - get_contact: Get contact details by UUID or email
|
|
10
|
+
* - list_contacts: List contacts with pagination
|
|
11
|
+
* - create_event: Create a conversion event
|
|
12
|
+
* - list_funnels: List sales funnels
|
|
13
|
+
* - get_funnel: Get funnel details with stages
|
|
14
|
+
* - create_opportunity: Create a sales opportunity
|
|
15
|
+
*
|
|
16
|
+
* Environment:
|
|
17
|
+
* RD_STATION_TOKEN — Bearer token from https://app.rdstation.com/
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
21
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
22
|
+
import {
|
|
23
|
+
CallToolRequestSchema,
|
|
24
|
+
ListToolsRequestSchema,
|
|
25
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
26
|
+
|
|
27
|
+
const TOKEN = process.env.RD_STATION_TOKEN || "";
|
|
28
|
+
const BASE_URL = "https://api.rd.services";
|
|
29
|
+
|
|
30
|
+
async function rdStationRequest(method: string, path: string, body?: unknown): Promise<unknown> {
|
|
31
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
32
|
+
method,
|
|
33
|
+
headers: {
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
"Authorization": `Bearer ${TOKEN}`,
|
|
36
|
+
},
|
|
37
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
38
|
+
});
|
|
39
|
+
if (!res.ok) {
|
|
40
|
+
const err = await res.text();
|
|
41
|
+
throw new Error(`RD Station API ${res.status}: ${err}`);
|
|
42
|
+
}
|
|
43
|
+
return res.json();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const server = new Server(
|
|
47
|
+
{ name: "mcp-rd-station", version: "0.1.0" },
|
|
48
|
+
{ capabilities: { tools: {} } }
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
52
|
+
tools: [
|
|
53
|
+
{
|
|
54
|
+
name: "create_contact",
|
|
55
|
+
description: "Create a contact in RD Station CRM",
|
|
56
|
+
inputSchema: {
|
|
57
|
+
type: "object",
|
|
58
|
+
properties: {
|
|
59
|
+
email: { type: "string", description: "Contact email" },
|
|
60
|
+
name: { type: "string", description: "Contact name" },
|
|
61
|
+
job_title: { type: "string", description: "Job title" },
|
|
62
|
+
phone: { type: "string", description: "Phone number" },
|
|
63
|
+
company: { type: "string", description: "Company name" },
|
|
64
|
+
tags: {
|
|
65
|
+
type: "array",
|
|
66
|
+
items: { type: "string" },
|
|
67
|
+
description: "Tags to assign",
|
|
68
|
+
},
|
|
69
|
+
cf_custom_fields: { type: "object", description: "Custom fields (key-value)" },
|
|
70
|
+
},
|
|
71
|
+
required: ["email"],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: "update_contact",
|
|
76
|
+
description: "Update a contact by UUID",
|
|
77
|
+
inputSchema: {
|
|
78
|
+
type: "object",
|
|
79
|
+
properties: {
|
|
80
|
+
uuid: { type: "string", description: "Contact UUID" },
|
|
81
|
+
name: { type: "string", description: "Updated name" },
|
|
82
|
+
email: { type: "string", description: "Updated email" },
|
|
83
|
+
job_title: { type: "string", description: "Updated job title" },
|
|
84
|
+
phone: { type: "string", description: "Updated phone" },
|
|
85
|
+
company: { type: "string", description: "Updated company" },
|
|
86
|
+
tags: { type: "array", items: { type: "string" }, description: "Updated tags" },
|
|
87
|
+
},
|
|
88
|
+
required: ["uuid"],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: "get_contact",
|
|
93
|
+
description: "Get contact details by UUID or email",
|
|
94
|
+
inputSchema: {
|
|
95
|
+
type: "object",
|
|
96
|
+
properties: {
|
|
97
|
+
uuid: { type: "string", description: "Contact UUID" },
|
|
98
|
+
email: { type: "string", description: "Contact email (alternative to UUID)" },
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "list_contacts",
|
|
104
|
+
description: "List contacts with pagination",
|
|
105
|
+
inputSchema: {
|
|
106
|
+
type: "object",
|
|
107
|
+
properties: {
|
|
108
|
+
page: { type: "number", description: "Page number (default 1)" },
|
|
109
|
+
limit: { type: "number", description: "Results per page (default 25)" },
|
|
110
|
+
query: { type: "string", description: "Search query" },
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: "create_event",
|
|
116
|
+
description: "Create a conversion event for a contact",
|
|
117
|
+
inputSchema: {
|
|
118
|
+
type: "object",
|
|
119
|
+
properties: {
|
|
120
|
+
event_type: { type: "string", enum: ["CONVERSION", "OPPORTUNITY", "SALE", "OPPORTUNITY_LOST"], description: "Event type" },
|
|
121
|
+
event_family: { type: "string", enum: ["CDP"], description: "Event family" },
|
|
122
|
+
payload: {
|
|
123
|
+
type: "object",
|
|
124
|
+
description: "Event payload",
|
|
125
|
+
properties: {
|
|
126
|
+
conversion_identifier: { type: "string", description: "Conversion identifier (e.g. form name)" },
|
|
127
|
+
email: { type: "string", description: "Contact email" },
|
|
128
|
+
name: { type: "string", description: "Contact name" },
|
|
129
|
+
cf_custom_fields: { type: "object", description: "Custom fields" },
|
|
130
|
+
},
|
|
131
|
+
required: ["conversion_identifier", "email"],
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
required: ["event_type", "event_family", "payload"],
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "list_funnels",
|
|
139
|
+
description: "List all sales funnels",
|
|
140
|
+
inputSchema: { type: "object", properties: {} },
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: "get_funnel",
|
|
144
|
+
description: "Get funnel details with stages",
|
|
145
|
+
inputSchema: {
|
|
146
|
+
type: "object",
|
|
147
|
+
properties: {
|
|
148
|
+
id: { type: "string", description: "Funnel ID" },
|
|
149
|
+
},
|
|
150
|
+
required: ["id"],
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: "create_opportunity",
|
|
155
|
+
description: "Create a sales opportunity in a funnel",
|
|
156
|
+
inputSchema: {
|
|
157
|
+
type: "object",
|
|
158
|
+
properties: {
|
|
159
|
+
deal_stage_id: { type: "string", description: "Stage ID in the funnel" },
|
|
160
|
+
name: { type: "string", description: "Opportunity name" },
|
|
161
|
+
contact_uuid: { type: "string", description: "Contact UUID" },
|
|
162
|
+
amount: { type: "number", description: "Deal amount in cents" },
|
|
163
|
+
prediction_date: { type: "string", description: "Expected close date (YYYY-MM-DD)" },
|
|
164
|
+
},
|
|
165
|
+
required: ["deal_stage_id", "name"],
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
}));
|
|
170
|
+
|
|
171
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
172
|
+
const { name, arguments: args } = request.params;
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
switch (name) {
|
|
176
|
+
case "create_contact":
|
|
177
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("POST", "/platform/contacts", args), null, 2) }] };
|
|
178
|
+
case "update_contact": {
|
|
179
|
+
const uuid = args?.uuid;
|
|
180
|
+
const body = { ...args } as Record<string, unknown>;
|
|
181
|
+
delete body.uuid;
|
|
182
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("PATCH", `/platform/contacts/${uuid}`, body), null, 2) }] };
|
|
183
|
+
}
|
|
184
|
+
case "get_contact": {
|
|
185
|
+
if (args?.uuid) {
|
|
186
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("GET", `/platform/contacts/${args.uuid}`), null, 2) }] };
|
|
187
|
+
}
|
|
188
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("GET", `/platform/contacts/email:${args?.email}`), null, 2) }] };
|
|
189
|
+
}
|
|
190
|
+
case "list_contacts": {
|
|
191
|
+
const params = new URLSearchParams();
|
|
192
|
+
if (args?.page) params.set("page", String(args.page));
|
|
193
|
+
if (args?.limit) params.set("limit", String(args.limit));
|
|
194
|
+
if (args?.query) params.set("query", String(args.query));
|
|
195
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("GET", `/platform/contacts?${params}`), null, 2) }] };
|
|
196
|
+
}
|
|
197
|
+
case "create_event":
|
|
198
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("POST", "/platform/events", args), null, 2) }] };
|
|
199
|
+
case "list_funnels":
|
|
200
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("GET", "/platform/deal_pipelines"), null, 2) }] };
|
|
201
|
+
case "get_funnel":
|
|
202
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("GET", `/platform/deal_pipelines/${args?.id}`), null, 2) }] };
|
|
203
|
+
case "create_opportunity":
|
|
204
|
+
return { content: [{ type: "text", text: JSON.stringify(await rdStationRequest("POST", "/platform/deals", args), null, 2) }] };
|
|
205
|
+
default:
|
|
206
|
+
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
207
|
+
}
|
|
208
|
+
} catch (err) {
|
|
209
|
+
return { content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
async function main() {
|
|
214
|
+
if (!TOKEN) {
|
|
215
|
+
console.error("RD_STATION_TOKEN environment variable is required");
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
const transport = new StdioServerTransport();
|
|
219
|
+
await server.connect(transport);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
main().catch(console.error);
|
package/tsconfig.json
ADDED