@countfinancial/cli 0.1.0 → 0.1.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.
Files changed (36) hide show
  1. package/README.md +5 -28
  2. package/dist/partner-mcp/config.d.ts +6 -0
  3. package/dist/partner-mcp/config.js +23 -0
  4. package/dist/partner-mcp/config.js.map +1 -0
  5. package/dist/partner-mcp/index.d.ts +2 -0
  6. package/dist/partner-mcp/index.js +17 -0
  7. package/dist/partner-mcp/index.js.map +1 -0
  8. package/dist/partner-mcp/partnerApiClient.d.ts +34 -0
  9. package/dist/partner-mcp/partnerApiClient.js +225 -0
  10. package/dist/partner-mcp/partnerApiClient.js.map +1 -0
  11. package/dist/partner-mcp/resources/registerResources.d.ts +8 -0
  12. package/dist/partner-mcp/resources/registerResources.js +70 -0
  13. package/dist/partner-mcp/resources/registerResources.js.map +1 -0
  14. package/dist/partner-mcp/server.d.ts +7 -0
  15. package/dist/partner-mcp/server.js +16 -0
  16. package/dist/partner-mcp/server.js.map +1 -0
  17. package/dist/partner-mcp/signing.d.ts +22 -0
  18. package/dist/partner-mcp/signing.js +20 -0
  19. package/dist/partner-mcp/signing.js.map +1 -0
  20. package/dist/partner-mcp/tools/definitions.d.ts +7 -0
  21. package/dist/partner-mcp/tools/definitions.js +1158 -0
  22. package/dist/partner-mcp/tools/definitions.js.map +1 -0
  23. package/dist/partner-mcp/tools/registerTools.d.ts +8 -0
  24. package/dist/partner-mcp/tools/registerTools.js +173 -0
  25. package/dist/partner-mcp/tools/registerTools.js.map +1 -0
  26. package/dist/partner-mcp/tools/schemas.d.ts +32 -0
  27. package/dist/partner-mcp/tools/schemas.js +47 -0
  28. package/dist/partner-mcp/tools/schemas.js.map +1 -0
  29. package/dist/partner-mcp/types.d.ts +47 -0
  30. package/dist/partner-mcp/types.js +2 -0
  31. package/dist/partner-mcp/types.js.map +1 -0
  32. package/dist/services/mcpLauncher.service.js +4 -4
  33. package/dist/services/mcpLauncher.service.js.map +1 -1
  34. package/dist/services/oauthLogin.service.js +1 -1
  35. package/dist/services/oauthLogin.service.js.map +1 -1
  36. package/package.json +4 -3
package/README.md CHANGED
@@ -1,36 +1,13 @@
1
- # COUNT CLI (`@count/cli`)
1
+ # COUNT CLI (`@countfinancial/cli`)
2
2
 
3
3
  Command-line tool for partner integrations that need **low-friction OAuth login** and a **local MCP server** for Claude Code, Cursor, and other agent runtimes.
4
4
 
5
- ## Install
6
-
7
- When `@count/partner-mcp` is published to npm:
8
-
9
- ```bash
10
- npm install
11
- npm run build
12
- npm link
13
- ```
5
+ The MCP server is bundled inside this package — no separate npm install required.
14
6
 
15
- Until then, link `@count/partner-mcp` from the [count-api](https://github.com/NotAllTalk/count-api) monorepo:
16
-
17
- ```bash
18
- cd /path/to/count-api
19
- npm install
20
- npm run mcp:count:build
21
- npm link --workspace @count/partner-mcp
22
-
23
- cd /path/to/count-cli
24
- npm link @count/partner-mcp
25
- npm install
26
- npm run build
27
- npm link
28
- ```
29
-
30
- When published to npm:
7
+ ## Install
31
8
 
32
9
  ```bash
33
- npm install -g @count/cli
10
+ npm install -g @countfinancial/cli
34
11
  ```
35
12
 
36
13
  ## Quick start
@@ -79,7 +56,7 @@ count mcp print-config
79
56
  | `count login` | Browser OAuth login + token storage |
80
57
  | `count logout` | Delete `~/.count/credentials.json` |
81
58
  | `count status` | Show whether credentials/tokens are present |
82
- | `count mcp` | Start the local `@count/partner-mcp` stdio server |
59
+ | `count mcp` | Start the local COUNT Partner MCP stdio server |
83
60
  | `count mcp print-config` | Emit MCP JSON for Claude Code / Cursor |
84
61
 
85
62
  ## Environment
@@ -0,0 +1,6 @@
1
+ import type { CountPartnerMcpConfig } from './types.js';
2
+ interface LoadConfigParams {
3
+ environment?: NodeJS.ProcessEnv;
4
+ }
5
+ export declare function loadConfig(params?: LoadConfigParams): CountPartnerMcpConfig;
6
+ export {};
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ const optionalNonEmptyString = z.preprocess((_value) => (_value === '' ? undefined : _value), z.string().trim().min(1).optional());
3
+ const environmentSchema = z.object({
4
+ COUNT_API_URL: z.string().trim().min(1).default('https://api.getcount.com'),
5
+ COUNT_CLIENT_ID: z.string().trim().min(1),
6
+ COUNT_CLIENT_SECRET: z.string().trim().min(1),
7
+ COUNT_ACCESS_TOKEN: optionalNonEmptyString,
8
+ COUNT_REFRESH_TOKEN: optionalNonEmptyString,
9
+ COUNT_REQUEST_TIMEOUT_MS: z.coerce.number().int().positive().default(30000),
10
+ });
11
+ export function loadConfig(params = {}) {
12
+ const { environment = process.env } = params;
13
+ const parsedEnvironment = environmentSchema.parse(environment);
14
+ return {
15
+ apiBaseUrl: parsedEnvironment.COUNT_API_URL.replace(/\/+$/, ''),
16
+ clientId: parsedEnvironment.COUNT_CLIENT_ID,
17
+ clientSecret: parsedEnvironment.COUNT_CLIENT_SECRET,
18
+ accessToken: parsedEnvironment.COUNT_ACCESS_TOKEN,
19
+ refreshToken: parsedEnvironment.COUNT_REFRESH_TOKEN,
20
+ requestTimeoutMs: parsedEnvironment.COUNT_REQUEST_TIMEOUT_MS,
21
+ };
22
+ }
23
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/partner-mcp/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,sBAAsB,GAAG,CAAC,CAAC,UAAU,CACzC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAChD,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CACpC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC;IAC3E,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C,kBAAkB,EAAE,sBAAsB;IAC1C,mBAAmB,EAAE,sBAAsB;IAC3C,wBAAwB,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CAC5E,CAAC,CAAC;AAMH,MAAM,UAAU,UAAU,CAAC,SAA2B,EAAE;IACtD,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;IAC7C,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAE/D,OAAO;QACL,UAAU,EAAE,iBAAiB,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC/D,QAAQ,EAAE,iBAAiB,CAAC,eAAe;QAC3C,YAAY,EAAE,iBAAiB,CAAC,mBAAmB;QACnD,WAAW,EAAE,iBAAiB,CAAC,kBAAkB;QACjD,YAAY,EAAE,iBAAiB,CAAC,mBAAmB;QACnD,gBAAgB,EAAE,iBAAiB,CAAC,wBAAwB;KAC7D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { loadConfig } from './config.js';
5
+ import { createServer } from './server.js';
6
+ async function main() {
7
+ const config = loadConfig();
8
+ const server = createServer({ config });
9
+ const transport = new StdioServerTransport();
10
+ await server.connect(transport);
11
+ }
12
+ main().catch((error) => {
13
+ const message = error instanceof Error ? error.message : String(error);
14
+ process.stderr.write(`COUNT partner MCP server failed to start: ${message}\n`);
15
+ process.exit(1);
16
+ });
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/partner-mcp/index.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,OAAO,IAAI,CAAC,CAAC;IAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { CountPartnerMcpConfig, RequestParams } from './types.js';
2
+ interface PartnerApiClientParams {
3
+ config: CountPartnerMcpConfig;
4
+ fetchImplementation?: typeof fetch;
5
+ currentTimeMs?: () => number;
6
+ }
7
+ export declare class PartnerApiError extends Error {
8
+ readonly statusCode: number;
9
+ readonly responseBody: unknown;
10
+ constructor(message: string, statusCode: number, responseBody: unknown);
11
+ }
12
+ export declare class PartnerApiClient {
13
+ private readonly config;
14
+ private readonly fetchImplementation;
15
+ private readonly currentTimeMs;
16
+ private accessToken?;
17
+ private refreshToken?;
18
+ constructor(params: PartnerApiClientParams);
19
+ getAuthState(): Record<string, boolean | string>;
20
+ request<TResponse = unknown>(params: RequestParams): Promise<TResponse>;
21
+ refreshAccessToken(): Promise<void>;
22
+ private performRequest;
23
+ private buildUrl;
24
+ private buildHeaders;
25
+ private buildRequestBody;
26
+ private parseResponseBody;
27
+ private getErrorMessage;
28
+ private shouldRefreshAfterError;
29
+ }
30
+ interface ToPartnerRouterPathParams {
31
+ path: string;
32
+ }
33
+ export declare function toPartnerRouterPath(params: ToPartnerRouterPathParams): string;
34
+ export {};
@@ -0,0 +1,225 @@
1
+ import { computePartnerSignature } from './signing.js';
2
+ export class PartnerApiError extends Error {
3
+ statusCode;
4
+ responseBody;
5
+ constructor(message, statusCode, responseBody) {
6
+ super(message);
7
+ this.name = 'PartnerApiError';
8
+ this.statusCode = statusCode;
9
+ this.responseBody = responseBody;
10
+ }
11
+ }
12
+ export class PartnerApiClient {
13
+ config;
14
+ fetchImplementation;
15
+ currentTimeMs;
16
+ accessToken;
17
+ refreshToken;
18
+ constructor(params) {
19
+ const { config, fetchImplementation = fetch, currentTimeMs = Date.now } = params;
20
+ this.config = config;
21
+ this.fetchImplementation = fetchImplementation;
22
+ this.currentTimeMs = currentTimeMs;
23
+ this.accessToken = config.accessToken;
24
+ this.refreshToken = config.refreshToken;
25
+ }
26
+ getAuthState() {
27
+ return {
28
+ apiBaseUrl: this.config.apiBaseUrl,
29
+ hasClientId: Boolean(this.config.clientId),
30
+ hasClientSecret: Boolean(this.config.clientSecret),
31
+ hasAccessToken: Boolean(this.accessToken),
32
+ hasRefreshToken: Boolean(this.refreshToken),
33
+ };
34
+ }
35
+ async request(params) {
36
+ const { method, path, signaturePath, query, body, requiresUserAuth = true, retryOnUnauthorized = true, } = params;
37
+ const response = await this.performRequest({
38
+ method,
39
+ path,
40
+ signaturePath,
41
+ query,
42
+ body,
43
+ requiresUserAuth,
44
+ });
45
+ if (!(response instanceof PartnerApiError)) {
46
+ return response;
47
+ }
48
+ if (requiresUserAuth &&
49
+ retryOnUnauthorized &&
50
+ this.refreshToken &&
51
+ this.shouldRefreshAfterError({ error: response })) {
52
+ await this.refreshAccessToken();
53
+ const retryResponse = await this.performRequest({
54
+ method,
55
+ path,
56
+ signaturePath,
57
+ query,
58
+ body,
59
+ requiresUserAuth,
60
+ });
61
+ if (!(retryResponse instanceof PartnerApiError)) {
62
+ return retryResponse;
63
+ }
64
+ throw retryResponse;
65
+ }
66
+ throw response;
67
+ }
68
+ async refreshAccessToken() {
69
+ if (!this.refreshToken) {
70
+ throw new PartnerApiError('No refresh token is configured for this MCP server.', 401, {
71
+ message: 'Missing COUNT_REFRESH_TOKEN',
72
+ });
73
+ }
74
+ const response = await this.request({
75
+ method: 'POST',
76
+ path: '/partners/refresh-user-access-token',
77
+ body: {
78
+ grantType: 'refresh_token',
79
+ refreshToken: this.refreshToken,
80
+ },
81
+ requiresUserAuth: false,
82
+ retryOnUnauthorized: false,
83
+ });
84
+ const tokenSet = response.data?.result;
85
+ if (!tokenSet?.accessToken || !tokenSet.refreshToken) {
86
+ throw new PartnerApiError('Refresh token response did not include a token set.', 502, response);
87
+ }
88
+ this.accessToken = tokenSet.accessToken;
89
+ this.refreshToken = tokenSet.refreshToken;
90
+ }
91
+ async performRequest(params) {
92
+ const { method, path, signaturePath, query, body, requiresUserAuth = true } = params;
93
+ const url = this.buildUrl({ path, query });
94
+ const abortController = new AbortController();
95
+ const timeout = setTimeout(() => abortController.abort(), this.config.requestTimeoutMs);
96
+ try {
97
+ const response = await this.fetchImplementation(url, {
98
+ method,
99
+ headers: this.buildHeaders({ method, path, signaturePath, body, requiresUserAuth }),
100
+ body: this.buildRequestBody({ method, body }),
101
+ signal: abortController.signal,
102
+ });
103
+ const responseBody = await this.parseResponseBody({ response });
104
+ if (!response.ok) {
105
+ return new PartnerApiError(this.getErrorMessage({ statusCode: response.status, responseBody }), response.status, responseBody);
106
+ }
107
+ return responseBody;
108
+ }
109
+ catch (error) {
110
+ if (error instanceof PartnerApiError) {
111
+ return error;
112
+ }
113
+ if (error instanceof Error && error.name === 'AbortError') {
114
+ return new PartnerApiError(`COUNT API request timed out after ${this.config.requestTimeoutMs}ms.`, 408, {
115
+ message: error.message,
116
+ });
117
+ }
118
+ const message = error instanceof Error ? error.message : String(error);
119
+ return new PartnerApiError(`COUNT API request failed: ${message}`, 502, { message });
120
+ }
121
+ finally {
122
+ clearTimeout(timeout);
123
+ }
124
+ }
125
+ buildUrl(params) {
126
+ const { path, query } = params;
127
+ const url = new URL(path, this.config.apiBaseUrl);
128
+ for (const [key, value] of Object.entries(query ?? {})) {
129
+ if (value === undefined || value === null) {
130
+ continue;
131
+ }
132
+ if (Array.isArray(value)) {
133
+ for (const item of value) {
134
+ url.searchParams.append(key, String(item));
135
+ }
136
+ continue;
137
+ }
138
+ url.searchParams.set(key, String(value));
139
+ }
140
+ return url.toString();
141
+ }
142
+ buildHeaders(params) {
143
+ const { method, path, signaturePath, body, requiresUserAuth } = params;
144
+ const timestamp = String(this.currentTimeMs());
145
+ const signature = computePartnerSignature({
146
+ method,
147
+ path: signaturePath ?? toPartnerRouterPath({ path }),
148
+ timestamp,
149
+ body,
150
+ clientSecret: this.config.clientSecret,
151
+ });
152
+ const headers = {
153
+ accept: 'application/json',
154
+ 'x-client-id': this.config.clientId,
155
+ 'x-timestamp': timestamp,
156
+ 'x-signature': signature,
157
+ };
158
+ if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
159
+ headers['content-type'] = 'application/json';
160
+ }
161
+ if (requiresUserAuth) {
162
+ if (!this.accessToken) {
163
+ throw new PartnerApiError('No access token is configured for this MCP server.', 401, {
164
+ message: 'Missing COUNT_ACCESS_TOKEN',
165
+ });
166
+ }
167
+ headers.authorization = `Bearer ${this.accessToken}`;
168
+ }
169
+ return headers;
170
+ }
171
+ buildRequestBody(params) {
172
+ const { method, body } = params;
173
+ if (method !== 'POST' && method !== 'PUT' && method !== 'PATCH') {
174
+ return undefined;
175
+ }
176
+ return JSON.stringify(body ?? {});
177
+ }
178
+ async parseResponseBody(params) {
179
+ const { response } = params;
180
+ const contentType = response.headers.get('content-type') ?? '';
181
+ const text = await response.text();
182
+ if (!text) {
183
+ return null;
184
+ }
185
+ if (contentType.includes('application/json')) {
186
+ try {
187
+ return JSON.parse(text);
188
+ }
189
+ catch {
190
+ return text;
191
+ }
192
+ }
193
+ return text;
194
+ }
195
+ getErrorMessage(params) {
196
+ const { statusCode, responseBody } = params;
197
+ if (responseBody && typeof responseBody === 'object') {
198
+ const errorBody = responseBody;
199
+ return errorBody.error_description ?? errorBody.message ?? `COUNT API returned ${statusCode}.`;
200
+ }
201
+ return `COUNT API returned ${statusCode}.`;
202
+ }
203
+ shouldRefreshAfterError(params) {
204
+ const { error } = params;
205
+ if (error.statusCode !== 401) {
206
+ return false;
207
+ }
208
+ if (!error.responseBody || typeof error.responseBody !== 'object') {
209
+ return true;
210
+ }
211
+ const errorBody = error.responseBody;
212
+ return errorBody.error === 'invalid_token' || errorBody.error_description === 'The access token expired';
213
+ }
214
+ }
215
+ export function toPartnerRouterPath(params) {
216
+ const { path } = params;
217
+ if (path === '/partners') {
218
+ return '/';
219
+ }
220
+ if (path.startsWith('/partners/')) {
221
+ return path.slice('/partners'.length);
222
+ }
223
+ return path;
224
+ }
225
+ //# sourceMappingURL=partnerApiClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partnerApiClient.js","sourceRoot":"","sources":["../../src/partner-mcp/partnerApiClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { PartnerApiClient } from '../partnerApiClient.js';
3
+ interface RegisterResourcesParams {
4
+ server: McpServer;
5
+ client: PartnerApiClient;
6
+ }
7
+ export declare function registerResources(params: RegisterResourcesParams): void;
8
+ export {};
@@ -0,0 +1,70 @@
1
+ const resources = [
2
+ {
3
+ name: 'COUNT_chart_of_accounts',
4
+ uri: 'count://chart-of-accounts',
5
+ title: 'COUNT Chart of Accounts',
6
+ description: 'Read-only snapshot of the authenticated workspace chart of accounts.',
7
+ path: '/partners/chart-of-accounts',
8
+ },
9
+ {
10
+ name: 'COUNT_customers',
11
+ uri: 'count://customers',
12
+ title: 'COUNT Customers',
13
+ description: 'Read-only snapshot of customers in the authenticated workspace.',
14
+ path: '/partners/customers',
15
+ },
16
+ {
17
+ name: 'COUNT_vendors',
18
+ uri: 'count://vendors',
19
+ title: 'COUNT Vendors',
20
+ description: 'Read-only snapshot of vendors in the authenticated workspace.',
21
+ path: '/partners/vendors',
22
+ },
23
+ {
24
+ name: 'COUNT_products',
25
+ uri: 'count://products',
26
+ title: 'COUNT Products',
27
+ description: 'Read-only snapshot of products and services in the authenticated workspace.',
28
+ path: '/partners/products',
29
+ },
30
+ {
31
+ name: 'COUNT_people',
32
+ uri: 'count://people',
33
+ title: 'COUNT People',
34
+ description: 'Read-only snapshot of people records in the authenticated workspace.',
35
+ path: '/partners/people',
36
+ },
37
+ {
38
+ name: 'COUNT_recurring_invoice_templates',
39
+ uri: 'count://recurring-invoice-templates',
40
+ title: 'COUNT Recurring Invoice Templates',
41
+ description: 'Read-only snapshot of recurring invoice templates in the authenticated workspace.',
42
+ path: '/partners/recurring-invoice-templates',
43
+ },
44
+ ];
45
+ export function registerResources(params) {
46
+ const { server, client } = params;
47
+ for (const resource of resources) {
48
+ server.registerResource(resource.name, resource.uri, {
49
+ title: resource.title,
50
+ description: resource.description,
51
+ mimeType: 'application/json',
52
+ }, async (uri) => {
53
+ const response = await client.request({
54
+ method: 'GET',
55
+ path: resource.path,
56
+ requiresUserAuth: true,
57
+ });
58
+ return {
59
+ contents: [
60
+ {
61
+ uri: uri.href,
62
+ mimeType: 'application/json',
63
+ text: JSON.stringify(response, null, 2),
64
+ },
65
+ ],
66
+ };
67
+ });
68
+ }
69
+ }
70
+ //# sourceMappingURL=registerResources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerResources.js","sourceRoot":"","sources":["../../../src/partner-mcp/resources/registerResources.ts"],"names":[],"mappings":"AAgBA,MAAM,SAAS,GAAyB;IACtC;QACE,IAAI,EAAE,yBAAyB;QAC/B,GAAG,EAAE,2BAA2B;QAChC,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,sEAAsE;QACnF,IAAI,EAAE,6BAA6B;KACpC;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,GAAG,EAAE,mBAAmB;QACxB,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,iEAAiE;QAC9E,IAAI,EAAE,qBAAqB;KAC5B;IACD;QACE,IAAI,EAAE,eAAe;QACrB,GAAG,EAAE,iBAAiB;QACtB,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,+DAA+D;QAC5E,IAAI,EAAE,mBAAmB;KAC1B;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,GAAG,EAAE,kBAAkB;QACvB,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,6EAA6E;QAC1F,IAAI,EAAE,oBAAoB;KAC3B;IACD;QACE,IAAI,EAAE,cAAc;QACpB,GAAG,EAAE,gBAAgB;QACrB,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,sEAAsE;QACnF,IAAI,EAAE,kBAAkB;KACzB;IACD;QACE,IAAI,EAAE,mCAAmC;QACzC,GAAG,EAAE,qCAAqC;QAC1C,KAAK,EAAE,mCAAmC;QAC1C,WAAW,EAAE,mFAAmF;QAChG,IAAI,EAAE,uCAAuC;KAC9C;CACF,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,MAA+B;IAC/D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAElC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,gBAAgB,CACrB,QAAQ,CAAC,IAAI,EACb,QAAQ,CAAC,GAAG,EACZ;YACE,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,QAAQ,EAAE,kBAAkB;SAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;YACZ,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;gBACpC,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,gBAAgB,EAAE,IAAI;aACvB,CAAC,CAAC;YAEH,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG,EAAE,GAAG,CAAC,IAAI;wBACb,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;qBACxC;iBACF;aACF,CAAC;QACJ,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CountPartnerMcpConfig } from './types.js';
3
+ interface CreateServerParams {
4
+ config: CountPartnerMcpConfig;
5
+ }
6
+ export declare function createServer(params: CreateServerParams): McpServer;
7
+ export {};
@@ -0,0 +1,16 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { PartnerApiClient } from './partnerApiClient.js';
3
+ import { registerResources } from './resources/registerResources.js';
4
+ import { registerTools } from './tools/registerTools.js';
5
+ export function createServer(params) {
6
+ const { config } = params;
7
+ const server = new McpServer({
8
+ name: '@countfinancial/cli',
9
+ version: '0.1.1',
10
+ });
11
+ const client = new PartnerApiClient({ config });
12
+ registerTools({ server, client });
13
+ registerResources({ server, client });
14
+ return server;
15
+ }
16
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/partner-mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAOzD,MAAM,UAAU,YAAY,CAAC,MAA0B;IACrD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAEhD,aAAa,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAEtC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { HttpMethod, JsonObject } from './types.js';
2
+ interface ComputeBodyHashParams {
3
+ method: HttpMethod;
4
+ body?: JsonObject;
5
+ }
6
+ interface ComputeSignatureParams {
7
+ method: HttpMethod;
8
+ path: string;
9
+ timestamp: string;
10
+ body?: JsonObject;
11
+ clientSecret: string;
12
+ }
13
+ interface BuildSignatureBaseStringParams {
14
+ method: HttpMethod;
15
+ path: string;
16
+ timestamp: string;
17
+ bodyHash?: string;
18
+ }
19
+ export declare function computeBodyHash(params: ComputeBodyHashParams): string;
20
+ export declare function buildSignatureBaseString(params: BuildSignatureBaseStringParams): string;
21
+ export declare function computePartnerSignature(params: ComputeSignatureParams): string;
22
+ export {};
@@ -0,0 +1,20 @@
1
+ import crypto from 'node:crypto';
2
+ const METHODS_WITH_BODY_HASH = new Set(['POST', 'PUT', 'PATCH']);
3
+ export function computeBodyHash(params) {
4
+ const { method, body } = params;
5
+ if (!METHODS_WITH_BODY_HASH.has(method)) {
6
+ return '';
7
+ }
8
+ return crypto.createHash('sha256').update(JSON.stringify(body ?? {})).digest('hex');
9
+ }
10
+ export function buildSignatureBaseString(params) {
11
+ const { method, path, timestamp, bodyHash = '' } = params;
12
+ return `${method}:${path}:${timestamp}:${bodyHash}`;
13
+ }
14
+ export function computePartnerSignature(params) {
15
+ const { method, path, timestamp, body, clientSecret } = params;
16
+ const bodyHash = computeBodyHash({ method, body });
17
+ const baseString = buildSignatureBaseString({ method, path, timestamp, bodyHash });
18
+ return crypto.createHmac('sha256', clientSecret).update(baseString).digest('hex');
19
+ }
20
+ //# sourceMappingURL=signing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/partner-mcp/signing.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAa,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAsB7E,MAAM,UAAU,eAAe,CAAC,MAA6B;IAC3D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;IAEhC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAAsC;IAC7E,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC;IAC1D,OAAO,GAAG,MAAM,IAAI,IAAI,IAAI,SAAS,IAAI,QAAQ,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAA8B;IACpE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAC/D,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,wBAAwB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEnF,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACpF,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ToolDefinition } from '../types.js';
2
+ export declare const toolDefinitions: ToolDefinition[];
3
+ interface GetToolDefinitionParams {
4
+ toolName: string;
5
+ }
6
+ export declare function getToolDefinition(params: GetToolDefinitionParams): ToolDefinition | undefined;
7
+ export {};