@opencx/mcp 1.15.15 → 1.15.16
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/companies.spec.d.ts +2 -0
- package/dist/companies.spec.d.ts.map +1 -0
- package/dist/companies.spec.js +191 -0
- package/dist/companies.spec.js.map +1 -0
- package/dist/schema.d.ts +436 -9
- package/dist/schema.d.ts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/companies.d.ts +4 -0
- package/dist/tools/companies.d.ts.map +1 -0
- package/dist/tools/companies.js +127 -0
- package/dist/tools/companies.js.map +1 -0
- package/dist/utils/session-channel.d.ts +2 -2
- package/dist/utils/session-channel.d.ts.map +1 -1
- package/dist/utils/session-channel.js +1 -0
- package/dist/utils/session-channel.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companies.spec.d.ts","sourceRoot":"","sources":["../src/companies.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
3
|
+
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
|
|
4
|
+
import { createServer } from './server.js';
|
|
5
|
+
function mockResponse(body, status = 200, statusText = 'OK') {
|
|
6
|
+
return new Response(JSON.stringify(body), { status, statusText });
|
|
7
|
+
}
|
|
8
|
+
function getRequestUrl(call) {
|
|
9
|
+
const arg = call[0];
|
|
10
|
+
if (arg instanceof Request)
|
|
11
|
+
return arg.url;
|
|
12
|
+
return String(arg);
|
|
13
|
+
}
|
|
14
|
+
function getRequestMethod(call) {
|
|
15
|
+
const arg = call[0];
|
|
16
|
+
if (arg instanceof Request)
|
|
17
|
+
return arg.method;
|
|
18
|
+
const opts = call[1];
|
|
19
|
+
return opts.method ?? 'GET';
|
|
20
|
+
}
|
|
21
|
+
async function getRequestBody(call) {
|
|
22
|
+
const arg = call[0];
|
|
23
|
+
if (arg instanceof Request) {
|
|
24
|
+
const text = await arg.clone().text();
|
|
25
|
+
return text ? JSON.parse(text) : undefined;
|
|
26
|
+
}
|
|
27
|
+
const opts = call[1];
|
|
28
|
+
return opts.body ? JSON.parse(opts.body) : undefined;
|
|
29
|
+
}
|
|
30
|
+
function contentJson(content) {
|
|
31
|
+
const parsed = content;
|
|
32
|
+
return JSON.parse(parsed[0].text);
|
|
33
|
+
}
|
|
34
|
+
const COMPANY = {
|
|
35
|
+
id: 'c1',
|
|
36
|
+
external_id: 'acct-1',
|
|
37
|
+
name: 'Acme Retail',
|
|
38
|
+
custom_data: { plan: 'growth' },
|
|
39
|
+
agent_owner: { id: 7, name: 'Dana', email: 'dana@open.cx' },
|
|
40
|
+
created_at: '2026-08-22T00:00:00.000Z',
|
|
41
|
+
updated_at: '2026-08-22T00:00:00.000Z',
|
|
42
|
+
};
|
|
43
|
+
describe('company tools', () => {
|
|
44
|
+
let client;
|
|
45
|
+
let cleanup;
|
|
46
|
+
let fetchSpy;
|
|
47
|
+
beforeEach(async () => {
|
|
48
|
+
fetchSpy = vi.fn();
|
|
49
|
+
vi.stubGlobal('fetch', fetchSpy);
|
|
50
|
+
const server = createServer('test-api-key', 'https://api.test.com');
|
|
51
|
+
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
52
|
+
await server.connect(serverTransport);
|
|
53
|
+
client = new Client({ name: 'test-client', version: '1.0.0' });
|
|
54
|
+
await client.connect(clientTransport);
|
|
55
|
+
cleanup = async () => {
|
|
56
|
+
await client.close();
|
|
57
|
+
await server.close();
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
afterEach(async () => {
|
|
61
|
+
await cleanup();
|
|
62
|
+
vi.restoreAllMocks();
|
|
63
|
+
});
|
|
64
|
+
it('registers all eight company tools', async () => {
|
|
65
|
+
const { tools } = await client.listTools();
|
|
66
|
+
const toolNames = tools.map((t) => t.name);
|
|
67
|
+
expect(toolNames).toContain('list_companies');
|
|
68
|
+
expect(toolNames).toContain('get_company');
|
|
69
|
+
expect(toolNames).toContain('upsert_company');
|
|
70
|
+
expect(toolNames).toContain('set_company_owner');
|
|
71
|
+
expect(toolNames).toContain('list_contact_companies');
|
|
72
|
+
expect(toolNames).toContain('link_contact_to_company');
|
|
73
|
+
expect(toolNames).toContain('link_contacts_to_companies');
|
|
74
|
+
expect(toolNames).toContain('unlink_contact_from_company');
|
|
75
|
+
});
|
|
76
|
+
it('list_companies GETs /companies and returns the owner', async () => {
|
|
77
|
+
fetchSpy.mockResolvedValueOnce(mockResponse({ data: [COMPANY], total: 1, page: 1, limit: 50 }));
|
|
78
|
+
const result = await client.callTool({ name: 'list_companies', arguments: {} });
|
|
79
|
+
const call = fetchSpy.mock.calls[0];
|
|
80
|
+
expect(getRequestUrl(call)).toBe('https://api.test.com/companies');
|
|
81
|
+
expect(getRequestMethod(call)).toBe('GET');
|
|
82
|
+
// The owner has to survive the wrapper — it is the whole point of the tool
|
|
83
|
+
// for an operator asking "who owns this account?".
|
|
84
|
+
const body = contentJson(result.content);
|
|
85
|
+
expect(body.data[0]?.agent_owner?.email).toBe('dana@open.cx');
|
|
86
|
+
});
|
|
87
|
+
it('get_company GETs the per-company route', async () => {
|
|
88
|
+
fetchSpy.mockResolvedValueOnce(mockResponse(COMPANY));
|
|
89
|
+
await client.callTool({ name: 'get_company', arguments: { company_id: 'c1' } });
|
|
90
|
+
const call = fetchSpy.mock.calls[0];
|
|
91
|
+
expect(getRequestUrl(call)).toBe('https://api.test.com/companies/c1');
|
|
92
|
+
expect(getRequestMethod(call)).toBe('GET');
|
|
93
|
+
});
|
|
94
|
+
it('upsert_company POSTs /companies with the external key', async () => {
|
|
95
|
+
fetchSpy.mockResolvedValueOnce(mockResponse(COMPANY, 201, 'Created'));
|
|
96
|
+
await client.callTool({
|
|
97
|
+
name: 'upsert_company',
|
|
98
|
+
arguments: { external_id: 'acct-1', name: 'Acme Retail', custom_data: { plan: 'growth' } },
|
|
99
|
+
});
|
|
100
|
+
const call = fetchSpy.mock.calls[0];
|
|
101
|
+
expect(getRequestUrl(call)).toBe('https://api.test.com/companies');
|
|
102
|
+
expect(getRequestMethod(call)).toBe('POST');
|
|
103
|
+
expect(await getRequestBody(call)).toEqual({
|
|
104
|
+
external_id: 'acct-1',
|
|
105
|
+
name: 'Acme Retail',
|
|
106
|
+
custom_data: { plan: 'growth' },
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
it('set_company_owner PUTs the owner route with the email', async () => {
|
|
110
|
+
fetchSpy.mockResolvedValueOnce(mockResponse(COMPANY));
|
|
111
|
+
await client.callTool({
|
|
112
|
+
name: 'set_company_owner',
|
|
113
|
+
arguments: { external_id: 'acct-1', owner: { email: 'dana@open.cx' } },
|
|
114
|
+
});
|
|
115
|
+
const call = fetchSpy.mock.calls[0];
|
|
116
|
+
expect(getRequestUrl(call)).toBe('https://api.test.com/companies/acct-1/owner');
|
|
117
|
+
expect(getRequestMethod(call)).toBe('PUT');
|
|
118
|
+
// external_id belongs in the path, never the body.
|
|
119
|
+
expect(await getRequestBody(call)).toEqual({ owner: { email: 'dana@open.cx' } });
|
|
120
|
+
});
|
|
121
|
+
it('set_company_owner passes an explicit null through to clear the owner', async () => {
|
|
122
|
+
fetchSpy.mockResolvedValueOnce(mockResponse({ ...COMPANY, agent_owner: null }));
|
|
123
|
+
await client.callTool({
|
|
124
|
+
name: 'set_company_owner',
|
|
125
|
+
arguments: { external_id: 'acct-1', owner: null },
|
|
126
|
+
});
|
|
127
|
+
const call = fetchSpy.mock.calls[0];
|
|
128
|
+
// A dropped null would read as "no owner given" and be rejected instead of
|
|
129
|
+
// clearing, so the null has to survive serialization.
|
|
130
|
+
expect(await getRequestBody(call)).toEqual({ owner: null });
|
|
131
|
+
});
|
|
132
|
+
it('upsert_company carries an owner through in one call', async () => {
|
|
133
|
+
fetchSpy.mockResolvedValueOnce(mockResponse(COMPANY, 201, 'Created'));
|
|
134
|
+
await client.callTool({
|
|
135
|
+
name: 'upsert_company',
|
|
136
|
+
arguments: {
|
|
137
|
+
external_id: 'acct-1',
|
|
138
|
+
name: 'Acme Retail',
|
|
139
|
+
owner: { email: 'dana@open.cx' },
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
const call = fetchSpy.mock.calls[0];
|
|
143
|
+
expect(await getRequestBody(call)).toEqual({
|
|
144
|
+
external_id: 'acct-1',
|
|
145
|
+
name: 'Acme Retail',
|
|
146
|
+
owner: { email: 'dana@open.cx' },
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
it('list_contact_companies GETs the contact route', async () => {
|
|
150
|
+
fetchSpy.mockResolvedValueOnce(mockResponse({ companies: [COMPANY] }));
|
|
151
|
+
await client.callTool({ name: 'list_contact_companies', arguments: { contact_id: 'ct1' } });
|
|
152
|
+
const call = fetchSpy.mock.calls[0];
|
|
153
|
+
expect(getRequestUrl(call)).toBe('https://api.test.com/contacts/ct1/companies');
|
|
154
|
+
expect(getRequestMethod(call)).toBe('GET');
|
|
155
|
+
});
|
|
156
|
+
it('link_contact_to_company POSTs the company key to the contact route', async () => {
|
|
157
|
+
fetchSpy.mockResolvedValueOnce(mockResponse({ outcome: 'linked', company: COMPANY }, 201, 'Created'));
|
|
158
|
+
await client.callTool({
|
|
159
|
+
name: 'link_contact_to_company',
|
|
160
|
+
arguments: { contact_id: 'ct1', external_id: 'acct-1' },
|
|
161
|
+
});
|
|
162
|
+
const call = fetchSpy.mock.calls[0];
|
|
163
|
+
expect(getRequestUrl(call)).toBe('https://api.test.com/contacts/ct1/companies');
|
|
164
|
+
expect(getRequestMethod(call)).toBe('POST');
|
|
165
|
+
expect(await getRequestBody(call)).toEqual({ external_id: 'acct-1' });
|
|
166
|
+
});
|
|
167
|
+
it('link_contacts_to_companies POSTs the batch to /companies/links', async () => {
|
|
168
|
+
fetchSpy.mockResolvedValueOnce(mockResponse({ results: [], summary: { total: 0, linked: 0, unchanged: 0, failed: 0 } }, 201, 'Created'));
|
|
169
|
+
await client.callTool({
|
|
170
|
+
name: 'link_contacts_to_companies',
|
|
171
|
+
arguments: { links: [{ contact_email: 'a@open.cx', external_id: 'acct-1' }] },
|
|
172
|
+
});
|
|
173
|
+
const call = fetchSpy.mock.calls[0];
|
|
174
|
+
expect(getRequestUrl(call)).toBe('https://api.test.com/companies/links');
|
|
175
|
+
expect(getRequestMethod(call)).toBe('POST');
|
|
176
|
+
expect(await getRequestBody(call)).toEqual({
|
|
177
|
+
links: [{ contact_email: 'a@open.cx', external_id: 'acct-1' }],
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
it('unlink_contact_from_company DELETEs one named company', async () => {
|
|
181
|
+
fetchSpy.mockResolvedValueOnce(mockResponse({ outcome: 'unlinked' }));
|
|
182
|
+
await client.callTool({
|
|
183
|
+
name: 'unlink_contact_from_company',
|
|
184
|
+
arguments: { contact_id: 'ct1', external_id: 'acct-1' },
|
|
185
|
+
});
|
|
186
|
+
const call = fetchSpy.mock.calls[0];
|
|
187
|
+
expect(getRequestUrl(call)).toBe('https://api.test.com/contacts/ct1/companies/acct-1');
|
|
188
|
+
expect(getRequestMethod(call)).toBe('DELETE');
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
//# sourceMappingURL=companies.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companies.spec.js","sourceRoot":"","sources":["../src/companies.spec.ts"],"names":[],"mappings":"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"}
|