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.
- package/README.md +66 -0
- package/bin/ynab +8 -0
- package/install.js +101 -0
- 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
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
|
+
}
|