@warmio/mcp 9.1.1 → 11.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/stdio.js DELETED
@@ -1,200 +0,0 @@
1
- import process from 'node:process';
2
- const CONTENT_LENGTH_HEADER = 'content-length:';
3
- export class AdaptiveStdioTransport {
4
- stdin;
5
- stdout;
6
- onclose;
7
- onerror;
8
- onmessage;
9
- buffer = Buffer.alloc(0);
10
- clientFraming = null;
11
- closed = false;
12
- started = false;
13
- constructor(stdin = process.stdin, stdout = process.stdout) {
14
- this.stdin = stdin;
15
- this.stdout = stdout;
16
- }
17
- async start() {
18
- if (this.started) {
19
- throw new Error('AdaptiveStdioTransport already started');
20
- }
21
- this.started = true;
22
- this.stdin.on('data', this.handleData);
23
- this.stdin.on('error', this.handleError);
24
- this.stdin.on('end', this.handleEnd);
25
- this.stdin.resume();
26
- }
27
- async close() {
28
- if (this.closed) {
29
- return;
30
- }
31
- this.closed = true;
32
- this.stdin.off('data', this.handleData);
33
- this.stdin.off('error', this.handleError);
34
- this.stdin.off('end', this.handleEnd);
35
- this.stdin.pause();
36
- this.buffer = Buffer.alloc(0);
37
- this.onclose?.();
38
- }
39
- async send(message, _options) {
40
- const json = JSON.stringify(message);
41
- const framing = this.clientFraming ?? 'content-length';
42
- const payload = framing === 'jsonl'
43
- ? `${json}\n`
44
- : `Content-Length: ${Buffer.byteLength(json, 'utf8')}\r\n\r\n${json}`;
45
- await new Promise((resolve) => {
46
- if (this.stdout.write(payload)) {
47
- resolve();
48
- return;
49
- }
50
- this.stdout.once('drain', resolve);
51
- });
52
- }
53
- handleData = (chunk) => {
54
- const incoming = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
55
- this.buffer = this.buffer.length === 0 ? incoming : Buffer.concat([this.buffer, incoming]);
56
- this.processBuffer();
57
- };
58
- handleError = (error) => {
59
- this.onerror?.(error);
60
- };
61
- handleEnd = () => {
62
- void this.close();
63
- };
64
- processBuffer() {
65
- while (true) {
66
- try {
67
- this.trimLeadingNewlines();
68
- const parsed = this.readMessage();
69
- if (parsed === null) {
70
- return;
71
- }
72
- this.clientFraming ??= parsed.framing;
73
- this.onmessage?.(parsed.message);
74
- }
75
- catch (error) {
76
- this.onerror?.(error instanceof Error ? error : new Error(String(error)));
77
- this.buffer = Buffer.alloc(0);
78
- return;
79
- }
80
- }
81
- }
82
- trimLeadingNewlines() {
83
- while (this.buffer.length > 0) {
84
- if (this.buffer[0] === 0x0a) {
85
- this.buffer = this.buffer.subarray(1);
86
- continue;
87
- }
88
- if (this.buffer.length > 1 && this.buffer[0] === 0x0d && this.buffer[1] === 0x0a) {
89
- this.buffer = this.buffer.subarray(2);
90
- continue;
91
- }
92
- return;
93
- }
94
- }
95
- readMessage() {
96
- const framing = this.clientFraming ?? this.detectFraming();
97
- if (framing === null) {
98
- return null;
99
- }
100
- return framing === 'content-length'
101
- ? this.readContentLengthMessage()
102
- : this.readJsonLineMessage();
103
- }
104
- detectFraming() {
105
- if (this.buffer.length === 0) {
106
- return null;
107
- }
108
- const preview = this.buffer
109
- .subarray(0, Math.min(this.buffer.length, 32))
110
- .toString('utf8')
111
- .toLowerCase();
112
- if (preview.startsWith(CONTENT_LENGTH_HEADER)) {
113
- return 'content-length';
114
- }
115
- if (preview.startsWith('{') || preview.startsWith('[')) {
116
- return 'jsonl';
117
- }
118
- const newlineIndex = this.buffer.indexOf(0x0a);
119
- if (newlineIndex === -1) {
120
- return null;
121
- }
122
- const firstLine = this.buffer.toString('utf8', 0, newlineIndex).replace(/\r$/, '').trimStart();
123
- if (firstLine.toLowerCase().startsWith(CONTENT_LENGTH_HEADER)) {
124
- return 'content-length';
125
- }
126
- if (firstLine.startsWith('{') || firstLine.startsWith('[')) {
127
- return 'jsonl';
128
- }
129
- throw new Error(`Unsupported MCP stdio framing: ${JSON.stringify(firstLine.slice(0, 80))}`);
130
- }
131
- readJsonLineMessage() {
132
- const newlineIndex = this.buffer.indexOf(0x0a);
133
- if (newlineIndex === -1) {
134
- return null;
135
- }
136
- const rawLine = this.buffer.toString('utf8', 0, newlineIndex).replace(/\r$/, '');
137
- this.buffer = this.buffer.subarray(newlineIndex + 1);
138
- if (rawLine.trim() === '') {
139
- return this.readMessage();
140
- }
141
- return {
142
- framing: 'jsonl',
143
- message: JSON.parse(rawLine),
144
- };
145
- }
146
- readContentLengthMessage() {
147
- const headerBoundary = this.findHeaderBoundary();
148
- if (headerBoundary === null) {
149
- return null;
150
- }
151
- const { bodyStart, headerEnd } = headerBoundary;
152
- const headerText = this.buffer.toString('utf8', 0, headerEnd);
153
- const contentLength = this.parseContentLength(headerText);
154
- if (this.buffer.length < bodyStart + contentLength) {
155
- return null;
156
- }
157
- const bodyText = this.buffer.toString('utf8', bodyStart, bodyStart + contentLength);
158
- this.buffer = this.buffer.subarray(bodyStart + contentLength);
159
- return {
160
- framing: 'content-length',
161
- message: JSON.parse(bodyText),
162
- };
163
- }
164
- findHeaderBoundary() {
165
- const crlfBoundary = this.buffer.indexOf('\r\n\r\n');
166
- if (crlfBoundary !== -1) {
167
- return {
168
- bodyStart: crlfBoundary + 4,
169
- headerEnd: crlfBoundary,
170
- };
171
- }
172
- const lfBoundary = this.buffer.indexOf('\n\n');
173
- if (lfBoundary !== -1) {
174
- return {
175
- bodyStart: lfBoundary + 2,
176
- headerEnd: lfBoundary,
177
- };
178
- }
179
- return null;
180
- }
181
- parseContentLength(headerText) {
182
- const headers = headerText.split(/\r?\n/);
183
- for (const header of headers) {
184
- const separatorIndex = header.indexOf(':');
185
- if (separatorIndex === -1) {
186
- continue;
187
- }
188
- const name = header.slice(0, separatorIndex).trim().toLowerCase();
189
- if (name !== 'content-length') {
190
- continue;
191
- }
192
- const value = Number.parseInt(header.slice(separatorIndex + 1).trim(), 10);
193
- if (!Number.isFinite(value) || value < 0) {
194
- throw new Error(`Invalid Content-Length header: ${header}`);
195
- }
196
- return value;
197
- }
198
- throw new Error('Missing Content-Length header');
199
- }
200
- }
package/dist/types.d.ts DELETED
@@ -1,8 +0,0 @@
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'];
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';
7
- export type { PrivateMcpMode } from '@warmio/contracts/mcp';
8
- export type { WarmServerOptions } from './server.js';
package/dist/types.js DELETED
@@ -1,8 +0,0 @@
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,2 +0,0 @@
1
- export * from './server.js';
2
- export * from './warm-api-client.js';
@@ -1,2 +0,0 @@
1
- export * from './server.js';
2
- export * from './warm-api-client.js';