@infamousendeavors/lunchmoney-mcp 0.3.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/LICENSE +25 -0
- package/README.md +288 -0
- package/SECURITY.md +130 -0
- package/dist/api/client.d.ts +11 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +82 -0
- package/dist/api/client.js.map +1 -0
- package/dist/auth-provider.d.ts +47 -0
- package/dist/auth-provider.d.ts.map +1 -0
- package/dist/auth-provider.js +111 -0
- package/dist/auth-provider.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +103 -0
- package/dist/cli.js.map +1 -0
- package/dist/credential-store.d.ts +25 -0
- package/dist/credential-store.d.ts.map +1 -0
- package/dist/credential-store.js +90 -0
- package/dist/credential-store.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/index.d.ts +189 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +178 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/server.d.ts +32 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +116 -0
- package/dist/server.js.map +1 -0
- package/dist/session-store.d.ts +28 -0
- package/dist/session-store.d.ts.map +1 -0
- package/dist/session-store.js +50 -0
- package/dist/session-store.js.map +1 -0
- package/dist/setup.d.ts +21 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +104 -0
- package/dist/setup.js.map +1 -0
- package/dist/tools/assets.d.ts +4 -0
- package/dist/tools/assets.d.ts.map +1 -0
- package/dist/tools/assets.js +63 -0
- package/dist/tools/assets.js.map +1 -0
- package/dist/tools/budgets.d.ts +4 -0
- package/dist/tools/budgets.d.ts.map +1 -0
- package/dist/tools/budgets.js +63 -0
- package/dist/tools/budgets.js.map +1 -0
- package/dist/tools/categories.d.ts +4 -0
- package/dist/tools/categories.d.ts.map +1 -0
- package/dist/tools/categories.js +105 -0
- package/dist/tools/categories.js.map +1 -0
- package/dist/tools/plaid.d.ts +4 -0
- package/dist/tools/plaid.d.ts.map +1 -0
- package/dist/tools/plaid.js +33 -0
- package/dist/tools/plaid.js.map +1 -0
- package/dist/tools/recurring.d.ts +4 -0
- package/dist/tools/recurring.d.ts.map +1 -0
- package/dist/tools/recurring.js +63 -0
- package/dist/tools/recurring.js.map +1 -0
- package/dist/tools/tags.d.ts +4 -0
- package/dist/tools/tags.d.ts.map +1 -0
- package/dist/tools/tags.js +63 -0
- package/dist/tools/tags.js.map +1 -0
- package/dist/tools/transactions.d.ts +4 -0
- package/dist/tools/transactions.d.ts.map +1 -0
- package/dist/tools/transactions.js +146 -0
- package/dist/tools/transactions.js.map +1 -0
- package/dist/tools/user.d.ts +4 -0
- package/dist/tools/user.d.ts.map +1 -0
- package/dist/tools/user.js +19 -0
- package/dist/tools/user.js.map +1 -0
- package/dist/types/index.d.ts +164 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/errors.d.ts +8 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +29 -0
- package/dist/utils/errors.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { GoogleProvider, GitHubProvider, OAuthProvider } from "fastmcp";
|
|
2
|
+
/**
|
|
3
|
+
* Create an OAuth auth provider for use with FastMCP HTTP transport.
|
|
4
|
+
* Supports Google, GitHub, CyberArk Identity, and custom OAuth providers.
|
|
5
|
+
*/
|
|
6
|
+
export function createAuthProvider(options) {
|
|
7
|
+
const { provider, baseUrl, clientId, clientSecret } = options;
|
|
8
|
+
switch (provider) {
|
|
9
|
+
case "google":
|
|
10
|
+
return new GoogleProvider({
|
|
11
|
+
clientId,
|
|
12
|
+
clientSecret,
|
|
13
|
+
baseUrl,
|
|
14
|
+
scopes: ["openid", "email"],
|
|
15
|
+
// consentRequired left at the provider default so Google shows its
|
|
16
|
+
// consent screen on first-time grants. Disabling it (0.2.x did) raised
|
|
17
|
+
// silent-grant / phishing risk for a server holding financial data.
|
|
18
|
+
...(options.tokenStorage && { tokenStorage: options.tokenStorage }),
|
|
19
|
+
...(options.encryptionKey !== undefined && { encryptionKey: options.encryptionKey }),
|
|
20
|
+
});
|
|
21
|
+
case "github":
|
|
22
|
+
return new GitHubProvider({
|
|
23
|
+
clientId,
|
|
24
|
+
clientSecret,
|
|
25
|
+
baseUrl,
|
|
26
|
+
scopes: ["read:user", "user:email"],
|
|
27
|
+
...(options.tokenStorage && { tokenStorage: options.tokenStorage }),
|
|
28
|
+
...(options.encryptionKey !== undefined && { encryptionKey: options.encryptionKey }),
|
|
29
|
+
});
|
|
30
|
+
case "cyberark": {
|
|
31
|
+
const tenantUrl = options.cyberarkTenantUrl;
|
|
32
|
+
if (!tenantUrl) {
|
|
33
|
+
throw new Error("cyberarkTenantUrl is required for CyberArk Identity OAuth");
|
|
34
|
+
}
|
|
35
|
+
return new OAuthProvider({
|
|
36
|
+
clientId,
|
|
37
|
+
clientSecret,
|
|
38
|
+
baseUrl,
|
|
39
|
+
authorizationEndpoint: `${tenantUrl}/oauth2/authorize`,
|
|
40
|
+
tokenEndpoint: `${tenantUrl}/oauth2/token`,
|
|
41
|
+
scopes: ["openid", "email", "profile"],
|
|
42
|
+
...(options.tokenStorage && { tokenStorage: options.tokenStorage }),
|
|
43
|
+
...(options.encryptionKey !== undefined && { encryptionKey: options.encryptionKey }),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
case "custom": {
|
|
47
|
+
if (!options.authorizationEndpoint || !options.tokenEndpoint) {
|
|
48
|
+
throw new Error("authorizationEndpoint and tokenEndpoint are required for custom OAuth");
|
|
49
|
+
}
|
|
50
|
+
return new OAuthProvider({
|
|
51
|
+
clientId,
|
|
52
|
+
clientSecret,
|
|
53
|
+
baseUrl,
|
|
54
|
+
authorizationEndpoint: options.authorizationEndpoint,
|
|
55
|
+
tokenEndpoint: options.tokenEndpoint,
|
|
56
|
+
scopes: options.scopes || ["openid", "email"],
|
|
57
|
+
...(options.tokenStorage && { tokenStorage: options.tokenStorage }),
|
|
58
|
+
...(options.encryptionKey !== undefined && { encryptionKey: options.encryptionKey }),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
default:
|
|
62
|
+
throw new Error(`Unknown auth provider: ${provider}. Supported: google, github, cyberark, custom`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Read OAuth credentials from environment variables for the given provider.
|
|
67
|
+
* Throws if required env vars are missing.
|
|
68
|
+
*/
|
|
69
|
+
export function getAuthCredentialsFromEnv(provider) {
|
|
70
|
+
switch (provider) {
|
|
71
|
+
case "google": {
|
|
72
|
+
const clientId = process.env.GOOGLE_CLIENT_ID;
|
|
73
|
+
const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
|
|
74
|
+
if (!clientId || !clientSecret) {
|
|
75
|
+
throw new Error("GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET environment variables are required for Google OAuth");
|
|
76
|
+
}
|
|
77
|
+
return { clientId, clientSecret };
|
|
78
|
+
}
|
|
79
|
+
case "github": {
|
|
80
|
+
const clientId = process.env.GITHUB_CLIENT_ID;
|
|
81
|
+
const clientSecret = process.env.GITHUB_CLIENT_SECRET;
|
|
82
|
+
if (!clientId || !clientSecret) {
|
|
83
|
+
throw new Error("GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET environment variables are required for GitHub OAuth");
|
|
84
|
+
}
|
|
85
|
+
return { clientId, clientSecret };
|
|
86
|
+
}
|
|
87
|
+
case "cyberark": {
|
|
88
|
+
const tenantUrl = process.env.CYBERARK_TENANT_URL;
|
|
89
|
+
const clientId = process.env.CYBERARK_CLIENT_ID || process.env.OAUTH_CLIENT_ID;
|
|
90
|
+
const clientSecret = process.env.CYBERARK_CLIENT_SECRET || process.env.OAUTH_CLIENT_SECRET;
|
|
91
|
+
if (!tenantUrl || !clientId || !clientSecret) {
|
|
92
|
+
throw new Error("CYBERARK_TENANT_URL, CYBERARK_CLIENT_ID (or OAUTH_CLIENT_ID), and CYBERARK_CLIENT_SECRET (or OAUTH_CLIENT_SECRET) are required for CyberArk Identity OAuth");
|
|
93
|
+
}
|
|
94
|
+
return { clientId, clientSecret, cyberarkTenantUrl: tenantUrl };
|
|
95
|
+
}
|
|
96
|
+
case "custom": {
|
|
97
|
+
const authorizationEndpoint = process.env.OAUTH_AUTH_URL;
|
|
98
|
+
const tokenEndpoint = process.env.OAUTH_TOKEN_URL;
|
|
99
|
+
const clientId = process.env.OAUTH_CLIENT_ID;
|
|
100
|
+
const clientSecret = process.env.OAUTH_CLIENT_SECRET;
|
|
101
|
+
const scopes = process.env.OAUTH_SCOPES?.split(",") || undefined;
|
|
102
|
+
if (!authorizationEndpoint || !tokenEndpoint || !clientId || !clientSecret) {
|
|
103
|
+
throw new Error("OAUTH_AUTH_URL, OAUTH_TOKEN_URL, OAUTH_CLIENT_ID, and OAUTH_CLIENT_SECRET are required for custom OAuth");
|
|
104
|
+
}
|
|
105
|
+
return { clientId, clientSecret, authorizationEndpoint, tokenEndpoint, scopes };
|
|
106
|
+
}
|
|
107
|
+
default:
|
|
108
|
+
throw new Error(`Unknown auth provider: ${provider}. Supported: google, github, cyberark, custom`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=auth-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-provider.js","sourceRoot":"","sources":["../src/auth-provider.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { type AuthProviderType } from "./auth-provider.js";
|
|
3
|
+
export interface CLIOptions {
|
|
4
|
+
mode: "stdio" | "http" | "setup" | "version";
|
|
5
|
+
port: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function parseArgs(argv: string[]): CLIOptions;
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the auth provider type from the AUTH_PROVIDER env var.
|
|
10
|
+
* Defaults to 'google' if not set. Throws if invalid.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveAuthProvider(): AuthProviderType;
|
|
13
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAIA,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAK5B,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAsCpD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAStD"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createServer, startServer } from "./server.js";
|
|
3
|
+
import { runSetupWizard } from "./setup.js";
|
|
4
|
+
import { createAuthProvider, getAuthCredentialsFromEnv, } from "./auth-provider.js";
|
|
5
|
+
import { CredentialStore } from "./credential-store.js";
|
|
6
|
+
import { createSessionStore } from "./session-store.js";
|
|
7
|
+
import { createRequire } from "module";
|
|
8
|
+
export function parseArgs(argv) {
|
|
9
|
+
const args = argv.slice(2); // skip node and script path
|
|
10
|
+
// Check for --version
|
|
11
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
12
|
+
return { mode: "version", port: 8080 };
|
|
13
|
+
}
|
|
14
|
+
// Check for setup command
|
|
15
|
+
if (args.includes("setup")) {
|
|
16
|
+
return { mode: "setup", port: 8080 };
|
|
17
|
+
}
|
|
18
|
+
// Check for --http flag
|
|
19
|
+
const isHttp = args.includes("--http");
|
|
20
|
+
// Check for --port flag
|
|
21
|
+
let port = 8080;
|
|
22
|
+
const portIndex = args.indexOf("--port");
|
|
23
|
+
if (portIndex !== -1 && portIndex + 1 < args.length) {
|
|
24
|
+
const parsedPort = parseInt(args[portIndex + 1], 10);
|
|
25
|
+
if (!isNaN(parsedPort) && parsedPort > 0 && parsedPort <= 65535) {
|
|
26
|
+
port = parsedPort;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Also check PORT env var if --port not specified on CLI
|
|
30
|
+
if (portIndex === -1 && process.env.PORT) {
|
|
31
|
+
const envPort = parseInt(process.env.PORT, 10);
|
|
32
|
+
if (!isNaN(envPort) && envPort > 0 && envPort <= 65535) {
|
|
33
|
+
port = envPort;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
mode: isHttp ? "http" : "stdio",
|
|
38
|
+
port,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the auth provider type from the AUTH_PROVIDER env var.
|
|
43
|
+
* Defaults to 'google' if not set. Throws if invalid.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveAuthProvider() {
|
|
46
|
+
const providerEnv = process.env.AUTH_PROVIDER || "google";
|
|
47
|
+
const valid = ["google", "github", "cyberark", "custom"];
|
|
48
|
+
if (!valid.includes(providerEnv)) {
|
|
49
|
+
throw new Error(`Invalid AUTH_PROVIDER="${providerEnv}". Supported: ${valid.join(", ")}`);
|
|
50
|
+
}
|
|
51
|
+
return providerEnv;
|
|
52
|
+
}
|
|
53
|
+
async function main() {
|
|
54
|
+
const options = parseArgs(process.argv);
|
|
55
|
+
switch (options.mode) {
|
|
56
|
+
case "version": {
|
|
57
|
+
const require = createRequire(import.meta.url);
|
|
58
|
+
const pkg = require("../package.json");
|
|
59
|
+
console.log(`lunchmoney-mcp v${pkg.version}`);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
case "setup": {
|
|
63
|
+
await runSetupWizard();
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case "http": {
|
|
67
|
+
// HTTP mode requires OAuth
|
|
68
|
+
const providerType = resolveAuthProvider();
|
|
69
|
+
const envConfig = getAuthCredentialsFromEnv(providerType);
|
|
70
|
+
const baseUrl = process.env.BASE_URL || `http://localhost:${options.port}`;
|
|
71
|
+
// Create encrypted session store for persisting OAuth tokens across restarts
|
|
72
|
+
const credentialStore = new CredentialStore();
|
|
73
|
+
const tokenStorage = await createSessionStore(credentialStore);
|
|
74
|
+
const auth = createAuthProvider({
|
|
75
|
+
provider: providerType,
|
|
76
|
+
baseUrl,
|
|
77
|
+
clientId: envConfig.clientId,
|
|
78
|
+
clientSecret: envConfig.clientSecret,
|
|
79
|
+
cyberarkTenantUrl: envConfig.cyberarkTenantUrl,
|
|
80
|
+
authorizationEndpoint: envConfig.authorizationEndpoint,
|
|
81
|
+
tokenEndpoint: envConfig.tokenEndpoint,
|
|
82
|
+
scopes: envConfig.scopes,
|
|
83
|
+
tokenStorage,
|
|
84
|
+
// Disable FastMCP's built-in encryption since EncryptedTokenStorage already handles it
|
|
85
|
+
encryptionKey: false,
|
|
86
|
+
});
|
|
87
|
+
const server = await createServer({ auth, health: true });
|
|
88
|
+
await startServer(server, "httpStream", options.port, providerType);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case "stdio":
|
|
92
|
+
default: {
|
|
93
|
+
const server = await createServer();
|
|
94
|
+
await startServer(server, "stdio");
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
main().catch((error) => {
|
|
100
|
+
console.error("Fatal error:", error.message || error);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare class CredentialStore {
|
|
2
|
+
getApiToken(): Promise<string | null>;
|
|
3
|
+
setApiToken(token: string): Promise<void>;
|
|
4
|
+
deleteApiToken(): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the AES-256-GCM encryption key for the session store.
|
|
7
|
+
*
|
|
8
|
+
* Resolution order:
|
|
9
|
+
* 1. OS keychain (generated and persisted on first use).
|
|
10
|
+
* 2. `ENCRYPTION_KEY` env var, validated as exactly 64 lowercase hex
|
|
11
|
+
* characters (32 bytes). An invalid value is a hard error.
|
|
12
|
+
* 3. Ephemeral random key — only allowed when `requirePersistent` is
|
|
13
|
+
* false (stdio mode, which has no persisted sessions). In HTTP/OAuth
|
|
14
|
+
* mode we refuse to start rather than silently invalidate every
|
|
15
|
+
* stored session on the next restart.
|
|
16
|
+
*
|
|
17
|
+
* @param requirePersistent - true in HTTP/OAuth mode, where an ephemeral
|
|
18
|
+
* key would silently drop all persisted sessions on restart.
|
|
19
|
+
*/
|
|
20
|
+
getEncryptionKey({ requirePersistent }?: {
|
|
21
|
+
requirePersistent?: boolean | undefined;
|
|
22
|
+
}): Promise<string>;
|
|
23
|
+
clear(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=credential-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-store.d.ts","sourceRoot":"","sources":["../src/credential-store.ts"],"names":[],"mappings":"AAIA,qBAAa,eAAe;IACpB,WAAW,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAYrC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAQrC;;;;;;;;;;;;;;OAcG;IACG,gBAAgB,CAAC,EAAE,iBAAyB,EAAE;;KAAK,GAAG,OAAO,CAAC,MAAM,CAAC;IA2CrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import keytar from 'keytar';
|
|
2
|
+
const SERVICE_NAME = 'lunchmoney-mcp';
|
|
3
|
+
export class CredentialStore {
|
|
4
|
+
async getApiToken() {
|
|
5
|
+
// Try keychain first
|
|
6
|
+
try {
|
|
7
|
+
const token = await keytar.getPassword(SERVICE_NAME, 'api-token');
|
|
8
|
+
if (token)
|
|
9
|
+
return token;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
// Keychain unavailable (Docker, CI, etc.)
|
|
13
|
+
}
|
|
14
|
+
// Fall back to ENV var
|
|
15
|
+
return process.env.LUNCH_MONEY_API_TOKEN || null;
|
|
16
|
+
}
|
|
17
|
+
async setApiToken(token) {
|
|
18
|
+
try {
|
|
19
|
+
await keytar.setPassword(SERVICE_NAME, 'api-token', token);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw new Error('Failed to store token in keychain. Use LUNCH_MONEY_API_TOKEN env var instead.');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async deleteApiToken() {
|
|
26
|
+
try {
|
|
27
|
+
await keytar.deletePassword(SERVICE_NAME, 'api-token');
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Ignore if keychain unavailable
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Resolve the AES-256-GCM encryption key for the session store.
|
|
35
|
+
*
|
|
36
|
+
* Resolution order:
|
|
37
|
+
* 1. OS keychain (generated and persisted on first use).
|
|
38
|
+
* 2. `ENCRYPTION_KEY` env var, validated as exactly 64 lowercase hex
|
|
39
|
+
* characters (32 bytes). An invalid value is a hard error.
|
|
40
|
+
* 3. Ephemeral random key — only allowed when `requirePersistent` is
|
|
41
|
+
* false (stdio mode, which has no persisted sessions). In HTTP/OAuth
|
|
42
|
+
* mode we refuse to start rather than silently invalidate every
|
|
43
|
+
* stored session on the next restart.
|
|
44
|
+
*
|
|
45
|
+
* @param requirePersistent - true in HTTP/OAuth mode, where an ephemeral
|
|
46
|
+
* key would silently drop all persisted sessions on restart.
|
|
47
|
+
*/
|
|
48
|
+
async getEncryptionKey({ requirePersistent = false } = {}) {
|
|
49
|
+
try {
|
|
50
|
+
let key = await keytar.getPassword(SERVICE_NAME, 'encryption-key');
|
|
51
|
+
if (!key) {
|
|
52
|
+
// Generate and store a new key
|
|
53
|
+
const crypto = await import('crypto');
|
|
54
|
+
key = crypto.randomBytes(32).toString('hex');
|
|
55
|
+
await keytar.setPassword(SERVICE_NAME, 'encryption-key', key);
|
|
56
|
+
}
|
|
57
|
+
return key;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
// Keychain unavailable (Docker, CI, headless). Surface it instead of
|
|
61
|
+
// swallowing — a silent fall-through here is how sessions vanish.
|
|
62
|
+
console.error(`[lunchmoney-mcp] OS keychain unavailable for the encryption key (${error.message}). Falling back to the ENCRYPTION_KEY env var.`);
|
|
63
|
+
}
|
|
64
|
+
const envKey = process.env.ENCRYPTION_KEY;
|
|
65
|
+
if (envKey !== undefined) {
|
|
66
|
+
if (!/^[0-9a-f]{64}$/.test(envKey)) {
|
|
67
|
+
throw new Error('ENCRYPTION_KEY must be exactly 64 lowercase hex characters (32 bytes). Generate one with: openssl rand -hex 32');
|
|
68
|
+
}
|
|
69
|
+
return envKey;
|
|
70
|
+
}
|
|
71
|
+
if (requirePersistent) {
|
|
72
|
+
throw new Error('No encryption key available: the OS keychain is unavailable and ENCRYPTION_KEY is not set. ' +
|
|
73
|
+
'Refusing to start in HTTP/OAuth mode because an ephemeral key would silently invalidate every ' +
|
|
74
|
+
'stored session on restart. Set ENCRYPTION_KEY (openssl rand -hex 32).');
|
|
75
|
+
}
|
|
76
|
+
// stdio mode: no persisted sessions, so an ephemeral key is acceptable.
|
|
77
|
+
const crypto = await import('crypto');
|
|
78
|
+
return crypto.randomBytes(32).toString('hex');
|
|
79
|
+
}
|
|
80
|
+
async clear() {
|
|
81
|
+
try {
|
|
82
|
+
await keytar.deletePassword(SERVICE_NAME, 'api-token');
|
|
83
|
+
await keytar.deletePassword(SERVICE_NAME, 'encryption-key');
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Ignore
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=credential-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../src/credential-store.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { createServer, startServer } from "./server.js";
|
|
2
|
+
export type { CreateServerOptions, AuthProviderInstance } from "./server.js";
|
|
3
|
+
export { CredentialStore } from "./credential-store.js";
|
|
4
|
+
export { LunchMoneyClient } from "./api/client.js";
|
|
5
|
+
export { runSetupWizard } from "./setup.js";
|
|
6
|
+
export { createAuthProvider, getAuthCredentialsFromEnv } from "./auth-provider.js";
|
|
7
|
+
export type { AuthProviderType, AuthProviderOptions } from "./auth-provider.js";
|
|
8
|
+
export { createSessionStore, getDataDirectory } from "./session-store.js";
|
|
9
|
+
export type { CreateSessionStoreOptions } from "./session-store.js";
|
|
10
|
+
export * from "./types/index.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AACnF,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,YAAY,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AACpE,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { createServer, startServer } from "./server.js";
|
|
2
|
+
export { CredentialStore } from "./credential-store.js";
|
|
3
|
+
export { LunchMoneyClient } from "./api/client.js";
|
|
4
|
+
export { runSetupWizard } from "./setup.js";
|
|
5
|
+
export { createAuthProvider, getAuthCredentialsFromEnv } from "./auth-provider.js";
|
|
6
|
+
export { createSessionStore, getDataDirectory } from "./session-store.js";
|
|
7
|
+
export * from "./types/index.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAEnF,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE1E,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const transactionFilterSchema: z.ZodObject<{
|
|
3
|
+
start_date: z.ZodOptional<z.ZodString>;
|
|
4
|
+
end_date: z.ZodOptional<z.ZodString>;
|
|
5
|
+
category_id: z.ZodOptional<z.ZodNumber>;
|
|
6
|
+
tag_id: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
account_id: z.ZodOptional<z.ZodNumber>;
|
|
8
|
+
debit_as_negative: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
pending: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
11
|
+
cleared: "cleared";
|
|
12
|
+
uncleared: "uncleared";
|
|
13
|
+
recurring: "recurring";
|
|
14
|
+
recurring_suggested: "recurring_suggested";
|
|
15
|
+
}>>;
|
|
16
|
+
offset: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
export declare const createCategorySchema: z.ZodObject<{
|
|
20
|
+
name: z.ZodString;
|
|
21
|
+
description: z.ZodOptional<z.ZodString>;
|
|
22
|
+
is_income: z.ZodOptional<z.ZodBoolean>;
|
|
23
|
+
exclude_budget: z.ZodOptional<z.ZodBoolean>;
|
|
24
|
+
exclude_from_totals: z.ZodOptional<z.ZodBoolean>;
|
|
25
|
+
category_group_id: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
parent_category_id: z.ZodOptional<z.ZodNumber>;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
export declare const updateCategorySchema: z.ZodObject<{
|
|
29
|
+
name: z.ZodOptional<z.ZodString>;
|
|
30
|
+
description: z.ZodOptional<z.ZodString>;
|
|
31
|
+
is_income: z.ZodOptional<z.ZodBoolean>;
|
|
32
|
+
exclude_budget: z.ZodOptional<z.ZodBoolean>;
|
|
33
|
+
exclude_from_totals: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
archived: z.ZodOptional<z.ZodBoolean>;
|
|
35
|
+
category_group_id: z.ZodOptional<z.ZodNumber>;
|
|
36
|
+
parent_category_id: z.ZodOptional<z.ZodNumber>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
export declare const createTagSchema: z.ZodObject<{
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
}, z.core.$strip>;
|
|
41
|
+
export declare const updateTagSchema: z.ZodObject<{
|
|
42
|
+
name: z.ZodString;
|
|
43
|
+
}, z.core.$strip>;
|
|
44
|
+
export declare const createTransactionSchema: z.ZodObject<{
|
|
45
|
+
date: z.ZodString;
|
|
46
|
+
amount: z.ZodString;
|
|
47
|
+
payee: z.ZodOptional<z.ZodString>;
|
|
48
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
49
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
50
|
+
category_id: z.ZodOptional<z.ZodNumber>;
|
|
51
|
+
account_id: z.ZodNumber;
|
|
52
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
53
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
54
|
+
cleared: "cleared";
|
|
55
|
+
uncleared: "uncleared";
|
|
56
|
+
}>>;
|
|
57
|
+
external_id: z.ZodOptional<z.ZodString>;
|
|
58
|
+
original_name: z.ZodOptional<z.ZodString>;
|
|
59
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
60
|
+
expense: "expense";
|
|
61
|
+
income: "income";
|
|
62
|
+
transfer: "transfer";
|
|
63
|
+
}>>;
|
|
64
|
+
}, z.core.$strip>;
|
|
65
|
+
export declare const updateTransactionSchema: z.ZodObject<{
|
|
66
|
+
date: z.ZodOptional<z.ZodString>;
|
|
67
|
+
amount: z.ZodOptional<z.ZodString>;
|
|
68
|
+
payee: z.ZodOptional<z.ZodString>;
|
|
69
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
70
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
71
|
+
category_id: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
72
|
+
account_id: z.ZodOptional<z.ZodNumber>;
|
|
73
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
74
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
75
|
+
cleared: "cleared";
|
|
76
|
+
uncleared: "uncleared";
|
|
77
|
+
}>>;
|
|
78
|
+
external_id: z.ZodOptional<z.ZodString>;
|
|
79
|
+
original_name: z.ZodOptional<z.ZodString>;
|
|
80
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
81
|
+
expense: "expense";
|
|
82
|
+
income: "income";
|
|
83
|
+
transfer: "transfer";
|
|
84
|
+
}>>;
|
|
85
|
+
}, z.core.$strip>;
|
|
86
|
+
export declare const bulkUpdateTransactionsSchema: z.ZodObject<{
|
|
87
|
+
transaction_ids: z.ZodArray<z.ZodNumber>;
|
|
88
|
+
category_id: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
89
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
90
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
91
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
92
|
+
cleared: "cleared";
|
|
93
|
+
uncleared: "uncleared";
|
|
94
|
+
}>>;
|
|
95
|
+
}, z.core.$strip>;
|
|
96
|
+
export declare const createRecurringItemSchema: z.ZodObject<{
|
|
97
|
+
payee: z.ZodOptional<z.ZodString>;
|
|
98
|
+
amount: z.ZodString;
|
|
99
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
100
|
+
category_id: z.ZodOptional<z.ZodNumber>;
|
|
101
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
102
|
+
account_id: z.ZodOptional<z.ZodNumber>;
|
|
103
|
+
tag_id: z.ZodOptional<z.ZodNumber>;
|
|
104
|
+
frequency: z.ZodOptional<z.ZodString>;
|
|
105
|
+
flow: z.ZodOptional<z.ZodEnum<{
|
|
106
|
+
inflow: "inflow";
|
|
107
|
+
outflow: "outflow";
|
|
108
|
+
}>>;
|
|
109
|
+
start_date: z.ZodOptional<z.ZodString>;
|
|
110
|
+
end_date: z.ZodOptional<z.ZodString>;
|
|
111
|
+
}, z.core.$strip>;
|
|
112
|
+
export declare const updateRecurringItemSchema: z.ZodObject<{
|
|
113
|
+
payee: z.ZodOptional<z.ZodString>;
|
|
114
|
+
amount: z.ZodOptional<z.ZodString>;
|
|
115
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
116
|
+
category_id: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
117
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
118
|
+
account_id: z.ZodOptional<z.ZodNumber>;
|
|
119
|
+
tag_id: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
120
|
+
frequency: z.ZodOptional<z.ZodString>;
|
|
121
|
+
flow: z.ZodOptional<z.ZodEnum<{
|
|
122
|
+
inflow: "inflow";
|
|
123
|
+
outflow: "outflow";
|
|
124
|
+
}>>;
|
|
125
|
+
start_date: z.ZodOptional<z.ZodString>;
|
|
126
|
+
end_date: z.ZodOptional<z.ZodString>;
|
|
127
|
+
}, z.core.$strip>;
|
|
128
|
+
export declare const createBudgetSchema: z.ZodObject<{
|
|
129
|
+
category_id: z.ZodOptional<z.ZodNumber>;
|
|
130
|
+
amount: z.ZodString;
|
|
131
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
132
|
+
start_date: z.ZodString;
|
|
133
|
+
end_date: z.ZodString;
|
|
134
|
+
}, z.core.$strip>;
|
|
135
|
+
export declare const updateBudgetSchema: z.ZodObject<{
|
|
136
|
+
category_id: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
137
|
+
amount: z.ZodOptional<z.ZodString>;
|
|
138
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
139
|
+
start_date: z.ZodOptional<z.ZodString>;
|
|
140
|
+
end_date: z.ZodOptional<z.ZodString>;
|
|
141
|
+
}, z.core.$strip>;
|
|
142
|
+
export declare const createAssetSchema: z.ZodObject<{
|
|
143
|
+
type_name: z.ZodString;
|
|
144
|
+
type_name_override: z.ZodOptional<z.ZodString>;
|
|
145
|
+
name: z.ZodString;
|
|
146
|
+
balance: z.ZodString;
|
|
147
|
+
balance_as_of: z.ZodOptional<z.ZodString>;
|
|
148
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
149
|
+
institution_name: z.ZodOptional<z.ZodString>;
|
|
150
|
+
}, z.core.$strip>;
|
|
151
|
+
export declare const updateAssetSchema: z.ZodObject<{
|
|
152
|
+
type_name: z.ZodOptional<z.ZodString>;
|
|
153
|
+
type_name_override: z.ZodOptional<z.ZodString>;
|
|
154
|
+
name: z.ZodOptional<z.ZodString>;
|
|
155
|
+
balance: z.ZodOptional<z.ZodString>;
|
|
156
|
+
balance_as_of: z.ZodOptional<z.ZodString>;
|
|
157
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
158
|
+
institution_name: z.ZodOptional<z.ZodString>;
|
|
159
|
+
}, z.core.$strip>;
|
|
160
|
+
export declare const createTransactionGroupSchema: z.ZodObject<{
|
|
161
|
+
date: z.ZodString;
|
|
162
|
+
payee: z.ZodString;
|
|
163
|
+
transactions: z.ZodArray<z.ZodNumber>;
|
|
164
|
+
category_id: z.ZodOptional<z.ZodNumber>;
|
|
165
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
166
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
167
|
+
}, z.core.$strip>;
|
|
168
|
+
export declare const unsplitTransactionsSchema: z.ZodObject<{
|
|
169
|
+
parent_ids: z.ZodArray<z.ZodNumber>;
|
|
170
|
+
remove_parents: z.ZodOptional<z.ZodBoolean>;
|
|
171
|
+
}, z.core.$strip>;
|
|
172
|
+
export declare const createCategoryGroupSchema: z.ZodObject<{
|
|
173
|
+
name: z.ZodString;
|
|
174
|
+
description: z.ZodOptional<z.ZodString>;
|
|
175
|
+
is_income: z.ZodOptional<z.ZodBoolean>;
|
|
176
|
+
exclude_from_budget: z.ZodOptional<z.ZodBoolean>;
|
|
177
|
+
exclude_from_totals: z.ZodOptional<z.ZodBoolean>;
|
|
178
|
+
category_ids: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
179
|
+
new_categories: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
180
|
+
}, z.core.$strip>;
|
|
181
|
+
export declare const addToGroupSchema: z.ZodObject<{
|
|
182
|
+
group_id: z.ZodNumber;
|
|
183
|
+
category_ids: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
184
|
+
new_categories: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
185
|
+
}, z.core.$strip>;
|
|
186
|
+
export declare const idSchema: z.ZodObject<{
|
|
187
|
+
id: z.ZodNumber;
|
|
188
|
+
}, z.core.$strip>;
|
|
189
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;iBAWlC,CAAC;AAGH,eAAO,MAAM,oBAAoB;;;;;;;;iBAQ/B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;iBAS/B,CAAC;AAGH,eAAO,MAAM,eAAe;;iBAE1B,CAAC;AAEH,eAAO,MAAM,eAAe;;iBAE1B,CAAC;AAGH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;iBAalC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;iBAalC,CAAC;AAEH,eAAO,MAAM,4BAA4B;;;;;;;;;iBAMvC,CAAC;AAGH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;iBAYpC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;iBAYpC,CAAC;AAGH,eAAO,MAAM,kBAAkB;;;;;;iBAM7B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;iBAM7B,CAAC;AAGH,eAAO,MAAM,iBAAiB;;;;;;;;iBAQ5B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;iBAQ5B,CAAC;AAGH,eAAO,MAAM,4BAA4B;;;;;;;iBAOvC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;iBAGpC,CAAC;AAGH,eAAO,MAAM,yBAAyB;;;;;;;;iBAQpC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;iBAI3B,CAAC;AAGH,eAAO,MAAM,QAAQ;;iBAEnB,CAAC"}
|