@warmio/mcp 7.0.0 → 8.0.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/schemas.js CHANGED
@@ -1,248 +1,2 @@
1
- import { z } from 'zod';
2
- const monthSchema = z.string().regex(/^\d{4}-\d{2}$/, 'Expected YYYY-MM month.');
3
- const dateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Expected YYYY-MM-DD date.');
4
- const dateTimeSchema = z.string().datetime({ offset: true });
5
- export const emptyInputSchema = {};
6
- export const automationInputSchema = z
7
- .object({
8
- body: z.record(z.unknown()).optional(),
9
- params: z.record(z.string()).optional(),
10
- })
11
- .strict();
12
- export const searchOperationsInputSchema = {
13
- query: z.string().max(200).optional().describe('Words describing the action or data you need.'),
14
- };
15
- export const describeOperationInputSchema = {
16
- operation_id: z.string().min(1),
17
- input: automationInputSchema
18
- .optional()
19
- .describe('Exact intended input. Required to obtain approval for a write operation.'),
20
- };
21
- export const invokeOperationInputSchema = {
22
- operation_id: z.string().min(1),
23
- input: automationInputSchema.optional(),
24
- approval_id: z
25
- .string()
26
- .uuid()
27
- .optional()
28
- .describe('Approval ID returned by describe_operation for the exact write input.'),
29
- };
30
- export const transactionIndexSchema = z
31
- .object({
32
- total: z.number().int().nonnegative(),
33
- months: z.array(z
34
- .object({
35
- month: monthSchema,
36
- count: z.number().int().nonnegative(),
37
- })
38
- .strict()),
39
- })
40
- .strict();
41
- export const positionSchema = z
42
- .object({
43
- date: dateSchema.nullable(),
44
- net_worth: z.number().finite().nullable(),
45
- cash: z.number().finite().nullable(),
46
- debt: z.number().finite().nullable(),
47
- investments: z.number().finite().nullable(),
48
- other_assets: z.number().finite().nullable(),
49
- total_assets: z.number().finite().nullable(),
50
- })
51
- .strict();
52
- export const accountSchema = z
53
- .object({
54
- id: z.string(),
55
- name: z.string(),
56
- type: z.enum(['depository', 'credit', 'loan', 'investment', 'brokerage', 'other']),
57
- subtype: z.string().nullable(),
58
- group: z.enum(['cash', 'debt', 'investments']).nullable(),
59
- institution: z.string().nullable(),
60
- mask: z.string().nullable(),
61
- balance: z.number().finite().nullable(),
62
- available: z.number().finite().nullable(),
63
- currency: z.string().nullable(),
64
- updated_at: dateTimeSchema.nullable(),
65
- })
66
- .strict();
67
- export const statusSchema = z
68
- .object({
69
- position: positionSchema.nullable(),
70
- accounts: z.array(accountSchema),
71
- })
72
- .strict();
73
- export const recurringSchema = z
74
- .object({
75
- id: z.string(),
76
- account_id: z.string().nullable(),
77
- direction: z.enum(['inflow', 'outflow']).nullable(),
78
- frequency: z
79
- .enum(['WEEKLY', 'BIWEEKLY', 'MONTHLY', 'QUARTERLY', 'SEMI_ANNUALLY', 'ANNUALLY'])
80
- .nullable(),
81
- status: z.enum(['active', 'inactive', 'dismissed']).nullable(),
82
- merchant: z.string().nullable(),
83
- amount: z.number().finite().nullable(),
84
- next_date: dateSchema.nullable(),
85
- })
86
- .strict();
87
- export const budgetSchema = z
88
- .object({
89
- id: z.string(),
90
- name: z.string(),
91
- type: z.enum(['category', 'merchant']),
92
- period: z.enum(['weekly', 'biweekly', 'monthly']),
93
- status: z.enum(['under', 'warning', 'over']),
94
- amount: z.number().finite(),
95
- spent: z.number().finite(),
96
- remaining: z.number().finite(),
97
- used_percent: z.number().finite(),
98
- })
99
- .strict();
100
- export const goalSchema = z
101
- .object({
102
- id: z.string(),
103
- name: z.string(),
104
- category: z.string(),
105
- status: z.enum(['not_started', 'in_progress', 'on_track', 'behind', 'completed']),
106
- target: z.number().finite(),
107
- current: z.number().finite(),
108
- progress_percent: z.number().finite(),
109
- target_date: dateSchema.nullable(),
110
- })
111
- .strict();
112
- export const snapshotSchema = z
113
- .object({
114
- date: dateSchema,
115
- net_worth: z.number().finite().nullable(),
116
- cash: z.number().finite().nullable(),
117
- debt: z.number().finite().nullable(),
118
- income: z.number().finite().nullable(),
119
- expenses: z.number().finite().nullable(),
120
- cash_flow: z.number().finite().nullable(),
121
- savings_rate: z.number().finite().nullable(),
122
- investments: z.number().finite().nullable(),
123
- assets: z.number().finite().nullable(),
124
- health_score: z.number().finite().nullable(),
125
- })
126
- .strict();
127
- export const liabilitySchema = z
128
- .object({
129
- account_id: z.string().nullable(),
130
- type: z.enum(['credit', 'student', 'mortgage', 'other']).nullable(),
131
- balance: z.number().finite().nullable(),
132
- minimum_payment: z.number().finite().nullable(),
133
- due_date: dateSchema.nullable(),
134
- interest_rate: z.number().finite().nullable(),
135
- rate_type: z.enum(['fixed', 'variable']).nullable(),
136
- overdue: z.boolean().nullable(),
137
- })
138
- .strict();
139
- export const holdingSchema = z
140
- .object({
141
- account_id: z.string().nullable(),
142
- symbol: z.string().nullable(),
143
- name: z.string().nullable(),
144
- type: z
145
- .enum(['cash', 'derivative', 'equity', 'etf', 'fixed_income', 'mutual_fund', 'other'])
146
- .nullable(),
147
- quantity: z.number().finite().nullable(),
148
- value: z.number().finite().nullable(),
149
- cost_basis: z.number().finite().nullable(),
150
- })
151
- .strict();
152
- export const healthSchema = z
153
- .object({
154
- score: z.number().finite(),
155
- label: z.enum(['Needs Attention', 'Good', 'Strong']),
156
- level: z.enum(['critical', 'poor', 'fair', 'good', 'strong']),
157
- summary: z.string(),
158
- data_completeness: z.number().finite(),
159
- pillars: z
160
- .object({
161
- spend: z.number().finite().nullable(),
162
- save: z.number().finite().nullable(),
163
- borrow: z.number().finite().nullable(),
164
- build: z.number().finite().nullable(),
165
- })
166
- .strict()
167
- .nullable(),
168
- })
169
- .strict();
170
- export const financialContextSchema = z
171
- .object({
172
- version: z.literal('v1'),
173
- updated_at: dateTimeSchema,
174
- currency: z.literal('USD'),
175
- status: statusSchema,
176
- transactions: transactionIndexSchema,
177
- recurring: z.array(recurringSchema),
178
- budgets: z.array(budgetSchema),
179
- goals: z.array(goalSchema),
180
- snapshots: z.array(snapshotSchema),
181
- liabilities: z.array(liabilitySchema),
182
- holdings: z.array(holdingSchema),
183
- health: healthSchema.nullable(),
184
- })
185
- .strict();
186
- export const transactionSchema = z
187
- .object({
188
- id: z.string(),
189
- account_id: z.string().nullable(),
190
- date: dateSchema.nullable(),
191
- amount: z.number().finite(),
192
- merchant: z.string().nullable(),
193
- name: z.string().nullable(),
194
- category: z.string().nullable(),
195
- subcategory: z.string().nullable(),
196
- pending: z.boolean().nullable(),
197
- currency: z.string().nullable(),
198
- })
199
- .strict();
200
- export const transactionMonthSchema = z
201
- .object({
202
- month: monthSchema,
203
- start_date: dateSchema,
204
- end_date: dateSchema,
205
- count: z.number().int().nonnegative(),
206
- items: z.array(transactionSchema),
207
- })
208
- .strict();
209
- export const latestTransactionsSchema = z
210
- .object({
211
- since: dateSchema,
212
- window_days: z.literal(10),
213
- count: z.number().int().nonnegative(),
214
- items: z.array(transactionSchema),
215
- })
216
- .strict();
217
- export const getTransactionsInputSchema = {
218
- month: monthSchema
219
- .optional()
220
- .describe('Transaction month in YYYY-MM format. Mutually exclusive with latest. Months outside the covered range return an error.'),
221
- latest: z
222
- .boolean()
223
- .optional()
224
- .describe('When true, return the fixed 10-day latest window. Mutually exclusive with month. A bare call with no arguments defaults to latest: true.'),
225
- };
226
- export const financialContextMetaSchema = z
227
- .object({
228
- version: z.literal('v1'),
229
- user_id: z.string(),
230
- context_id: z.string(),
231
- generated_at: dateTimeSchema,
232
- updated_at: dateTimeSchema,
233
- content_hash: z.string(),
234
- byte_length: z.number().int().nonnegative(),
235
- counts: z
236
- .object({
237
- accounts: z.number().int().nonnegative(),
238
- transaction_months: z.number().int().nonnegative(),
239
- transactions: z.number().int().nonnegative(),
240
- snapshots: z.number().int().nonnegative(),
241
- })
242
- .strict(),
243
- })
244
- .strict();
245
- export const verifyKeyOutputSchema = {
246
- status: z.string(),
247
- valid: z.boolean(),
248
- };
1
+ export { automationInputSchema, financialContextAccountSchema as accountSchema, financialContextMetaSchema, financialContextSchema, financialContextTransactionSchema as transactionSchema, latestTransactionsSchema, transactionMonthSchema, } from '@warmio/contracts/schemas';
2
+ export { describeOperationMcpInputShape as describeOperationInputSchema, emptyMcpInputShape as emptyInputSchema, getTransactionsMcpInputShape as getTransactionsInputSchema, invokeOperationMcpInputShape as invokeOperationInputSchema, searchOperationsMcpInputShape as searchOperationsInputSchema, } from '@warmio/contracts/mcp';
package/dist/server.js CHANGED
@@ -3,8 +3,8 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import { toJsonSchemaCompat } from '@modelcontextprotocol/sdk/server/zod-json-schema-compat.js';
4
4
  import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { z } from 'zod';
6
+ import { getTransactionsMcpInputSchema, normalizeGetTransactionsMcpInput, privateMcpToolDefinitions, } from '@warmio/contracts/mcp';
6
7
  import { createWarmApiClient, getConfiguredApiKey, verifyWarmApiKey, WarmApiError, } from './warm-api-client.js';
7
- import { describeOperationInputSchema, emptyInputSchema, getTransactionsInputSchema, invokeOperationInputSchema, searchOperationsInputSchema, } from './schemas.js';
8
8
  export { createWarmApiClient, getConfiguredApiKey, verifyWarmApiKey, WarmApiError };
9
9
  export const API_URL = process.env.WARM_API_URL || 'https://app.warm.io';
10
10
  function getPackageVersion() {
@@ -29,8 +29,7 @@ function createStructuredToolResult(structuredContent, isError = false) {
29
29
  text: JSON.stringify(structuredContent, null, 2),
30
30
  },
31
31
  ],
32
- ...(isError ? { isError: true } : {}),
33
- structuredContent,
32
+ ...(isError ? { isError: true } : { structuredContent }),
34
33
  };
35
34
  }
36
35
  function createToolFailure(error) {
@@ -48,69 +47,56 @@ function createToolFailure(error) {
48
47
  },
49
48
  }, true);
50
49
  }
51
- function parseGetTransactionsArgs(args) {
52
- const hasMonth = typeof args.month === 'string';
53
- const hasLatestKey = Object.prototype.hasOwnProperty.call(args, 'latest');
54
- const hasLatest = args.latest === true;
55
- if (hasMonth && hasLatestKey) {
56
- throw new Error('`month` and `latest` are mutually exclusive.');
57
- }
58
- if (hasMonth) {
59
- return { month: args.month };
60
- }
61
- if (hasLatest || Object.keys(args).length === 0) {
62
- return { latest: true };
50
+ function getToolDefinition(name, mode) {
51
+ const definition = privateMcpToolDefinitions.find((candidate) => candidate.mode === mode && candidate.name === name);
52
+ if (!definition)
53
+ throw new Error(`Missing ${mode} MCP contract for ${name}.`);
54
+ return definition;
55
+ }
56
+ function getListToolOutputSchema(outputSchema) {
57
+ const schema = toJsonSchemaCompat(outputSchema, {
58
+ pipeStrategy: 'output',
59
+ strictUnions: true,
60
+ });
61
+ if (schema.type === 'object')
62
+ return schema;
63
+ if (Array.isArray(schema.anyOf) &&
64
+ schema.anyOf.length > 0 &&
65
+ schema.anyOf.every((candidate) => typeof candidate === 'object' && candidate !== null && candidate.type === 'object')) {
66
+ return { ...schema, type: 'object' };
63
67
  }
64
- throw new Error('Call get_transactions with `month` in YYYY-MM format, `latest: true`, or no arguments.');
68
+ return undefined;
65
69
  }
66
70
  export function registerWarmTools(server, options = {}, mode = 'context') {
67
71
  const client = createWarmApiClient({ ...options, audience: mode });
68
72
  const contextTools = [
69
73
  {
70
- annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
71
- description: 'Read-only compact FinancialContext JSON. Includes status.position, status.accounts, transaction index total/months, recurring, budgets, goals, snapshots, liabilities, holdings, and health. Transaction items are not inline; use get_transactions for items.',
74
+ ...getToolDefinition('get_financial_context', 'context'),
72
75
  handler: async () => await client.getFinancialContext(),
73
- inputShape: emptyInputSchema,
74
- name: 'get_financial_context',
75
76
  },
76
77
  {
77
- annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
78
- description: 'Read-only transactions from the FinancialContext artifact. Pass exactly one selector: `month` in YYYY-MM format for a month page, or `latest: true` for the fixed latest window. A bare call with no arguments defaults to `latest: true`. The latest window is fixed at 10 days and is not caller-configurable. `month` and `latest` are mutually exclusive. Months outside the covered range return an error.',
78
+ ...getToolDefinition('get_transactions', 'context'),
79
79
  handler: async (args) => {
80
- return await client.getTransactions(parseGetTransactionsArgs(args));
80
+ return await client.getTransactions(normalizeGetTransactionsMcpInput(args));
81
81
  },
82
- inputShape: getTransactionsInputSchema,
83
- name: 'get_transactions',
84
82
  },
85
83
  {
86
- annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
87
- description: 'Read-only API key validation for the configured Warm account.',
84
+ ...getToolDefinition('verify_key', 'context'),
88
85
  handler: async () => await client.validateAudience(),
89
- inputShape: emptyInputSchema,
90
- name: 'verify_key',
91
86
  },
92
87
  ];
93
88
  const automationTools = [
94
89
  {
95
- annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
96
- description: 'Search the supported Warm operation catalog. Use this first to find the smallest matching operation.',
90
+ ...getToolDefinition('search_operations', 'automation'),
97
91
  handler: async (args) => await client.searchOperations(typeof args.query === 'string' ? args.query : undefined),
98
- inputShape: searchOperationsInputSchema,
99
- name: 'search_operations',
100
92
  },
101
93
  {
102
- annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false },
103
- description: 'Describe one operation, including its input schema and risk. For write operations, pass the exact intended input to receive an approval with its ID, status, URL, and expiry.',
94
+ ...getToolDefinition('describe_operation', 'automation'),
104
95
  handler: async (args) => await client.describeOperation(args.operation_id, args.input),
105
- inputShape: describeOperationInputSchema,
106
- name: 'describe_operation',
107
96
  },
108
97
  {
109
- annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false },
110
- description: 'Invoke one previously discovered Warm operation. Every write operation requires the approval_id returned for the exact same input by describe_operation.',
98
+ ...getToolDefinition('invoke_operation', 'automation'),
111
99
  handler: async (args) => await client.invokeOperation(args.operation_id, args.input, typeof args.approval_id === 'string' ? args.approval_id : undefined),
112
- inputShape: invokeOperationInputSchema,
113
- name: 'invoke_operation',
114
100
  },
115
101
  ];
116
102
  const tools = mode === 'automation' ? automationTools : contextTools;
@@ -120,15 +106,19 @@ export function registerWarmTools(server, options = {}, mode = 'context') {
120
106
  },
121
107
  });
122
108
  server.server.setRequestHandler(ListToolsRequestSchema, () => ({
123
- tools: tools.map((tool) => ({
124
- description: tool.description,
125
- annotations: tool.annotations,
126
- inputSchema: toJsonSchemaCompat(z.object(tool.inputShape).strict(), {
127
- pipeStrategy: 'input',
128
- strictUnions: true,
129
- }),
130
- name: tool.name,
131
- })),
109
+ tools: tools.map((tool) => {
110
+ const outputSchema = getListToolOutputSchema(tool.outputSchema);
111
+ return {
112
+ description: tool.description,
113
+ annotations: tool.annotations,
114
+ inputSchema: toJsonSchemaCompat(z.object(tool.inputShape).strict(), {
115
+ pipeStrategy: 'input',
116
+ strictUnions: true,
117
+ }),
118
+ ...(outputSchema ? { outputSchema } : {}),
119
+ name: tool.name,
120
+ };
121
+ }),
132
122
  }));
133
123
  server.server.setRequestHandler(CallToolRequestSchema, async (request) => {
134
124
  const tool = tools.find((candidate) => candidate.name === request.params.name);
@@ -141,11 +131,9 @@ export function registerWarmTools(server, options = {}, mode = 'context') {
141
131
  throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${request.params.name}: ${parseResult.error.message}`);
142
132
  }
143
133
  if (tool.name === 'get_transactions') {
144
- try {
145
- parseGetTransactionsArgs(parseResult.data);
146
- }
147
- catch (error) {
148
- throw new McpError(ErrorCode.InvalidParams, error instanceof Error ? error.message : String(error));
134
+ const transactionInput = await getTransactionsMcpInputSchema.safeParseAsync(parseResult.data);
135
+ if (!transactionInput.success) {
136
+ throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${request.params.name}: ${transactionInput.error.message}`);
149
137
  }
150
138
  }
151
139
  try {
@@ -1,4 +1,6 @@
1
1
  import { type WarmApiAudience } from './config-paths.js';
2
+ import type { AutomationInput, AutomationOperation, FinancialContext, FinancialContextAccount, FinancialContextBudget, FinancialContextGoal, FinancialContextHealth, FinancialContextHolding, FinancialContextLiability, FinancialContextMeta, FinancialContextPosition, FinancialContextRecurring, FinancialContextSnapshot, FinancialContextStatus, FinancialContextTransaction, FinancialContextTransactionIndex, LatestTransactions, TransactionMonth } from '@warmio/contracts/types';
3
+ export type { AutomationInput, AutomationOperation, FinancialContext, FinancialContextMeta, LatestTransactions, TransactionMonth, } from '@warmio/contracts/types';
2
4
  export interface WarmApiClientOptions {
3
5
  audience?: WarmApiAudience;
4
6
  apiKeyResolver?: () => string | null;
@@ -6,154 +8,18 @@ export interface WarmApiClientOptions {
6
8
  fetchImplementation?: typeof fetch;
7
9
  requestTimeoutMs?: number;
8
10
  }
9
- export interface TransactionIndex {
10
- total: number;
11
- months: Array<{
12
- month: string;
13
- count: number;
14
- }>;
15
- }
16
- export interface Position {
17
- date: string | null;
18
- net_worth: number | null;
19
- cash: number | null;
20
- debt: number | null;
21
- investments: number | null;
22
- other_assets: number | null;
23
- total_assets: number | null;
24
- }
25
- export interface Account {
26
- id: string;
27
- name: string;
28
- type: 'depository' | 'credit' | 'loan' | 'investment' | 'brokerage' | 'other';
29
- subtype: string | null;
30
- group: 'cash' | 'debt' | 'investments' | null;
31
- institution: string | null;
32
- mask: string | null;
33
- balance: number | null;
34
- available: number | null;
35
- currency: string | null;
36
- updated_at: string | null;
37
- }
38
- export interface Status {
39
- position: Position | null;
40
- accounts: Account[];
41
- }
42
- export interface Recurring {
43
- id: string;
44
- account_id: string | null;
45
- direction: 'inflow' | 'outflow' | null;
46
- frequency: 'WEEKLY' | 'BIWEEKLY' | 'MONTHLY' | 'QUARTERLY' | 'SEMI_ANNUALLY' | 'ANNUALLY' | null;
47
- status: 'active' | 'inactive' | 'dismissed' | null;
48
- merchant: string | null;
49
- amount: number | null;
50
- next_date: string | null;
51
- }
52
- export interface Budget {
53
- id: string;
54
- name: string;
55
- type: 'category' | 'merchant';
56
- period: 'weekly' | 'biweekly' | 'monthly';
57
- status: 'under' | 'warning' | 'over';
58
- amount: number;
59
- spent: number;
60
- remaining: number;
61
- used_percent: number;
62
- }
63
- export interface Goal {
64
- id: string;
65
- name: string;
66
- category: string;
67
- status: 'not_started' | 'in_progress' | 'on_track' | 'behind' | 'completed';
68
- target: number;
69
- current: number;
70
- progress_percent: number;
71
- target_date: string | null;
72
- }
73
- export interface Snapshot {
74
- date: string;
75
- net_worth: number | null;
76
- cash: number | null;
77
- debt: number | null;
78
- income: number | null;
79
- expenses: number | null;
80
- cash_flow: number | null;
81
- savings_rate: number | null;
82
- investments: number | null;
83
- assets: number | null;
84
- health_score: number | null;
85
- }
86
- export interface Liability {
87
- account_id: string | null;
88
- type: 'credit' | 'student' | 'mortgage' | 'other' | null;
89
- balance: number | null;
90
- minimum_payment: number | null;
91
- due_date: string | null;
92
- interest_rate: number | null;
93
- rate_type: 'fixed' | 'variable' | null;
94
- overdue: boolean | null;
95
- }
96
- export interface Holding {
97
- account_id: string | null;
98
- symbol: string | null;
99
- name: string | null;
100
- type: 'cash' | 'derivative' | 'equity' | 'etf' | 'fixed_income' | 'mutual_fund' | 'other' | null;
101
- quantity: number | null;
102
- value: number | null;
103
- cost_basis: number | null;
104
- }
105
- export interface Health {
106
- score: number;
107
- label: 'Needs Attention' | 'Good' | 'Strong';
108
- level: 'critical' | 'poor' | 'fair' | 'good' | 'strong';
109
- summary: string;
110
- data_completeness: number;
111
- pillars: {
112
- spend: number | null;
113
- save: number | null;
114
- borrow: number | null;
115
- build: number | null;
116
- } | null;
117
- }
118
- export interface FinancialContext extends Record<string, unknown> {
119
- version: 'v1';
120
- updated_at: string;
121
- currency: 'USD';
122
- status: Status;
123
- transactions: TransactionIndex;
124
- recurring: Recurring[];
125
- budgets: Budget[];
126
- goals: Goal[];
127
- snapshots: Snapshot[];
128
- liabilities: Liability[];
129
- holdings: Holding[];
130
- health: Health | null;
131
- }
132
- export interface Transaction {
133
- id: string;
134
- account_id: string | null;
135
- date: string | null;
136
- amount: number;
137
- merchant: string | null;
138
- name: string | null;
139
- category: string | null;
140
- subcategory: string | null;
141
- pending: boolean | null;
142
- currency: string | null;
143
- }
144
- export interface TransactionMonth extends Record<string, unknown> {
145
- month: string;
146
- start_date: string;
147
- end_date: string;
148
- count: number;
149
- items: Transaction[];
150
- }
151
- export interface LatestTransactions extends Record<string, unknown> {
152
- since: string;
153
- window_days: 10;
154
- count: number;
155
- items: Transaction[];
156
- }
11
+ export type Account = FinancialContextAccount;
12
+ export type Budget = FinancialContextBudget;
13
+ export type Goal = FinancialContextGoal;
14
+ export type Health = FinancialContextHealth;
15
+ export type Holding = FinancialContextHolding;
16
+ export type Liability = FinancialContextLiability;
17
+ export type Position = FinancialContextPosition;
18
+ export type Recurring = FinancialContextRecurring;
19
+ export type Snapshot = FinancialContextSnapshot;
20
+ export type Status = FinancialContextStatus;
21
+ export type Transaction = FinancialContextTransaction;
22
+ export type TransactionIndex = FinancialContextTransactionIndex;
157
23
  export type GetTransactionsInput = {
158
24
  month: string;
159
25
  latest?: never;
@@ -162,42 +28,14 @@ export type GetTransactionsInput = {
162
28
  month?: never;
163
29
  };
164
30
  export type GetTransactionsOutput = TransactionMonth | LatestTransactions;
165
- export interface FinancialContextMeta extends Record<string, unknown> {
166
- version: 'v1';
167
- user_id: string;
168
- context_id: string;
169
- generated_at: string;
170
- updated_at: string;
171
- content_hash: string;
172
- byte_length: number;
173
- counts: {
174
- accounts: number;
175
- transaction_months: number;
176
- transactions: number;
177
- snapshots: number;
178
- };
179
- }
180
31
  export interface VerifyKeyOutput extends Record<string, unknown> {
181
32
  audience?: 'automation' | 'context' | 'oauth';
182
33
  status: string;
183
34
  valid: boolean;
184
35
  }
185
- export interface AutomationOperation extends Record<string, unknown> {
186
- confirmation_required: boolean;
187
- description: string;
188
- method: 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT';
189
- operation_id: string;
190
- path: string;
191
- risk: Array<'read' | 'write' | 'destructive' | 'external_effect'>;
192
- summary: string;
193
- }
194
- export interface AutomationInput {
195
- body?: Record<string, unknown>;
196
- params?: Record<string, string>;
197
- }
198
- export interface AutomationOperationDescription extends AutomationOperation {
36
+ export type AutomationOperationDescription = AutomationOperation & {
199
37
  input_schema: Record<string, unknown>;
200
- }
38
+ };
201
39
  export interface DescribeOperationOutput extends Record<string, unknown> {
202
40
  approval?: {
203
41
  approval_url: string;
@@ -240,4 +78,3 @@ export declare class WarmApiError extends Error {
240
78
  }
241
79
  export declare function createWarmApiClient(options?: WarmApiClientOptions): WarmApiClient;
242
80
  export declare function verifyWarmApiKey(apiKey: string, audience?: WarmApiAudience): Promise<VerifyKeyOutput>;
243
- export {};
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@warmio/mcp",
3
- "version": "7.0.0",
3
+ "version": "8.0.0",
4
+ "mcpName": "io.github.jasonstockman/warmio",
4
5
  "description": "Warm CLI and compact context or automation MCP server",
5
6
  "type": "module",
6
7
  "main": "dist/index.js",
@@ -24,6 +25,10 @@
24
25
  "./install": {
25
26
  "types": "./dist/install.d.ts",
26
27
  "default": "./dist/install.js"
28
+ },
29
+ "./manifest": {
30
+ "types": "./dist/manifest.d.ts",
31
+ "default": "./dist/manifest.js"
27
32
  }
28
33
  },
29
34
  "bin": {
@@ -51,7 +56,12 @@
51
56
  "chatgpt"
52
57
  ],
53
58
  "license": "MIT",
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/jasonstockman/warm-mcp.git"
62
+ },
54
63
  "dependencies": {
64
+ "@warmio/contracts": "1.0.0",
55
65
  "@modelcontextprotocol/sdk": "^1.27.1",
56
66
  "dotenv": "^17.2.3",
57
67
  "zod": "^3.25.76"