ynab-cli-rs 0.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.
Files changed (4) hide show
  1. package/README.md +66 -0
  2. package/bin/ynab +8 -0
  3. package/install.js +101 -0
  4. package/package.json +37 -0
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # ynab-cli-rs
2
+
3
+ Command-line interface and MCP server for the [YNAB](https://www.ynab.com) (You Need A Budget) API. Built in Rust, distributed as a single binary.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g ynab-cli-rs
9
+ ```
10
+
11
+ Or run directly:
12
+
13
+ ```bash
14
+ npx ynab-cli-rs --help
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # Authenticate with your YNAB personal access token
21
+ ynab auth login --pat
22
+
23
+ # List your budgets
24
+ ynab plans list
25
+
26
+ # Set a default budget so you don't need --plan-id every time
27
+ ynab plans set-default <PLAN_ID>
28
+
29
+ # List transactions
30
+ ynab transactions list
31
+ ```
32
+
33
+ ## MCP Server
34
+
35
+ Start the MCP server for AI agent integration:
36
+
37
+ ```bash
38
+ ynab mcp
39
+ ```
40
+
41
+ Configure in Claude Desktop:
42
+
43
+ ```json
44
+ {
45
+ "mcpServers": {
46
+ "ynab": {
47
+ "command": "ynab",
48
+ "args": ["mcp"],
49
+ "env": {
50
+ "YNAB_ACCESS_TOKEN": "your-token-here"
51
+ }
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ ## Supported Platforms
58
+
59
+ - macOS (Intel and Apple Silicon)
60
+ - Linux (x64 and ARM64)
61
+
62
+ ## Links
63
+
64
+ - [GitHub Repository](https://github.com/0xdecaf/ynab-cli)
65
+ - [YNAB API Documentation](https://api.ynab.com)
66
+ - [Get a Personal Access Token](https://app.ynab.com/settings/developer)
package/bin/ynab ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ console.error(
4
+ "ynab binary not found. The postinstall script may not have run.\n" +
5
+ "Try: npm rebuild ynab-cli-rs\n" +
6
+ "Or install manually: https://github.com/0xdecaf/ynab-cli/releases"
7
+ );
8
+ process.exit(1);
package/install.js ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ const https = require("https");
6
+ const fs = require("fs");
7
+ const path = require("path");
8
+ const { execSync } = require("child_process");
9
+
10
+ const REPO = "0xdecaf/ynab-cli";
11
+ const BINARY_NAME = "ynab";
12
+
13
+ const PLATFORM_MAP = {
14
+ "darwin-x64": "x86_64-apple-darwin",
15
+ "darwin-arm64": "aarch64-apple-darwin",
16
+ "linux-x64": "x86_64-unknown-linux-gnu",
17
+ "linux-arm64": "aarch64-unknown-linux-gnu",
18
+ };
19
+
20
+ function getTarget() {
21
+ const key = `${process.platform}-${process.arch}`;
22
+ const target = PLATFORM_MAP[key];
23
+ if (!target) {
24
+ console.error(
25
+ `Unsupported platform: ${process.platform} ${process.arch}\n` +
26
+ `Supported: macOS (x64, arm64), Linux (x64, arm64)`
27
+ );
28
+ process.exit(1);
29
+ }
30
+ return target;
31
+ }
32
+
33
+ function getVersion() {
34
+ const pkg = JSON.parse(
35
+ fs.readFileSync(path.join(__dirname, "package.json"), "utf8")
36
+ );
37
+ return pkg.version;
38
+ }
39
+
40
+ function download(url) {
41
+ return new Promise((resolve, reject) => {
42
+ https
43
+ .get(url, (res) => {
44
+ // Follow redirects (GitHub releases redirect to S3)
45
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
46
+ return download(res.headers.location).then(resolve, reject);
47
+ }
48
+ if (res.statusCode !== 200) {
49
+ reject(new Error(`Download failed: HTTP ${res.statusCode} from ${url}`));
50
+ return;
51
+ }
52
+ const chunks = [];
53
+ res.on("data", (chunk) => chunks.push(chunk));
54
+ res.on("end", () => resolve(Buffer.concat(chunks)));
55
+ res.on("error", reject);
56
+ })
57
+ .on("error", reject);
58
+ });
59
+ }
60
+
61
+ async function install() {
62
+ const target = getTarget();
63
+ const version = getVersion();
64
+ const tarball = `ynab-cli-${target}.tar.gz`;
65
+ const url = `https://github.com/${REPO}/releases/download/v${version}/${tarball}`;
66
+
67
+ const binDir = path.join(__dirname, "bin");
68
+ const binPath = path.join(binDir, BINARY_NAME);
69
+ const tmpTarball = path.join(__dirname, tarball);
70
+
71
+ console.log(`Downloading ynab v${version} for ${target}...`);
72
+
73
+ try {
74
+ const data = await download(url);
75
+
76
+ // Write tarball to temp file
77
+ fs.writeFileSync(tmpTarball, data);
78
+
79
+ // Ensure bin directory exists
80
+ fs.mkdirSync(binDir, { recursive: true });
81
+
82
+ // Extract binary from tarball
83
+ execSync(`tar xzf "${tmpTarball}" -C "${binDir}"`, { stdio: "pipe" });
84
+
85
+ // Make binary executable
86
+ fs.chmodSync(binPath, 0o755);
87
+
88
+ // Clean up tarball
89
+ fs.unlinkSync(tmpTarball);
90
+
91
+ console.log(`Installed ynab to ${binPath}`);
92
+ } catch (err) {
93
+ console.error(`Failed to install ynab: ${err.message}`);
94
+ console.error(
95
+ `\nYou can manually download from:\n https://github.com/${REPO}/releases/tag/v${version}`
96
+ );
97
+ process.exit(1);
98
+ }
99
+ }
100
+
101
+ install();
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "ynab-cli-rs",
3
+ "version": "0.1.0",
4
+ "description": "YNAB CLI — command-line interface and MCP server for the YNAB API (Rust)",
5
+ "bin": {
6
+ "ynab": "bin/ynab"
7
+ },
8
+ "scripts": {
9
+ "postinstall": "node install.js"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/0xdecaf/ynab-cli.git"
14
+ },
15
+ "publishConfig": {
16
+ "provenance": true
17
+ },
18
+ "keywords": [
19
+ "ynab",
20
+ "budget",
21
+ "cli",
22
+ "mcp",
23
+ "finance"
24
+ ],
25
+ "license": "MIT",
26
+ "engines": {
27
+ "node": ">=14"
28
+ },
29
+ "os": [
30
+ "darwin",
31
+ "linux"
32
+ ],
33
+ "cpu": [
34
+ "x64",
35
+ "arm64"
36
+ ]
37
+ }