@warmio/mcp 9.0.0 → 9.1.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/types.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- export declare const WARM_CONTEXT_TOOL_NAMES: readonly ["get_financial_context", "get_transactions", "verify_key"];
2
- export declare const WARM_AUTOMATION_TOOL_NAMES: readonly ["search_operations", "describe_operation", "invoke_operation"];
3
- export declare const WARM_TOOL_NAMES: readonly ["get_financial_context", "get_transactions", "verify_key", "search_operations", "describe_operation", "invoke_operation"];
4
- export type WarmToolName = (typeof WARM_TOOL_NAMES)[number];
1
+ import { privateMcpToolDefinitions } from '@warmio/contracts/mcp';
2
+ export declare const WARM_CONTEXT_TOOL_NAMES: string[];
3
+ export declare const WARM_AUTOMATION_TOOL_NAMES: string[];
4
+ export declare const WARM_TOOL_NAMES: string[];
5
+ export type WarmToolName = (typeof privateMcpToolDefinitions)[number]['name'];
5
6
  export type { Account, AutomationInput, AutomationOperation, AutomationOperationDescription, Budget, DescribeOperationOutput, FinancialContext, FinancialContextMeta, GetTransactionsInput, GetTransactionsOutput, Goal, Health, Holding, InvokeOperationOutput, LatestTransactions, Liability, Position, Recurring, Snapshot, Status, Transaction, TransactionIndex, TransactionMonth, VerifyKeyOutput, WarmApiClient, WarmApiClientOptions, } from './warm-api-client.js';
6
7
  export type { PrivateMcpMode } from '@warmio/contracts/mcp';
7
8
  export type { WarmServerOptions } from './server.js';
package/dist/types.js CHANGED
@@ -1,11 +1,8 @@
1
- export const WARM_CONTEXT_TOOL_NAMES = [
2
- 'get_financial_context',
3
- 'get_transactions',
4
- 'verify_key',
5
- ];
6
- export const WARM_AUTOMATION_TOOL_NAMES = [
7
- 'search_operations',
8
- 'describe_operation',
9
- 'invoke_operation',
10
- ];
11
- export const WARM_TOOL_NAMES = [...WARM_CONTEXT_TOOL_NAMES, ...WARM_AUTOMATION_TOOL_NAMES];
1
+ import { privateMcpToolDefinitions } from '@warmio/contracts/mcp';
2
+ export const WARM_CONTEXT_TOOL_NAMES = privateMcpToolDefinitions
3
+ .filter((tool) => tool.mode === 'context')
4
+ .map((tool) => tool.name);
5
+ export const WARM_AUTOMATION_TOOL_NAMES = privateMcpToolDefinitions
6
+ .filter((tool) => tool.mode === 'automation')
7
+ .map((tool) => tool.name);
8
+ export const WARM_TOOL_NAMES = privateMcpToolDefinitions.map((tool) => tool.name);
@@ -1,11 +1,20 @@
1
1
  import { getWarmApiKeyPath, readConfigFile } from './config-paths.js';
2
+ import { API_ORIGIN, apiEndpointManifest, } from '@warmio/contracts/api';
2
3
  import { WARM_MCP_CREDENTIALS, WARM_MCP_INSTALLER_COMMANDS, } from '@warmio/contracts/mcp';
3
- const DEFAULT_API_URL = process.env.WARM_API_URL || 'https://app.warm.io';
4
+ const DEFAULT_API_URL = process.env.WARM_API_URL || API_ORIGIN;
4
5
  const DEFAULT_REQUEST_TIMEOUT_MS = (() => {
5
6
  const raw = Number(process.env.WARM_API_TIMEOUT_MS || 10_000);
6
7
  return Number.isFinite(raw) && raw > 0 ? raw : 10_000;
7
8
  })();
8
9
  const cachedApiKeys = new Map();
10
+ const endpointByOperationId = Object.fromEntries(apiEndpointManifest.map((endpoint) => [endpoint.operation_id, endpoint]));
11
+ function getEndpointPath(operationId, audience) {
12
+ const endpoint = endpointByOperationId[operationId];
13
+ if (endpoint.audience !== audience) {
14
+ throw new Error(`API operation ${operationId} is not available to ${audience}.`);
15
+ }
16
+ return endpoint.path;
17
+ }
9
18
  function getRequestSignal(timeoutMs) {
10
19
  if (typeof AbortSignal.timeout === 'function') {
11
20
  return AbortSignal.timeout(timeoutMs);
@@ -120,23 +129,29 @@ async function requestSuccessfulJson(request, options) {
120
129
  return response.body;
121
130
  }
122
131
  export function createWarmApiClient(options = {}) {
123
- const getFinancialContext = async () => await requestSuccessfulJson({ endpoint: '/api/financial-context' }, options);
124
- const getFinancialContextMeta = async () => await requestSuccessfulJson({ endpoint: '/api/financial-context/meta' }, options);
132
+ const getFinancialContext = async () => await requestSuccessfulJson({ endpoint: getEndpointPath('getFinancialContext', 'context') }, options);
133
+ const getFinancialContextMeta = async () => await requestSuccessfulJson({ endpoint: getEndpointPath('getFinancialContextMeta', 'context') }, options);
125
134
  const getTransactions = async (input) => {
126
135
  const rawInput = input;
127
136
  if (typeof rawInput.month === 'string' && rawInput.latest !== undefined) {
128
137
  throw new Error('`month` and `latest` are mutually exclusive.');
129
138
  }
130
139
  if (typeof rawInput.month === 'string') {
131
- return await requestSuccessfulJson({ endpoint: '/api/financial-context/transactions', query: { month: rawInput.month } }, options);
140
+ return await requestSuccessfulJson({
141
+ endpoint: getEndpointPath('getFinancialContextTransactions', 'context'),
142
+ query: { month: rawInput.month },
143
+ }, options);
132
144
  }
133
145
  if (rawInput.latest === true) {
134
- return await requestSuccessfulJson({ endpoint: '/api/financial-context/transactions', query: { latest: '1' } }, options);
146
+ return await requestSuccessfulJson({
147
+ endpoint: getEndpointPath('getFinancialContextTransactions', 'context'),
148
+ query: { latest: '1' },
149
+ }, options);
135
150
  }
136
151
  throw new Error('Call getTransactions with `month` in YYYY-MM format or `latest: true`.');
137
152
  };
138
153
  const verifyKey = async () => {
139
- const response = await requestSuccessfulJson({ endpoint: '/api/verify' }, options);
154
+ const response = await requestSuccessfulJson({ endpoint: getEndpointPath('verifyApiAccess', 'context') }, options);
140
155
  return {
141
156
  audience: response.audience,
142
157
  status: response.status || (response.valid ? 'ok' : 'invalid'),
@@ -154,12 +169,12 @@ export function createWarmApiClient(options = {}) {
154
169
  };
155
170
  const searchOperations = async (query) => await requestSuccessfulJson({
156
171
  body: query ? { query } : {},
157
- endpoint: '/api/automation/operations/search',
172
+ endpoint: getEndpointPath('searchOperations', 'automation'),
158
173
  method: 'POST',
159
174
  }, options);
160
175
  const describeOperation = async (operationId, input) => await requestSuccessfulJson({
161
176
  body: { operation_id: operationId, ...(input ? { input } : {}) },
162
- endpoint: '/api/automation/operations/describe',
177
+ endpoint: getEndpointPath('describeOperation', 'automation'),
163
178
  method: 'POST',
164
179
  }, options);
165
180
  const invokeOperation = async (operationId, input, approvalId) => await requestSuccessfulJson({
@@ -168,7 +183,7 @@ export function createWarmApiClient(options = {}) {
168
183
  input: input ?? {},
169
184
  ...(approvalId ? { approval_id: approvalId } : {}),
170
185
  },
171
- endpoint: '/api/automation/operations/invoke',
186
+ endpoint: getEndpointPath('invokeOperation', 'automation'),
172
187
  method: 'POST',
173
188
  }, options);
174
189
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmio/mcp",
3
- "version": "9.0.0",
3
+ "version": "9.1.0",
4
4
  "mcpName": "io.github.jasonstockman/warmio",
5
5
  "description": "Warm CLI and compact context or automation MCP server",
6
6
  "type": "module",
@@ -60,7 +60,7 @@
60
60
  "url": "git+https://github.com/jasonstockman/warm-mcp.git"
61
61
  },
62
62
  "dependencies": {
63
- "@warmio/contracts": "1.1.0",
63
+ "@warmio/contracts": "1.2.0",
64
64
  "@modelcontextprotocol/sdk": "^1.27.1",
65
65
  "dotenv": "^17.2.3",
66
66
  "zod": "^3.25.76"