takumi-cli 1.2.3 → 1.2.7
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 +42 -6
- package/bin/takumi-mcp +58 -0
- package/commands/mcp-config.sh +8 -11
- package/mcp/server.js +15 -2
- package/package.json +3 -2
- package/test.sh +40 -0
package/README.md
CHANGED
|
@@ -89,15 +89,51 @@ takumi info ./videos
|
|
|
89
89
|
|
|
90
90
|
takumi includes an MCP server so AI clients like Claude Code and Kiro can use all commands as tools. No syntax to remember, just describe what you want.
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
Run `takumi mcp-config` to get the config block for your client, or copy from below.
|
|
93
|
+
|
|
94
|
+
### VS Code
|
|
95
|
+
|
|
96
|
+
Create or edit `.vscode/mcp.json` in your project:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"servers": {
|
|
101
|
+
"takumi": {
|
|
102
|
+
"command": "takumi-mcp"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
94
106
|
```
|
|
95
107
|
|
|
96
|
-
|
|
108
|
+
### Claude Code
|
|
109
|
+
|
|
110
|
+
Add to `~/.claude.json` or create `.mcp.json` in your project root:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"mcpServers": {
|
|
115
|
+
"takumi": {
|
|
116
|
+
"command": "takumi-mcp"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Kiro
|
|
123
|
+
|
|
124
|
+
Create or edit `.kiro/settings/mcp.json` in your project:
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"mcpServers": {
|
|
129
|
+
"takumi": {
|
|
130
|
+
"command": "takumi-mcp"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
97
135
|
|
|
98
|
-
|
|
99
|
-
- **Claude Code:** `~/.claude.json` or project `.mcp.json` (uses `"mcpServers"`)
|
|
100
|
-
- **Kiro:** `.kiro/settings/mcp.json` (uses `"mcpServers"`)
|
|
136
|
+
> **Note:** If your editor can't find `takumi-mcp`, use the full path from `takumi mcp-config` instead.
|
|
101
137
|
|
|
102
138
|
Once configured, just ask in natural language:
|
|
103
139
|
|
package/bin/takumi-mcp
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Wrapper to start the takumi MCP server.
|
|
3
|
+
# Finds node even when launched outside a login shell (VS Code, Kiro, etc.)
|
|
4
|
+
|
|
5
|
+
find_node() {
|
|
6
|
+
# Check PATH first
|
|
7
|
+
if command -v node &>/dev/null; then
|
|
8
|
+
command -v node
|
|
9
|
+
return
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
# nvm (macOS/Linux)
|
|
13
|
+
if [ -d "$HOME/.nvm/versions/node" ]; then
|
|
14
|
+
local latest
|
|
15
|
+
latest="$(ls -v "$HOME/.nvm/versions/node" | tail -1)"
|
|
16
|
+
if [ -n "$latest" ] && [ -x "$HOME/.nvm/versions/node/$latest/bin/node" ]; then
|
|
17
|
+
echo "$HOME/.nvm/versions/node/$latest/bin/node"
|
|
18
|
+
return
|
|
19
|
+
fi
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# fnm
|
|
23
|
+
if [ -d "$HOME/.fnm" ]; then
|
|
24
|
+
local latest
|
|
25
|
+
latest="$(ls -v "$HOME/.fnm/node-versions" 2>/dev/null | tail -1)"
|
|
26
|
+
if [ -n "$latest" ] && [ -x "$HOME/.fnm/node-versions/$latest/installation/bin/node" ]; then
|
|
27
|
+
echo "$HOME/.fnm/node-versions/$latest/installation/bin/node"
|
|
28
|
+
return
|
|
29
|
+
fi
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Homebrew
|
|
33
|
+
if [ -x "/opt/homebrew/bin/node" ]; then
|
|
34
|
+
echo "/opt/homebrew/bin/node"
|
|
35
|
+
return
|
|
36
|
+
fi
|
|
37
|
+
if [ -x "/usr/local/bin/node" ]; then
|
|
38
|
+
echo "/usr/local/bin/node"
|
|
39
|
+
return
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# Volta
|
|
43
|
+
if [ -x "$HOME/.volta/bin/node" ]; then
|
|
44
|
+
echo "$HOME/.volta/bin/node"
|
|
45
|
+
return
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
return 1
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
NODE="$(find_node)"
|
|
52
|
+
if [ -z "$NODE" ]; then
|
|
53
|
+
echo "Error: node not found. Install Node.js: https://nodejs.org" >&2
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
58
|
+
exec "$NODE" "$SCRIPT_DIR/mcp/server.js"
|
package/commands/mcp-config.sh
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
# ── MCP Config: Print MCP server configuration JSON ─────────────────────────
|
|
3
3
|
|
|
4
4
|
cmd_mcp-config() {
|
|
5
|
-
local
|
|
6
|
-
|
|
5
|
+
local MCP_CMD
|
|
6
|
+
MCP_CMD="$(command -v takumi-mcp 2>/dev/null || realpath "${SCRIPT_DIR}/bin/takumi-mcp")"
|
|
7
7
|
|
|
8
|
-
if [ ! -
|
|
9
|
-
echo "❌
|
|
10
|
-
echo "
|
|
8
|
+
if [ ! -x "$MCP_CMD" ]; then
|
|
9
|
+
echo "❌ takumi-mcp not found."
|
|
10
|
+
echo " Reinstall takumi: brew upgrade takumi / npm install -g takumi-cli"
|
|
11
11
|
return 1
|
|
12
12
|
fi
|
|
13
13
|
|
|
@@ -17,8 +17,7 @@ cmd_mcp-config() {
|
|
|
17
17
|
{
|
|
18
18
|
"servers": {
|
|
19
19
|
"takumi": {
|
|
20
|
-
"command": "
|
|
21
|
-
"args": ["${MCP_SERVER}"]
|
|
20
|
+
"command": "${MCP_CMD}"
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
}
|
|
@@ -31,8 +30,7 @@ EOF
|
|
|
31
30
|
{
|
|
32
31
|
"mcpServers": {
|
|
33
32
|
"takumi": {
|
|
34
|
-
"command": "
|
|
35
|
-
"args": ["${MCP_SERVER}"]
|
|
33
|
+
"command": "${MCP_CMD}"
|
|
36
34
|
}
|
|
37
35
|
}
|
|
38
36
|
}
|
|
@@ -45,8 +43,7 @@ EOF
|
|
|
45
43
|
{
|
|
46
44
|
"mcpServers": {
|
|
47
45
|
"takumi": {
|
|
48
|
-
"command": "
|
|
49
|
-
"args": ["${MCP_SERVER}"]
|
|
46
|
+
"command": "${MCP_CMD}"
|
|
50
47
|
}
|
|
51
48
|
}
|
|
52
49
|
}
|
package/mcp/server.js
CHANGED
|
@@ -18,13 +18,26 @@ function run(args) {
|
|
|
18
18
|
isError: true,
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
// Validate that file path args exist before running
|
|
23
|
+
const filePath = args[1];
|
|
24
|
+
if (filePath) {
|
|
25
|
+
const fs = require("fs");
|
|
26
|
+
if (!fs.existsSync(filePath)) {
|
|
27
|
+
return Promise.resolve({
|
|
28
|
+
text: `Error: file or folder not found: ${filePath}`,
|
|
29
|
+
isError: true,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
21
34
|
return new Promise((resolve) => {
|
|
22
35
|
execFile(BASH, [TAKUMI, ...args], { timeout: 300_000, env: ENV }, (err, stdout, stderr) => {
|
|
23
36
|
const output = [stdout, stderr].filter(Boolean).join("\n").trim();
|
|
24
37
|
if (err && !output) {
|
|
25
|
-
resolve({ text: `Error: ${err.message}`, isError: true });
|
|
38
|
+
resolve({ text: `Error (exit code ${err.code}): ${err.message}`, isError: true });
|
|
26
39
|
} else if (err) {
|
|
27
|
-
resolve({ text: output
|
|
40
|
+
resolve({ text: `Error (exit code ${err.code}):\n${output}`, isError: true });
|
|
28
41
|
} else {
|
|
29
42
|
resolve({ text: output || "Done.", isError: false });
|
|
30
43
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "takumi-cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
4
4
|
"description": "The craftsman's toolkit for shaping video assets",
|
|
5
5
|
"bin": {
|
|
6
|
-
"takumi": "bin/takumi.js"
|
|
6
|
+
"takumi": "bin/takumi.js",
|
|
7
|
+
"takumi-mcp": "bin/takumi-mcp"
|
|
7
8
|
},
|
|
8
9
|
"files": [
|
|
9
10
|
"bin/",
|
package/test.sh
CHANGED
|
@@ -131,6 +131,45 @@ assert "640x480 capped 240 → 320:240" "320:240" "$OUT"
|
|
|
131
131
|
OUT=$(get_best_mod16 3840 2160 1080)
|
|
132
132
|
assert "4K capped 1080 → 1920:1080" "1920:1080" "$OUT"
|
|
133
133
|
|
|
134
|
+
# ── Paths with spaces ──────────────────────────────────────────────────────
|
|
135
|
+
|
|
136
|
+
echo ""
|
|
137
|
+
echo "🔧 Paths with spaces"
|
|
138
|
+
|
|
139
|
+
TMP_DIR=$(mktemp -d)
|
|
140
|
+
SPACE_DIR="${TMP_DIR}/folder with spaces"
|
|
141
|
+
mkdir -p "$SPACE_DIR"
|
|
142
|
+
|
|
143
|
+
OUT=$(run info "$SPACE_DIR/nonexistent file.mp4")
|
|
144
|
+
assert "info handles spaces in path" "not found" "$OUT"
|
|
145
|
+
|
|
146
|
+
OUT=$(run convert "$SPACE_DIR/nonexistent file.mp4")
|
|
147
|
+
assert "convert handles spaces in path" "not found" "$OUT"
|
|
148
|
+
|
|
149
|
+
OUT=$(run trim "$SPACE_DIR/nonexistent file.mp4" 00:00:00 00:00:05)
|
|
150
|
+
assert "trim handles spaces in path" "not found" "$OUT"
|
|
151
|
+
|
|
152
|
+
OUT=$(run thumb "$SPACE_DIR/nonexistent file.mp4")
|
|
153
|
+
assert "thumb handles spaces in path" "not found" "$OUT"
|
|
154
|
+
|
|
155
|
+
OUT=$(run gif "$SPACE_DIR/nonexistent file.mp4" 00:00:00 00:00:05)
|
|
156
|
+
assert "gif handles spaces in path" "not found" "$OUT"
|
|
157
|
+
|
|
158
|
+
OUT=$(run strip "$SPACE_DIR/nonexistent file.mp4" audio)
|
|
159
|
+
assert "strip handles spaces in path" "not found" "$OUT"
|
|
160
|
+
|
|
161
|
+
rm -rf "$TMP_DIR"
|
|
162
|
+
|
|
163
|
+
# ── MCP server ──────────────────────────────────────────────────────────────
|
|
164
|
+
|
|
165
|
+
echo ""
|
|
166
|
+
echo "🔧 MCP server"
|
|
167
|
+
|
|
168
|
+
MCP_INIT='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}'
|
|
169
|
+
OUT=$(echo "$MCP_INIT" | node mcp/server.js 2>/dev/null || true)
|
|
170
|
+
assert "MCP server initializes" "takumi" "$OUT"
|
|
171
|
+
assert "MCP server reports tools capability" "tools" "$OUT"
|
|
172
|
+
|
|
134
173
|
# ── All commands listed in help ──────────────────────────────────────────────
|
|
135
174
|
|
|
136
175
|
echo ""
|
|
@@ -141,6 +180,7 @@ for CMD in "${COMMANDS[@]}"; do
|
|
|
141
180
|
assert "$CMD listed in help" "$CMD" "$HELP"
|
|
142
181
|
done
|
|
143
182
|
assert "setup listed in help" "setup" "$HELP"
|
|
183
|
+
assert "mcp-config listed in help" "mcp-config" "$HELP"
|
|
144
184
|
|
|
145
185
|
# ── Results ──────────────────────────────────────────────────────────────────
|
|
146
186
|
|