@koolink/koolink 1.0.1

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 KooLink
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # koolink
2
+
3
+ Shorten any URL to a clean `kool.ink/xyz` link from your terminal. **Free, unlimited, no signup.** AI-agent ready.
4
+
5
+ ```bash
6
+ npx @koolink/koolink https://example.com/very/long/path
7
+ # → https://kool.ink/abc123
8
+ ```
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ # one-off (no install)
14
+ npx @koolink/koolink https://example.com
15
+
16
+ # or install globally
17
+ npm install -g @koolink/koolink
18
+ koolink https://example.com
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```bash
24
+ # Shorten a URL (prints the short link, copies to clipboard on desktop)
25
+ koolink https://example.com/very/long/path
26
+
27
+ # Shorten from stdin (great for piping)
28
+ echo "https://example.com" | koolink
29
+
30
+ # Shorten a batch
31
+ cat urls.txt | xargs -I{} koolink {}
32
+ ```
33
+
34
+ | Flag | Description |
35
+ |---|---|
36
+ | `--help` / `-h` | Show help |
37
+ | `--version` / `-v` | Show version |
38
+
39
+ ## Install as an MCP server
40
+
41
+ Point any MCP client (Claude Desktop, Cursor, Windsurf, etc.) at the hosted MCP server at `https://mcp.kool.ink` — no API key required for anonymous shortening.
42
+
43
+ ```json
44
+ {
45
+ "mcpServers": {
46
+ "koolink": {
47
+ "url": "https://mcp.kool.ink"
48
+ }
49
+ }
50
+ }
51
+ ```
52
+
53
+ ## Tools
54
+
55
+ This server exposes the following MCP tools:
56
+
57
+ | Tool | Description | Input |
58
+ |---|---|---|
59
+ | `shorten_url` | Shorten a long URL and return a compact kool.ink short link. | `{ "url": "<long-url>" }` |
60
+
61
+ ## Why KooLink
62
+
63
+ - **Free forever** — no account, no credit card, no limits
64
+ - **Clean, memorable URLs** — `kool.ink/xyz`, not `bit.ly/4xdK9qZ`
65
+ - **AI-agent ready** — same service over MCP at `https://mcp.kool.ink`, or the REST API
66
+ - **Analytics** — every link is click-tracked with bot traffic filtered out
67
+ - **Creator Earning Programme** — as traffic grows, you earn
68
+
69
+ ## API
70
+
71
+ The CLI calls the public anonymous endpoint:
72
+
73
+ ```bash
74
+ curl -X POST https://kool.ink/api/links \
75
+ -H "Content-Type: application/json" \
76
+ -d '{"url":"https://example.com"}'
77
+ ```
78
+
79
+ For AI agents, use the MCP server at `https://mcp.kool.ink` (no API key needed for anonymous shortening).
80
+
81
+ ## License
82
+
83
+ MIT
package/bin/koolink.js ADDED
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * koolink — shorten any URL to a clean kool.ink link from your terminal.
4
+ *
5
+ * Usage:
6
+ * koolink <url> Shorten a URL
7
+ * echo <url> | koolink Shorten from stdin
8
+ * koolink --help Show help
9
+ * koolink --version Show version
10
+ *
11
+ * Free, unlimited, no signup. Uses the public anonymous kool.ink API.
12
+ */
13
+
14
+ const API_URL = "https://kool.ink/api/links";
15
+ const SITE_URL = "https://kool.ink";
16
+
17
+ // Prevent self-shortening: never shorten a link that already points at kool.ink.
18
+ function isKoolinkUrl(url) {
19
+ try {
20
+ const u = new URL(url);
21
+ return /(^|\.)kool\.ink$/i.test(u.hostname) || /(^|\.)kool\.ink:/i.test(u.hostname);
22
+ } catch {
23
+ return false;
24
+ }
25
+ }
26
+
27
+ function isValidUrl(url) {
28
+ try {
29
+ const u = new URL(url);
30
+ return u.protocol === "http:" || u.protocol === "https:";
31
+ } catch {
32
+ return false;
33
+ }
34
+ }
35
+
36
+ async function shorten(url) {
37
+ const res = await fetch(API_URL, {
38
+ method: "POST",
39
+ headers: { "Content-Type": "application/json" },
40
+ body: JSON.stringify({ url }),
41
+ });
42
+ if (!res.ok) {
43
+ let msg = `API error ${res.status}`;
44
+ try {
45
+ const j = await res.json();
46
+ if (j.error) msg = j.error;
47
+ else if (j.message) msg = j.message;
48
+ } catch {}
49
+ throw new Error(msg);
50
+ }
51
+ const data = await res.json();
52
+ return data.shortUrl || data.url || API_URL;
53
+ }
54
+
55
+ async function copy(text) {
56
+ // Best-effort: copy to clipboard if available (not on all platforms/CI).
57
+ if (!process.stdout.isTTY) return;
58
+ try {
59
+ const { execSync } = require("child_process");
60
+ if (process.platform === "darwin") execSync("pbcopy", { input: text });
61
+ else if (process.platform === "win32") execSync("clip", { input: text });
62
+ else if (process.platform === "linux") {
63
+ try { execSync("xclip", { input: text }, { stdio: "ignore" }); }
64
+ catch { try { execSync("xsel -b", { input: text }, { stdio: "ignore" }); } catch {} }
65
+ }
66
+ } catch {}
67
+ }
68
+
69
+ async function main() {
70
+ const args = process.argv.slice(2);
71
+
72
+ if (args.includes("--help") || args.includes("-h")) {
73
+ console.log(`koolink — shorten any URL to a clean kool.ink link
74
+
75
+ Usage:
76
+ koolink <url> Shorten a URL
77
+ echo <url> | koolink Shorten from stdin
78
+ koolink --help Show this help
79
+ koolink --version Show version
80
+
81
+ Examples:
82
+ koolink https://example.com/very-long/path
83
+ echo "https://example.com" | koolink
84
+ cat urls.txt | xargs -I{} koolink {}
85
+
86
+ Free, unlimited, no signup. AI-agent ready: https://mcp.kool.ink`);
87
+ return;
88
+ }
89
+
90
+ if (args.includes("--version") || args.includes("-v")) {
91
+ const pkg = require("../package.json");
92
+ console.log(pkg.version);
93
+ return;
94
+ }
95
+
96
+ // Resolve the URL: first non-flag arg, else stdin.
97
+ // Reject the known info flags first so "koolink --help" etc. still work.
98
+ let url = args.find((a) => !a.startsWith("-"));
99
+ if (!url) {
100
+ // Read from stdin (piped).
101
+ const stdin = await new Promise((resolve) => {
102
+ let buf = "";
103
+ process.stdin.setEncoding("utf8");
104
+ process.stdin.on("data", (d) => (buf += d));
105
+ process.stdin.on("end", () => resolve(buf.trim()));
106
+ });
107
+ url = stdin.split(/\s+/).find((s) => s.startsWith("http"));
108
+ }
109
+
110
+ if (!url) {
111
+ console.error("Error: no URL provided. Usage: koolink <url> (or pipe: echo <url> | koolink)");
112
+ process.exit(1);
113
+ }
114
+
115
+ if (!isValidUrl(url)) {
116
+ console.error(`Error: "${url}" is not a valid http(s) URL.`);
117
+ process.exit(1);
118
+ }
119
+
120
+ if (isKoolinkUrl(url)) {
121
+ console.error(`Error: "${url}" already points at kool.ink. Nothing to shorten.`);
122
+ process.exit(1);
123
+ }
124
+
125
+ try {
126
+ const short = await shorten(url);
127
+ console.log(short);
128
+ await copy(short);
129
+ if (process.stdout.isTTY) {
130
+ process.stderr.write(`\n✓ Copied to clipboard → ${short}\n`);
131
+ process.stderr.write(` (free, unlimited, no signup · ${SITE_URL})\n`);
132
+ }
133
+ } catch (e) {
134
+ console.error(`Error: ${e.message}`);
135
+ process.exit(1);
136
+ }
137
+ }
138
+
139
+ main().catch((e) => {
140
+ console.error(`Error: ${e.message}`);
141
+ process.exit(1);
142
+ });
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@koolink/koolink",
3
+ "version": "1.0.1",
4
+ "description": "Shorten any URL to a clean kool.ink link from your terminal. Free, unlimited, no signup. AI-agent ready.",
5
+ "bin": {
6
+ "koolink": "./bin/koolink.js"
7
+ },
8
+ "files": [
9
+ "bin"
10
+ ],
11
+ "engines": {
12
+ "node": ">=16"
13
+ },
14
+ "keywords": [
15
+ "url-shortener",
16
+ "shorten",
17
+ "short-link",
18
+ "shorturl",
19
+ "bitly",
20
+ "tinyurl",
21
+ "koolink",
22
+ "mcp",
23
+ "ai-agent",
24
+ "cli"
25
+ ],
26
+ "license": "MIT",
27
+ "author": "KooLink",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/KooLink/koolink-cli.git"
31
+ },
32
+ "bugs": {
33
+ "url": "https://github.com/KooLink/koolink-cli/issues"
34
+ },
35
+ "homepage": "https://kool.ink",
36
+ "publishConfig": {
37
+ "access": "public"
38
+ }
39
+ }