@opencx/mcp 1.15.9 → 1.15.11

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=partner-analytics.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partner-analytics.spec.d.ts","sourceRoot":"","sources":["../src/partner-analytics.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,208 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { connectInMemory, fetchCallHeaders, fetchCallUrl, toolTextResultSchema, } from './spec-helpers.js';
3
+ // The three partner-wide tools: they wrap the partner-analytics public API 1:1
4
+ // (same key, same envelope as run_analytics_query), and — like their org
5
+ // sibling — surface API 4xx (a 403 for a non-partner-admin org, a 400 for bad
6
+ // SQL) as a normal `{ ok: false }` result the model can read and act on, never
7
+ // as a thrown tool error.
8
+ function mockResponse(body, status = 200) {
9
+ return new Response(JSON.stringify(body), {
10
+ status,
11
+ headers: { 'content-type': 'application/json' },
12
+ });
13
+ }
14
+ function requestMethod(call) {
15
+ const [input, init] = call;
16
+ if (input instanceof Request)
17
+ return input.method;
18
+ return init?.method ?? 'GET';
19
+ }
20
+ async function requestBody(call) {
21
+ const [input, init] = call;
22
+ if (input instanceof Request) {
23
+ const text = await input.clone().text();
24
+ return text ? JSON.parse(text) : undefined;
25
+ }
26
+ return typeof init?.body === 'string' ? JSON.parse(init.body) : undefined;
27
+ }
28
+ describe('partner analytics tools', () => {
29
+ let client;
30
+ let cleanup;
31
+ let fetchSpy;
32
+ beforeEach(async () => {
33
+ fetchSpy = vi.fn();
34
+ vi.stubGlobal('fetch', fetchSpy);
35
+ ({ client, cleanup } = await connectInMemory());
36
+ });
37
+ afterEach(async () => {
38
+ await cleanup();
39
+ vi.restoreAllMocks();
40
+ });
41
+ it('registers list_partner_orgs, search_partner_orgs and run_partner_analytics_query, all flagged partner-admin-only', async () => {
42
+ const { tools } = await client.listTools();
43
+ const byName = new Map(tools.map((t) => [t.name, t]));
44
+ for (const name of [
45
+ 'list_partner_orgs',
46
+ 'search_partner_orgs',
47
+ 'run_partner_analytics_query',
48
+ ]) {
49
+ const tool = byName.get(name);
50
+ expect(tool, name).toBeDefined();
51
+ expect(tool?.description, name).toMatch(/PARTNER ADMIN ORGS ONLY/);
52
+ }
53
+ // The roster tool points at the search tool for finding/ranking customers;
54
+ // the search tool documents the health statuses the model will be asked about.
55
+ expect(byName.get('list_partner_orgs')?.description).toContain('search_partner_orgs');
56
+ for (const status of ['new', 'setup_incomplete', 'inactive', 'healthy']) {
57
+ expect(byName.get('search_partner_orgs')?.description).toContain(status);
58
+ }
59
+ // The partner tool names its views and how to name orgs; the org tool is unchanged.
60
+ expect(byName.get('run_partner_analytics_query')?.description).toContain('report_partner_sessions');
61
+ expect(byName.get('run_partner_analytics_query')?.description).toContain('org_id');
62
+ expect(byName.get('run_analytics_query')?.description).not.toContain('report_partner_');
63
+ });
64
+ it('list_partner_orgs GETs /partner-analytics/orgs with the API key and returns the roster', async () => {
65
+ const roster = {
66
+ partner: { id: 'p1', name: 'FareHarbor' },
67
+ data: [{ id: 'o1', name: 'Alpha Boats', external_id: 'alpha', tags: ['rank-1'] }],
68
+ total: 1,
69
+ };
70
+ fetchSpy.mockResolvedValueOnce(mockResponse(roster));
71
+ const result = toolTextResultSchema.parse(await client.callTool({ name: 'list_partner_orgs', arguments: {} }));
72
+ const call = fetchSpy.mock.calls[0];
73
+ expect(fetchCallUrl(call)).toBe('https://api.test.com/partner-analytics/orgs');
74
+ expect(requestMethod(call)).toBe('GET');
75
+ expect(fetchCallHeaders(call).get('authorization')).toBe('Bearer test-api-key');
76
+ expect(result.isError).toBeFalsy();
77
+ expect(JSON.parse(result.content[0].text)).toEqual(roster);
78
+ });
79
+ it('search_partner_orgs GETs /partner-analytics/orgs/search with every filter as a query param', async () => {
80
+ const page = {
81
+ partner: { id: 'p1', name: 'FareHarbor' },
82
+ data: [
83
+ {
84
+ id: 'o1',
85
+ name: 'Alpha Boats',
86
+ external_id: 'alpha',
87
+ tags: ['rank-1'],
88
+ health: { status: 'inactive', sessions_30d: 0, total_sessions: 12 },
89
+ channels: { chat: true, email: false, whatsapp: false, voice: false },
90
+ },
91
+ ],
92
+ total: 1,
93
+ limit: 25,
94
+ offset: 50,
95
+ };
96
+ fetchSpy.mockResolvedValueOnce(mockResponse(page));
97
+ const result = toolTextResultSchema.parse(await client.callTool({
98
+ name: 'search_partner_orgs',
99
+ arguments: {
100
+ q: 'alpha',
101
+ status: 'inactive,new',
102
+ has_ai: 'true',
103
+ has_actions: 'false',
104
+ tags: 'rank-1,rank-2',
105
+ channels: 'chat',
106
+ sort_by: 'sessions_30d',
107
+ sort_dir: 'desc',
108
+ limit: 25,
109
+ offset: 50,
110
+ },
111
+ }));
112
+ const call = fetchSpy.mock.calls[0];
113
+ const url = new URL(fetchCallUrl(call));
114
+ expect(url.origin + url.pathname).toBe('https://api.test.com/partner-analytics/orgs/search');
115
+ expect(Object.fromEntries(url.searchParams)).toEqual({
116
+ q: 'alpha',
117
+ status: 'inactive,new',
118
+ has_ai: 'true',
119
+ has_actions: 'false',
120
+ tags: 'rank-1,rank-2',
121
+ channels: 'chat',
122
+ sort_by: 'sessions_30d',
123
+ sort_dir: 'desc',
124
+ limit: '25',
125
+ offset: '50',
126
+ });
127
+ expect(requestMethod(call)).toBe('GET');
128
+ expect(fetchCallHeaders(call).get('authorization')).toBe('Bearer test-api-key');
129
+ expect(result.isError).toBeFalsy();
130
+ expect(JSON.parse(result.content[0].text)).toEqual(page);
131
+ });
132
+ it('search_partner_orgs with no arguments sends no query params (server defaults apply)', async () => {
133
+ fetchSpy.mockResolvedValueOnce(mockResponse({ partner: { id: 'p1', name: 'P' }, data: [], total: 0, limit: 50, offset: 0 }));
134
+ await client.callTool({ name: 'search_partner_orgs', arguments: {} });
135
+ const call = fetchSpy.mock.calls[0];
136
+ expect(fetchCallUrl(call)).toBe('https://api.test.com/partner-analytics/orgs/search');
137
+ });
138
+ it('search_partner_orgs surfaces a 403 (not a partner admin org) as { ok: false }', async () => {
139
+ fetchSpy.mockResolvedValueOnce(mockResponse({ message: 'This organization does not administer a partner.' }, 403));
140
+ const result = toolTextResultSchema.parse(await client.callTool({ name: 'search_partner_orgs', arguments: { q: 'x' } }));
141
+ expect(result.isError).toBeFalsy();
142
+ expect(JSON.parse(result.content[0].text)).toMatchObject({ ok: false, status: 403 });
143
+ });
144
+ it('run_partner_analytics_query POSTs sql + parameters to /partner-analytics/query', async () => {
145
+ fetchSpy.mockResolvedValueOnce(mockResponse({ rows: [{ org_id: 'o1', n: '3' }], row_count: 1, truncated: false }));
146
+ const result = toolTextResultSchema.parse(await client.callTool({
147
+ name: 'run_partner_analytics_query',
148
+ arguments: {
149
+ sql: 'SELECT org_id, count() AS n FROM report_partner_sessions WHERE channel = ? GROUP BY org_id',
150
+ parameters: ['web'],
151
+ },
152
+ }));
153
+ const call = fetchSpy.mock.calls[0];
154
+ expect(fetchCallUrl(call)).toBe('https://api.test.com/partner-analytics/query');
155
+ expect(requestMethod(call)).toBe('POST');
156
+ expect(await requestBody(call)).toEqual({
157
+ sql: 'SELECT org_id, count() AS n FROM report_partner_sessions WHERE channel = ? GROUP BY org_id',
158
+ parameters: ['web'],
159
+ });
160
+ expect(result.isError).toBeFalsy();
161
+ expect(JSON.parse(result.content[0].text)).toEqual({
162
+ rows: [{ org_id: 'o1', n: '3' }],
163
+ row_count: 1,
164
+ truncated: false,
165
+ });
166
+ });
167
+ it('defaults parameters to [] when omitted', async () => {
168
+ fetchSpy.mockResolvedValueOnce(mockResponse({ rows: [], row_count: 0, truncated: false }));
169
+ await client.callTool({
170
+ name: 'run_partner_analytics_query',
171
+ arguments: { sql: 'SELECT count() FROM report_partner_sessions' },
172
+ });
173
+ expect(await requestBody(fetchSpy.mock.calls[0])).toEqual({
174
+ sql: 'SELECT count() FROM report_partner_sessions',
175
+ parameters: [],
176
+ });
177
+ });
178
+ it('surfaces a 403 (not a partner admin org) as a readable { ok: false } result, not a tool error', async () => {
179
+ const forbidden = {
180
+ statusCode: 403,
181
+ message: 'Partner analytics are only available to partner admin organizations.',
182
+ };
183
+ fetchSpy.mockResolvedValueOnce(mockResponse(forbidden, 403));
184
+ const result = toolTextResultSchema.parse(await client.callTool({ name: 'list_partner_orgs', arguments: {} }));
185
+ expect(result.isError).toBeFalsy();
186
+ // `error` is the raw response body (same shape run_analytics_query returns).
187
+ expect(JSON.parse(result.content[0].text)).toEqual({
188
+ ok: false,
189
+ status: 403,
190
+ error: JSON.stringify(forbidden),
191
+ });
192
+ });
193
+ it('surfaces a 400 (bad SQL) as { ok: false } so the model can correct and retry', async () => {
194
+ const bad = { statusCode: 400, message: 'Query failed (47): Unknown expression identifier' };
195
+ fetchSpy.mockResolvedValueOnce(mockResponse(bad, 400));
196
+ const result = toolTextResultSchema.parse(await client.callTool({
197
+ name: 'run_partner_analytics_query',
198
+ arguments: { sql: 'SELECT nope FROM report_partner_sessions' },
199
+ }));
200
+ expect(result.isError).toBeFalsy();
201
+ expect(JSON.parse(result.content[0].text)).toEqual({
202
+ ok: false,
203
+ status: 400,
204
+ error: JSON.stringify(bad),
205
+ });
206
+ });
207
+ });
208
+ //# sourceMappingURL=partner-analytics.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partner-analytics.spec.js","sourceRoot":"","sources":["../src/partner-analytics.spec.ts"],"names":[],"mappings":"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"}
package/dist/schema.d.ts CHANGED
@@ -4048,6 +4048,66 @@ export interface paths {
4048
4048
  patch?: never;
4049
4049
  trace?: never;
4050
4050
  };
4051
+ "/partner-analytics/orgs": {
4052
+ parameters: {
4053
+ query?: never;
4054
+ header?: never;
4055
+ path?: never;
4056
+ cookie?: never;
4057
+ };
4058
+ /**
4059
+ * List the connected orgs of the calling partner admin org
4060
+ * @description The partner's connected organizations — the scope of every `runPartnerAnalyticsQuery` and the org dimension (id → name) to join `report_partner_*` rows to. Only available to partner admin organizations (403 otherwise).
4061
+ */
4062
+ get: operations["listPartnerOrgs"];
4063
+ put?: never;
4064
+ post?: never;
4065
+ delete?: never;
4066
+ options?: never;
4067
+ head?: never;
4068
+ patch?: never;
4069
+ trace?: never;
4070
+ };
4071
+ "/partner-analytics/orgs/search": {
4072
+ parameters: {
4073
+ query?: never;
4074
+ header?: never;
4075
+ path?: never;
4076
+ cookie?: never;
4077
+ };
4078
+ /**
4079
+ * Search connected orgs with health signals (paginated)
4080
+ * @description Find, filter, sort and page through the calling partner's connected orgs (its customers), each with the health signals the Partner Admin console shows: `health.status` — `new` (connected < 7 days, no sessions yet), `setup_incomplete` (no knowledge sources and no actions), `inactive` (no session in the last 30 days), `healthy` (everything else) — plus `members`, `data_sources`, `has_ai_training`, `has_actions`, `sessions_30d`, `total_sessions`, `last_session_at`, and per-channel connected flags (`chat`, `email`, `whatsapp`, `voice`). `q` matches name or external_id; `status`, `tags` and `channels` are comma-separated (tags match ANY, channels match ALL); `has_ai` / `has_actions` are 'true' / 'false'. Max 100 rows per page (`limit`/`offset`); `total` is the filtered count. For volume, quality and behaviour beyond these signals use `runPartnerAnalyticsQuery`; for the full id → name roster use `listPartnerOrgs`. Only available to partner admin organizations (403 otherwise).
4081
+ */
4082
+ get: operations["searchPartnerOrgs"];
4083
+ put?: never;
4084
+ post?: never;
4085
+ delete?: never;
4086
+ options?: never;
4087
+ head?: never;
4088
+ patch?: never;
4089
+ trace?: never;
4090
+ };
4091
+ "/partner-analytics/query": {
4092
+ parameters: {
4093
+ query?: never;
4094
+ header?: never;
4095
+ path?: never;
4096
+ cookie?: never;
4097
+ };
4098
+ get?: never;
4099
+ put?: never;
4100
+ /**
4101
+ * Run a read-only analytics query across the partner’s connected orgs
4102
+ * @description Run a read-only SQL query against the partner-scoped `report_partner_*` analytics views (the same columns as the org `report_*` views, plus `org_id`), covering every org connected to the calling partner admin org. Read-only and scoped server-side; only available to partner admin organizations (403 otherwise).
4103
+ */
4104
+ post: operations["runPartnerAnalyticsQuery"];
4105
+ delete?: never;
4106
+ options?: never;
4107
+ head?: never;
4108
+ patch?: never;
4109
+ trace?: never;
4110
+ };
4051
4111
  "/salesforce/miaw/webhook": {
4052
4112
  parameters: {
4053
4113
  query?: never;
@@ -8719,6 +8779,57 @@ export interface components {
8719
8779
  row_count: number;
8720
8780
  truncated: boolean;
8721
8781
  };
8782
+ PartnerOrgDto: {
8783
+ id: string;
8784
+ name: string;
8785
+ external_id: string | null;
8786
+ tags: string[];
8787
+ created_at: string | null;
8788
+ };
8789
+ ListPartnerOrgsResponseDto: {
8790
+ partner: {
8791
+ id: string;
8792
+ name: string;
8793
+ };
8794
+ data: components["schemas"]["PartnerOrgDto"][];
8795
+ total: number;
8796
+ };
8797
+ PartnerOrgHealthDto: {
8798
+ id: string;
8799
+ name: string;
8800
+ external_id: string | null;
8801
+ website: string | null;
8802
+ logo_url: string | null;
8803
+ created_at: string | null;
8804
+ tags: string[];
8805
+ health: {
8806
+ /** @enum {string} */
8807
+ status: "healthy" | "setup_incomplete" | "inactive" | "new";
8808
+ members: number;
8809
+ data_sources: number;
8810
+ has_ai_training: boolean;
8811
+ has_actions: boolean;
8812
+ sessions_30d: number;
8813
+ total_sessions: number;
8814
+ last_session_at: string | null;
8815
+ };
8816
+ channels: {
8817
+ chat: boolean;
8818
+ email: boolean;
8819
+ whatsapp: boolean;
8820
+ voice: boolean;
8821
+ };
8822
+ };
8823
+ SearchPartnerOrgsResponseDto: {
8824
+ partner: {
8825
+ id: string;
8826
+ name: string;
8827
+ };
8828
+ data: components["schemas"]["PartnerOrgHealthDto"][];
8829
+ total: number;
8830
+ limit: number;
8831
+ offset: number;
8832
+ };
8722
8833
  OfficeHoursPublicResponseDto: {
8723
8834
  /** @description Office hours schedule ID */
8724
8835
  id: string;
@@ -17386,6 +17497,108 @@ export interface operations {
17386
17497
  };
17387
17498
  };
17388
17499
  };
17500
+ listPartnerOrgs: {
17501
+ parameters: {
17502
+ query?: never;
17503
+ header?: never;
17504
+ path?: never;
17505
+ cookie?: never;
17506
+ };
17507
+ requestBody?: never;
17508
+ responses: {
17509
+ /** @description Default Response */
17510
+ 200: {
17511
+ headers: {
17512
+ [name: string]: unknown;
17513
+ };
17514
+ content: {
17515
+ "application/json": components["schemas"]["ListPartnerOrgsResponseDto"];
17516
+ };
17517
+ };
17518
+ /** @description Internal Server Error */
17519
+ 500: {
17520
+ headers: {
17521
+ [name: string]: unknown;
17522
+ };
17523
+ content: {
17524
+ "application/json": components["schemas"]["ErrorDto"];
17525
+ };
17526
+ };
17527
+ };
17528
+ };
17529
+ searchPartnerOrgs: {
17530
+ parameters: {
17531
+ query?: {
17532
+ limit?: number;
17533
+ offset?: number;
17534
+ q?: string;
17535
+ status?: string;
17536
+ has_ai?: "true" | "false";
17537
+ has_actions?: "true" | "false";
17538
+ tags?: string;
17539
+ channels?: string;
17540
+ sort_by?: "created_at" | "name" | "members" | "data_sources" | "sessions_30d" | "total_sessions" | "last_session_at";
17541
+ sort_dir?: "asc" | "desc";
17542
+ };
17543
+ header?: never;
17544
+ path?: never;
17545
+ cookie?: never;
17546
+ };
17547
+ requestBody?: never;
17548
+ responses: {
17549
+ /** @description Default Response */
17550
+ 200: {
17551
+ headers: {
17552
+ [name: string]: unknown;
17553
+ };
17554
+ content: {
17555
+ "application/json": components["schemas"]["SearchPartnerOrgsResponseDto"];
17556
+ };
17557
+ };
17558
+ /** @description Internal Server Error */
17559
+ 500: {
17560
+ headers: {
17561
+ [name: string]: unknown;
17562
+ };
17563
+ content: {
17564
+ "application/json": components["schemas"]["ErrorDto"];
17565
+ };
17566
+ };
17567
+ };
17568
+ };
17569
+ runPartnerAnalyticsQuery: {
17570
+ parameters: {
17571
+ query?: never;
17572
+ header?: never;
17573
+ path?: never;
17574
+ cookie?: never;
17575
+ };
17576
+ requestBody: {
17577
+ content: {
17578
+ "application/json": components["schemas"]["RunReportQueryBody"];
17579
+ };
17580
+ };
17581
+ responses: {
17582
+ /** @description Default Response */
17583
+ 201: {
17584
+ headers: {
17585
+ [name: string]: unknown;
17586
+ };
17587
+ content: {
17588
+ "application/json": components["schemas"]["RunReportQueryResponseDto"];
17589
+ };
17590
+ };
17591
+ /** @description Internal Server Error */
17592
+ 500: {
17593
+ headers: {
17594
+ [name: string]: unknown;
17595
+ };
17596
+ content: {
17597
+ "application/json": components["schemas"]["ErrorDto"];
17598
+ };
17599
+ };
17600
+ };
17601
+ };
17389
17602
  getSalesforceCrmConnectionStatus: {
17390
17603
  parameters: {
17391
17604
  query?: never;