@warmio/mcp 11.0.5 → 11.0.9
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/README.md +67 -6
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/dist/config-paths.d.ts.map +1 -1
- package/dist/config-paths.js +5 -5
- package/dist/config-paths.js.map +1 -1
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +140 -44
- package/dist/install.js.map +1 -1
- package/dist/load-env.d.ts +3 -0
- package/dist/load-env.d.ts.map +1 -1
- package/dist/load-env.js +23 -9
- package/dist/load-env.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +41 -22
- package/dist/server.js.map +1 -1
- package/dist/warm-api-client.d.ts +8 -9
- package/dist/warm-api-client.d.ts.map +1 -1
- package/dist/warm-api-client.js +68 -23
- package/dist/warm-api-client.js.map +1 -1
- package/package.json +7 -9
- package/.cursor-plugin/README.md +0 -152
- package/.cursor-plugin/plugin.json +0 -39
- package/assets/logo.svg +0 -14
- package/mcp.json +0 -11
- package/skills/warm/SKILL.md +0 -152
package/dist/server.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
/* oxlint-disable anti-slop/no-shape-in-symbol-names -- inputShape and ZodRawShape are canonical MCP/Zod contract terms. */
|
|
3
3
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
|
-
import { toJsonSchemaCompat } from '@modelcontextprotocol/sdk/server/zod-json-schema-compat.js';
|
|
5
4
|
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
|
|
6
5
|
import { z } from 'zod';
|
|
7
6
|
import { getTransactionsMcpInputSchema, normalizeGetTransactionsMcpInput, privateMcpToolDefinitions, privateMcpToolDescriptors, } from '@warmio/contracts/mcp';
|
|
@@ -10,7 +9,10 @@ import { createReadOnlyWarmApiClient, createWarmApiClient, WarmApiError, } from
|
|
|
10
9
|
export { createReadOnlyWarmApiClient, createWarmApiClient, getConfiguredApiKey, WarmApiError, } from './warm-api-client.js';
|
|
11
10
|
function packageVersion() {
|
|
12
11
|
try {
|
|
13
|
-
|
|
12
|
+
// oxfmt-ignore
|
|
13
|
+
return (
|
|
14
|
+
// oxlint-disable-next-line typescript/consistent-type-assertions -- [typescript/consistent-type-assertions] Pre-existing production TypeScript assertion surfaced by the corrected assertion-expression family classifier.
|
|
15
|
+
JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version || '0.0.0');
|
|
14
16
|
}
|
|
15
17
|
catch {
|
|
16
18
|
return '0.0.0';
|
|
@@ -20,7 +22,7 @@ export const WARM_SERVER_INFO = { name: 'warm', version: packageVersion() };
|
|
|
20
22
|
// oxlint-disable-next-line anti-slop/no-object-parameters -- MCP structured content requires a JSON object result.
|
|
21
23
|
function structuredResult(value, isError = false) {
|
|
22
24
|
return {
|
|
23
|
-
content: [{ type: 'text', text: JSON.stringify(value
|
|
25
|
+
content: [{ type: 'text', text: JSON.stringify(value) }],
|
|
24
26
|
...(isError ? { isError: true } : { structuredContent: value }),
|
|
25
27
|
};
|
|
26
28
|
}
|
|
@@ -49,6 +51,9 @@ function mcpOutputSchema(name) {
|
|
|
49
51
|
? outputSchema
|
|
50
52
|
: { ...outputSchema, type: 'object' };
|
|
51
53
|
}
|
|
54
|
+
function isMcpToolInputSchema(value) {
|
|
55
|
+
return 'type' in value && value.type === 'object';
|
|
56
|
+
}
|
|
52
57
|
function readToolDefinitions(client) {
|
|
53
58
|
return [
|
|
54
59
|
{
|
|
@@ -57,7 +62,7 @@ function readToolDefinitions(client) {
|
|
|
57
62
|
},
|
|
58
63
|
{
|
|
59
64
|
...descriptor('get_transactions'),
|
|
60
|
-
handler: async (args) => await client.getTransactions(normalizeGetTransactionsMcpInput(
|
|
65
|
+
handler: async (args) => await client.getTransactions(normalizeGetTransactionsMcpInput(args)),
|
|
61
66
|
},
|
|
62
67
|
];
|
|
63
68
|
}
|
|
@@ -65,47 +70,61 @@ function automationToolDefinitions(client) {
|
|
|
65
70
|
return [
|
|
66
71
|
{
|
|
67
72
|
...descriptor('search_operations'),
|
|
68
|
-
handler: async (args) => await client.searchOperations(z.string().optional().parse(args
|
|
73
|
+
handler: async (args) => await client.searchOperations(z.string().optional().parse(args['query'])),
|
|
69
74
|
},
|
|
70
75
|
{
|
|
71
76
|
...descriptor('describe_operation'),
|
|
72
|
-
handler: async (args) => await client.describeOperation(z.string().parse(args
|
|
77
|
+
handler: async (args) => await client.describeOperation(z.string().parse(args['operation_id']), automationInputSchema.optional().parse(args['input'])),
|
|
73
78
|
},
|
|
74
79
|
{
|
|
75
80
|
...descriptor('invoke_operation'),
|
|
76
|
-
handler: async (args) => await client.invokeOperation(z.string().parse(args
|
|
81
|
+
handler: async (args) => await client.invokeOperation(z.string().parse(args['operation_id']), automationInputSchema.optional().parse(args['input']), z.string().uuid().optional().parse(args['approval_id'])),
|
|
77
82
|
},
|
|
78
83
|
];
|
|
79
84
|
}
|
|
80
85
|
function registerTools(server, tools) {
|
|
81
86
|
server.server.registerCapabilities({ tools: { listChanged: true } });
|
|
82
87
|
server.server.setRequestHandler(ListToolsRequestSchema, () => ({
|
|
83
|
-
tools: tools.map((tool) =>
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
tools: tools.map((tool) => {
|
|
89
|
+
const inputSchema = canonicalToolDescriptor(tool.name).input_schema;
|
|
90
|
+
if (!isMcpToolInputSchema(inputSchema)) {
|
|
91
|
+
throw new Error(`Invalid MCP input schema for ${tool.name}.`);
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
annotations: tool.annotations,
|
|
95
|
+
description: tool.description,
|
|
96
|
+
inputSchema,
|
|
97
|
+
outputSchema: mcpOutputSchema(tool.name),
|
|
98
|
+
name: tool.name,
|
|
99
|
+
};
|
|
100
|
+
}),
|
|
93
101
|
}));
|
|
94
102
|
server.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
95
103
|
const tool = tools.find((candidate) => candidate.name === request.params.name);
|
|
96
104
|
if (!tool)
|
|
97
105
|
throw new McpError(ErrorCode.InvalidParams, `Tool ${request.params.name} not found`);
|
|
106
|
+
const invoke = async (name, handler) => {
|
|
107
|
+
try {
|
|
108
|
+
const result = await handler();
|
|
109
|
+
const invokeStatus = z.object({ status: z.number() }).safeParse(result);
|
|
110
|
+
return structuredResult(result, name === 'invoke_operation' && invokeStatus.success && invokeStatus.data.status >= 400);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
return toolFailure(error);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
if (tool.name === 'get_transactions') {
|
|
117
|
+
const parsed = await getTransactionsMcpInputSchema.safeParseAsync(request.params.arguments ?? {});
|
|
118
|
+
if (!parsed.success)
|
|
119
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${tool.name}: ${parsed.error.message}`);
|
|
120
|
+
return await invoke(tool.name, () => tool.handler(parsed.data));
|
|
121
|
+
}
|
|
98
122
|
const parsed = await z
|
|
99
123
|
.object(tool.inputShape)
|
|
100
124
|
.strict()
|
|
101
125
|
.safeParseAsync(request.params.arguments ?? {});
|
|
102
126
|
if (!parsed.success)
|
|
103
127
|
throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${tool.name}: ${parsed.error.message}`);
|
|
104
|
-
if (tool.name === 'get_transactions') {
|
|
105
|
-
const transactionInput = await getTransactionsMcpInputSchema.safeParseAsync(parsed.data);
|
|
106
|
-
if (!transactionInput.success)
|
|
107
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${tool.name}: ${transactionInput.error.message}`);
|
|
108
|
-
}
|
|
109
128
|
try {
|
|
110
129
|
const result = await tool.handler(parsed.data);
|
|
111
130
|
const invokeStatus = z.object({ status: z.number() }).safeParse(result);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,2HAA2H;AAC3H,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { normalizeGetTransactionsMcpInput } from '@warmio/contracts/mcp';
|
|
2
|
+
import type { AutomationInput, AutomationOperation, FinancialContext, FinancialContextMeta, FinancialContextTransactionsRequest, LatestTransactions, TransactionMonth } from '@warmio/contracts/types';
|
|
3
|
+
export type { AutomationInput, AutomationOperation, FinancialContext, FinancialContextMeta, FinancialContextTransactionsRequest, LatestTransactions, TransactionMonth, } from '@warmio/contracts/types';
|
|
4
|
+
export type FinancialContextMonth = Extract<FinancialContextTransactionsRequest, {
|
|
5
|
+
month: string;
|
|
6
|
+
}>['month'];
|
|
3
7
|
export interface WarmApiClientOptions {
|
|
4
8
|
apiKeyResolver?: () => string | null;
|
|
5
9
|
apiUrl?: string;
|
|
@@ -9,13 +13,7 @@ export interface WarmApiClientOptions {
|
|
|
9
13
|
export interface ReadOnlyWarmApiClientOptions extends Omit<WarmApiClientOptions, 'apiKeyResolver'> {
|
|
10
14
|
accessTokenResolver: () => string | null;
|
|
11
15
|
}
|
|
12
|
-
export type GetTransactionsInput =
|
|
13
|
-
month: string;
|
|
14
|
-
latest?: never;
|
|
15
|
-
} | {
|
|
16
|
-
latest: true;
|
|
17
|
-
month?: never;
|
|
18
|
-
};
|
|
16
|
+
export type GetTransactionsInput = ReturnType<typeof normalizeGetTransactionsMcpInput>;
|
|
19
17
|
export type GetTransactionsOutput = TransactionMonth | LatestTransactions;
|
|
20
18
|
export type AutomationOperationDescription = AutomationOperation & {
|
|
21
19
|
input_schema: Record<string, unknown>;
|
|
@@ -62,6 +60,7 @@ export declare class WarmApiError extends Error {
|
|
|
62
60
|
get headers(): Record<string, string>;
|
|
63
61
|
get status(): number;
|
|
64
62
|
}
|
|
63
|
+
export declare const BANK_LOGIN_CAPACITY_EXCEEDED_CODE = "bank_login_capacity_exceeded";
|
|
65
64
|
export declare function createWarmApiClient(options?: WarmApiClientOptions): WarmApiClient;
|
|
66
65
|
export declare function createReadOnlyWarmApiClient(options: ReadOnlyWarmApiClientOptions): ReadOnlyWarmApiClient;
|
|
67
66
|
//# sourceMappingURL=warm-api-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"warm-api-client.d.ts","sourceRoot":"","sources":["../src/warm-api-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"warm-api-client.d.ts","sourceRoot":"","sources":["../src/warm-api-client.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AAE9E,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,mCAAmC,EACnC,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AAGjC,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,mCAAmC,EACnC,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,qBAAqB,GAAG,OAAO,CACzC,mCAAmC,EACnC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAClB,CAAC,OAAO,CAAC,CAAC;AAEX,MAAM,WAAW,oBAAoB;IACnC,cAAc,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,OAAO,KAAK,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CAAC,oBAAoB,EAAE,gBAAgB,CAAC;IAChG,mBAAmB,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,gCAAgC,CAAC,CAAC;AACvF,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;AAC1E,MAAM,MAAM,8BAA8B,GAAG,mBAAmB,GAAG;IAEjE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC,CAAC;AACF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE;QACT,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,EAAE,8BAA8B,CAAC;CAC3C;AACD,MAAM,WAAW,qBAAqB;IAEpC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,qBAAqB;IACpC,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjD,uBAAuB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACzD,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC9E;AACD,MAAM,WAAW,aAAc,SAAQ,qBAAqB;IAC1D,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,mBAAmB,EAAE,CAAA;KAAE,CAAC,CAAC;IACjF,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAClG,eAAe,CACb,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,eAAe,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACnC;AACD,eAAO,MAAM,OAAO,wBAAa,CAAC;AAclC,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAKnD;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAED,UAAU,eAAe,CAAC,KAAK;IAC7B,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,YAAa,SAAQ,KAAK;IAGnC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC;IAF7C,YACE,OAAO,EAAE,MAAM,EACN,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,EAI5C;IAGD,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEpC;IACD,IAAI,MAAM,IAAI,MAAM,CAEnB;CACF;AA2DD,eAAO,MAAM,iCAAiC,iCAAiC,CAAC;AA8JhF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAErF;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,qBAAqB,CAEvB"}
|
package/dist/warm-api-client.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { API_ORIGIN, apiEndpointManifest } from '@warmio/contracts/api';
|
|
2
|
+
import { automationInvocationResponseSchema, automationOperationDescriptionResponseSchema, automationOperationSearchResponseSchema, financialContextMetaSchema, financialContextSchema, latestTransactionsSchema, transactionMonthSchema, } from '@warmio/contracts/schemas';
|
|
2
3
|
import { WARM_MCP_CREDENTIALS, WARM_MCP_INSTALLER_COMMAND } from '@warmio/contracts/mcp';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
import { getWarmApiKeyPath, readConfigFile } from './config-paths.js';
|
|
5
6
|
export const API_URL = API_ORIGIN;
|
|
6
|
-
const
|
|
7
|
-
|
|
7
|
+
const endpointByOperationId = new Map(apiEndpointManifest.map((endpoint) => [endpoint.operation_id, endpoint.path]));
|
|
8
|
+
function endpointFor(operationId) {
|
|
9
|
+
const endpoint = endpointByOperationId.get(operationId);
|
|
10
|
+
if (!endpoint)
|
|
11
|
+
throw new Error(`Unknown Warm API operation: ${operationId}`);
|
|
12
|
+
return endpoint;
|
|
13
|
+
}
|
|
14
|
+
const DEFAULT_TIMEOUT_MS = Number(process.env['WARM_API_TIMEOUT_MS'] || 10_000) || 10_000;
|
|
8
15
|
let cachedApiKey;
|
|
9
16
|
export function getConfiguredApiKey() {
|
|
10
17
|
if (cachedApiKey !== undefined)
|
|
@@ -47,22 +54,54 @@ function parseResponseBody(text) {
|
|
|
47
54
|
return text;
|
|
48
55
|
}
|
|
49
56
|
}
|
|
57
|
+
function parseDescribeOperationResponse(value) {
|
|
58
|
+
const parsed = automationOperationDescriptionResponseSchema.parse(value);
|
|
59
|
+
const output = { operation: parsed.operation };
|
|
60
|
+
if (parsed.approval) {
|
|
61
|
+
output.approval = parsed.approval;
|
|
62
|
+
}
|
|
63
|
+
return output;
|
|
64
|
+
}
|
|
65
|
+
function parseInvokeOperationResponse(value) {
|
|
66
|
+
const parsed = automationInvocationResponseSchema.parse(value);
|
|
67
|
+
return {
|
|
68
|
+
body: parsed.body,
|
|
69
|
+
headers: parsed.headers,
|
|
70
|
+
operation_id: parsed.operation_id,
|
|
71
|
+
status: parsed.status,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const describeOperationResponseParser = {
|
|
75
|
+
parse: parseDescribeOperationResponse,
|
|
76
|
+
};
|
|
77
|
+
const invokeOperationResponseParser = {
|
|
78
|
+
parse: parseInvokeOperationResponse,
|
|
79
|
+
};
|
|
80
|
+
export const BANK_LOGIN_CAPACITY_EXCEEDED_CODE = 'bank_login_capacity_exceeded';
|
|
81
|
+
const MESSAGE_BY_ERROR_CODE = {
|
|
82
|
+
[BANK_LOGIN_CAPACITY_EXCEEDED_CODE]: 'Your Warm product is locked because you have more bank logins than your plan includes. Remove a bank login or change your plan to restore access.',
|
|
83
|
+
};
|
|
50
84
|
function errorFromResponse(response) {
|
|
51
85
|
const knownMessages = new Map([
|
|
52
86
|
[401, 'Invalid API key. Regenerate it in Warm Settings.'],
|
|
53
87
|
[403, 'API access is available on paid plans only.'],
|
|
54
88
|
[429, 'Rate limit exceeded. Try again in a few minutes.'],
|
|
55
89
|
]);
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
90
|
+
const errorBody = z
|
|
91
|
+
.object({ code: z.string().optional(), error: z.string().optional() })
|
|
92
|
+
.safeParse(response.body).data;
|
|
93
|
+
const codeMessage = errorBody?.code ? MESSAGE_BY_ERROR_CODE[errorBody.code] : undefined;
|
|
94
|
+
return new WarmApiError(codeMessage ??
|
|
95
|
+
(errorBody?.code ? errorBody.error : undefined) ??
|
|
96
|
+
knownMessages.get(response.status) ??
|
|
97
|
+
errorBody?.error ??
|
|
59
98
|
`Request failed with status ${response.status}`, response);
|
|
60
99
|
}
|
|
61
100
|
function createRequest(authorizationResolver, options) {
|
|
62
101
|
const apiUrl = options.apiUrl || API_URL;
|
|
63
102
|
const fetchImplementation = options.fetchImplementation || fetch;
|
|
64
103
|
const requestTimeoutMs = options.requestTimeoutMs || DEFAULT_TIMEOUT_MS;
|
|
65
|
-
return async (input) => {
|
|
104
|
+
return async (input, responseSchema) => {
|
|
66
105
|
const token = authorizationResolver();
|
|
67
106
|
if (!token)
|
|
68
107
|
throw new Error(`No Warm API key configured. Run \"${WARM_MCP_INSTALLER_COMMAND}\" or set ${WARM_MCP_CREDENTIALS.apiKeyEnv}.`);
|
|
@@ -80,11 +119,16 @@ function createRequest(authorizationResolver, options) {
|
|
|
80
119
|
Accept: 'application/json',
|
|
81
120
|
Authorization: `Bearer ${token}`,
|
|
82
121
|
};
|
|
83
|
-
const requestInit = {
|
|
84
|
-
|
|
122
|
+
const requestInit = {
|
|
123
|
+
headers,
|
|
124
|
+
signal: requestSignal(requestTimeoutMs),
|
|
125
|
+
};
|
|
126
|
+
if (input.method) {
|
|
85
127
|
requestInit.method = input.method;
|
|
86
|
-
|
|
128
|
+
}
|
|
129
|
+
if (input.body) {
|
|
87
130
|
requestInit.body = JSON.stringify(input.body);
|
|
131
|
+
}
|
|
88
132
|
const response = await fetchImplementation(url, requestInit);
|
|
89
133
|
const text = await response.text();
|
|
90
134
|
const body = parseResponseBody(text);
|
|
@@ -95,23 +139,24 @@ function createRequest(authorizationResolver, options) {
|
|
|
95
139
|
};
|
|
96
140
|
if (!response.ok)
|
|
97
141
|
throw errorFromResponse(apiResponse);
|
|
98
|
-
return body;
|
|
142
|
+
return responseSchema.parse(body);
|
|
99
143
|
};
|
|
100
144
|
}
|
|
101
145
|
function createReadOnlyClient(request) {
|
|
102
146
|
return {
|
|
103
|
-
getFinancialContext: () => request({ endpoint:
|
|
104
|
-
getFinancialContextMeta: () => request({ endpoint:
|
|
147
|
+
getFinancialContext: () => request({ endpoint: endpointFor('getFinancialContext') }, financialContextSchema),
|
|
148
|
+
getFinancialContextMeta: () => request({ endpoint: endpointFor('getFinancialContextMeta') }, financialContextMetaSchema),
|
|
105
149
|
getTransactions: (input) => {
|
|
106
|
-
if ('month' in input)
|
|
150
|
+
if ('month' in input) {
|
|
107
151
|
return request({
|
|
108
|
-
endpoint:
|
|
152
|
+
endpoint: endpointFor('getFinancialContextTransactions'),
|
|
109
153
|
query: { month: input.month },
|
|
110
|
-
});
|
|
154
|
+
}, transactionMonthSchema);
|
|
155
|
+
}
|
|
111
156
|
return request({
|
|
112
|
-
endpoint:
|
|
157
|
+
endpoint: endpointFor('getFinancialContextTransactions'),
|
|
113
158
|
query: { latest: '1' },
|
|
114
|
-
});
|
|
159
|
+
}, latestTransactionsSchema);
|
|
115
160
|
},
|
|
116
161
|
};
|
|
117
162
|
}
|
|
@@ -120,29 +165,29 @@ function createClient(authorizationResolver, options) {
|
|
|
120
165
|
return {
|
|
121
166
|
...createReadOnlyClient(request),
|
|
122
167
|
searchOperations: (query) => request({
|
|
123
|
-
endpoint:
|
|
168
|
+
endpoint: endpointFor('searchOperations'),
|
|
124
169
|
method: 'POST',
|
|
125
170
|
body: query ? { query } : {},
|
|
126
|
-
}),
|
|
171
|
+
}, automationOperationSearchResponseSchema),
|
|
127
172
|
describeOperation: (operation_id, input) => {
|
|
128
173
|
const body = { operation_id };
|
|
129
174
|
if (input)
|
|
130
175
|
Object.assign(body, { input });
|
|
131
176
|
return request({
|
|
132
|
-
endpoint:
|
|
177
|
+
endpoint: endpointFor('describeOperation'),
|
|
133
178
|
method: 'POST',
|
|
134
179
|
body,
|
|
135
|
-
});
|
|
180
|
+
}, describeOperationResponseParser);
|
|
136
181
|
},
|
|
137
182
|
invokeOperation: (operation_id, input, approval_id) => {
|
|
138
183
|
const body = { operation_id, input: input ?? {} };
|
|
139
184
|
if (approval_id)
|
|
140
185
|
Object.assign(body, { approval_id });
|
|
141
186
|
return request({
|
|
142
|
-
endpoint:
|
|
187
|
+
endpoint: endpointFor('invokeOperation'),
|
|
143
188
|
method: 'POST',
|
|
144
189
|
body,
|
|
145
|
-
});
|
|
190
|
+
}, invokeOperationResponseParser);
|
|
146
191
|
},
|
|
147
192
|
};
|
|
148
193
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"warm-api-client.js","sourceRoot":"","sources":["../src/warm-api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"warm-api-client.js","sourceRoot":"","sources":["../src/warm-api-client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@warmio/mcp",
|
|
3
|
-
"version": "11.0.
|
|
3
|
+
"version": "11.0.9",
|
|
4
4
|
"description": "Warm local stdio MCP server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -33,14 +33,10 @@
|
|
|
33
33
|
"warmio": "dist/cli.js"
|
|
34
34
|
},
|
|
35
35
|
"files": [
|
|
36
|
-
"dist"
|
|
37
|
-
".cursor-plugin",
|
|
38
|
-
"assets",
|
|
39
|
-
"mcp.json",
|
|
40
|
-
"skills"
|
|
36
|
+
"dist"
|
|
41
37
|
],
|
|
42
38
|
"scripts": {
|
|
43
|
-
"build": "
|
|
39
|
+
"build": "tsgo -p tsconfig.json",
|
|
44
40
|
"test": "pnpm build && node --test test/*.mjs",
|
|
45
41
|
"pack:check": "pnpm pack --dry-run"
|
|
46
42
|
},
|
|
@@ -58,13 +54,15 @@
|
|
|
58
54
|
"directory": "libraries/mcp"
|
|
59
55
|
},
|
|
60
56
|
"dependencies": {
|
|
61
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
62
|
-
"@warmio/contracts": "3.0.
|
|
57
|
+
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
58
|
+
"@warmio/contracts": "3.0.4",
|
|
63
59
|
"dotenv": "^17.2.3",
|
|
60
|
+
"jsonc-parser": "^3.3.1",
|
|
64
61
|
"zod": "^3.25.76"
|
|
65
62
|
},
|
|
66
63
|
"devDependencies": {
|
|
67
64
|
"@types/node": "^24.10.9",
|
|
65
|
+
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
68
66
|
"typescript": "7.0.2"
|
|
69
67
|
}
|
|
70
68
|
}
|
package/.cursor-plugin/README.md
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
# Warm Cursor Plugin
|
|
2
|
-
|
|
3
|
-
Official Cursor Marketplace plugin for [Warm](https://warm.io) — personal finance automation via MCP.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
This plugin provides access to Warm's Model Context Protocol (MCP) server, enabling AI assistants to:
|
|
8
|
-
|
|
9
|
-
- **Read financial context** — balances, accounts, budgets, goals, liabilities, holdings
|
|
10
|
-
- **Retrieve transactions** — latest 10-day window or specific month
|
|
11
|
-
- **Search operations** — discover available automation operations
|
|
12
|
-
- **Invoke operations** — execute approved automations with write-operation safeguards
|
|
13
|
-
|
|
14
|
-
All write operations require explicit approval via a two-step describe → invoke flow.
|
|
15
|
-
|
|
16
|
-
## Installation
|
|
17
|
-
|
|
18
|
-
### From Cursor Marketplace (Recommended)
|
|
19
|
-
|
|
20
|
-
1. Open Cursor
|
|
21
|
-
2. Go to Settings → Cursor Plugins
|
|
22
|
-
3. Search for "Warm"
|
|
23
|
-
4. Click "Install"
|
|
24
|
-
5. Enter your Warm API key when prompted
|
|
25
|
-
|
|
26
|
-
Get your API key: [https://warm.io/settings/api-keys](https://warm.io/settings/api-keys)
|
|
27
|
-
|
|
28
|
-
### Local Testing (Development)
|
|
29
|
-
|
|
30
|
-
For local development and testing:
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
# Symlink the full plugin package root (not just .cursor-plugin/)
|
|
34
|
-
mkdir -p ~/.cursor/plugins/local
|
|
35
|
-
ln -s /path/to/warm-app/libraries/mcp ~/.cursor/plugins/local/warm
|
|
36
|
-
|
|
37
|
-
# Restart Cursor or run Developer: Reload Window
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Configuration
|
|
41
|
-
|
|
42
|
-
The plugin requires one environment variable:
|
|
43
|
-
|
|
44
|
-
- **`WARM_API_KEY`** (required, secret) — Your Warm API key from [https://warm.io/settings/api-keys](https://warm.io/settings/api-keys)
|
|
45
|
-
|
|
46
|
-
This is automatically configured when you install from the Cursor Marketplace.
|
|
47
|
-
|
|
48
|
-
## Available MCP Tools
|
|
49
|
-
|
|
50
|
-
### Read Tools
|
|
51
|
-
|
|
52
|
-
- `get_financial_context` — Compact overview of your financial status
|
|
53
|
-
- `get_transactions` — Transaction history (latest or by month)
|
|
54
|
-
|
|
55
|
-
### Automation Tools
|
|
56
|
-
|
|
57
|
-
- `search_operations` — Find available operations
|
|
58
|
-
- `describe_operation` — Get operation details and approval for writes
|
|
59
|
-
- `invoke_operation` — Execute approved operations
|
|
60
|
-
|
|
61
|
-
See [skills/warm/SKILL.md](../skills/warm/SKILL.md) for detailed usage examples and workflow guidance.
|
|
62
|
-
|
|
63
|
-
## Usage Examples
|
|
64
|
-
|
|
65
|
-
### Read Financial Data
|
|
66
|
-
|
|
67
|
-
```
|
|
68
|
-
Show me my current net worth and account balances
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
What were my transactions in January 2024?
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Automation
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
Search for operations related to budgets
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
Create a monthly budget for groceries with $500 limit
|
|
83
|
-
(The assistant will use describe_operation to get approval, then invoke_operation)
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Security & Approvals
|
|
87
|
-
|
|
88
|
-
- **Read operations** execute immediately without approval
|
|
89
|
-
- **Write operations** require a two-step approval flow:
|
|
90
|
-
1. `describe_operation` with exact input → returns `approval_id`
|
|
91
|
-
2. `invoke_operation` with same input + `approval_id` → executes
|
|
92
|
-
- Approvals expire and are single-use
|
|
93
|
-
- The AI cannot move money or modify data without explicit approval
|
|
94
|
-
|
|
95
|
-
## Documentation
|
|
96
|
-
|
|
97
|
-
- Plugin skill guide: [skills/warm/SKILL.md](../skills/warm/SKILL.md)
|
|
98
|
-
- Warm Developer Docs: [https://warm.io/developers](https://warm.io/developers)
|
|
99
|
-
- MCP package source: [libraries/mcp](../)
|
|
100
|
-
- Published npm package: [@warmio/mcp](https://www.npmjs.com/package/@warmio/mcp)
|
|
101
|
-
|
|
102
|
-
## Publishing to Cursor Marketplace
|
|
103
|
-
|
|
104
|
-
To publish this plugin to the Cursor Marketplace:
|
|
105
|
-
|
|
106
|
-
1. Ensure `plugin.json`, `mcp.json`, and `skills/warm/SKILL.md` are complete and correct
|
|
107
|
-
2. Test locally via `~/.cursor/plugins/local/warm` symlink to `libraries/mcp`
|
|
108
|
-
3. Submit at: [https://cursor.com/marketplace/publish](https://cursor.com/marketplace/publish)
|
|
109
|
-
4. Provide repository path: `jasonstockman/warm-app` (monorepo root with `.cursor-plugin/marketplace.json`)
|
|
110
|
-
|
|
111
|
-
The marketplace will read the plugin manifest and host it for one-click installation.
|
|
112
|
-
|
|
113
|
-
## Development
|
|
114
|
-
|
|
115
|
-
This plugin is maintained in the [warm-app](https://github.com/jasonstockman/warm-app) monorepo under `libraries/mcp/.cursor-plugin`.
|
|
116
|
-
|
|
117
|
-
The underlying MCP server is published as [@warmio/mcp](https://www.npmjs.com/package/@warmio/mcp) on npm.
|
|
118
|
-
|
|
119
|
-
### Local Package Testing
|
|
120
|
-
|
|
121
|
-
To test against a local build of `@warmio/mcp`:
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
# Build the MCP package
|
|
125
|
-
cd libraries/mcp
|
|
126
|
-
pnpm build
|
|
127
|
-
|
|
128
|
-
# Update mcp.json to use local path temporarily
|
|
129
|
-
{
|
|
130
|
-
"mcpServers": {
|
|
131
|
-
"warm": {
|
|
132
|
-
"command": "node",
|
|
133
|
-
"args": ["/absolute/path/to/libraries/mcp/dist/cli.js", "mcp"],
|
|
134
|
-
"env": {
|
|
135
|
-
"WARM_API_KEY": "${WARM_API_KEY}"
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
Remember to revert to `npx -y @warmio/mcp@latest mcp` before publishing.
|
|
143
|
-
|
|
144
|
-
## License
|
|
145
|
-
|
|
146
|
-
MIT License — see [LICENSE](../LICENSE) or repository root for details.
|
|
147
|
-
|
|
148
|
-
## Support
|
|
149
|
-
|
|
150
|
-
- Issues: [GitHub Issues](https://github.com/jasonstockman/warm-app/issues)
|
|
151
|
-
- Email: hello@warm.io
|
|
152
|
-
- Documentation: https://warm.io/developers
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "warm",
|
|
3
|
-
"displayName": "Warm",
|
|
4
|
-
"version": "1.0.0",
|
|
5
|
-
"description": "Personal finance automation MCP server. Read financial context, transactions, search operations, and invoke approved automations.",
|
|
6
|
-
"author": {
|
|
7
|
-
"name": "Warm",
|
|
8
|
-
"email": "hello@warm.io"
|
|
9
|
-
},
|
|
10
|
-
"homepage": "https://warm.io/developers",
|
|
11
|
-
"repository": "https://github.com/jasonstockman/warm-app",
|
|
12
|
-
"license": "MIT",
|
|
13
|
-
"logo": "assets/logo.svg",
|
|
14
|
-
"keywords": [
|
|
15
|
-
"warm",
|
|
16
|
-
"finance",
|
|
17
|
-
"automation",
|
|
18
|
-
"personal-finance",
|
|
19
|
-
"financial-data",
|
|
20
|
-
"budgets",
|
|
21
|
-
"transactions",
|
|
22
|
-
"mcp"
|
|
23
|
-
],
|
|
24
|
-
"category": "integrations",
|
|
25
|
-
"tags": ["finance", "automation", "personal-finance", "mcp"],
|
|
26
|
-
"variables": {
|
|
27
|
-
"type": "object",
|
|
28
|
-
"properties": {
|
|
29
|
-
"WARM_API_KEY": {
|
|
30
|
-
"type": "string",
|
|
31
|
-
"title": "Warm API key",
|
|
32
|
-
"description": "Full-access API key from https://warm.io/settings/api-keys"
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
"required": ["WARM_API_KEY"]
|
|
36
|
-
},
|
|
37
|
-
"mcpServers": "./mcp.json",
|
|
38
|
-
"skills": "./skills/"
|
|
39
|
-
}
|