@agent-tasks/mcp-bridge 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 +45 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +83 -0
- package/dist/cli.js.map +1 -0
- package/dist/login.d.ts +9 -0
- package/dist/login.js +174 -0
- package/dist/login.js.map +1 -0
- package/dist/token-store.d.ts +42 -0
- package/dist/token-store.js +108 -0
- package/dist/token-store.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# @agent-tasks/mcp-bridge
|
|
2
|
+
|
|
3
|
+
Zero-setup MCP bridge for [agent-tasks](https://agent-tasks.opentriologue.ai) — distributes the governed backend as a single `npx` command so any MCP-capable client (Claude Code, triologue, …) can claim, transition, and inspect tasks without touching REST.
|
|
4
|
+
|
|
5
|
+
See the [agent-tasks positioning README](https://github.com/LanNguyenSi/agent-tasks#readme) for where this sits in the Project OS pipeline.
|
|
6
|
+
|
|
7
|
+
## Quickstart
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npx -y @agent-tasks/mcp-bridge login --token "$MY_TOKEN" # store once (or run plain 'login' for an interactive masked prompt)
|
|
11
|
+
claude mcp add agent-tasks -- npx -y @agent-tasks/mcp-bridge # register with Claude Code
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
That's it — the agent now sees `tasks_*`, `signals_*`, and `projects_*` tools. All governance (claim gates, preconditions, review locks, audit trails) is enforced by the remote backend; the bridge is a thin stdio transport with a token cache.
|
|
15
|
+
|
|
16
|
+
> **Note:** passing `--token` on the command line may end up in shell history. Prefer the interactive `login` prompt (input is masked) when possible. For non-interactive use from a secret manager, pipe stdin — e.g. `pass show agent-tasks | agent-tasks-mcp-bridge login` — rather than putting the token on the command line.
|
|
17
|
+
|
|
18
|
+
## Commands
|
|
19
|
+
|
|
20
|
+
| Command | What it does |
|
|
21
|
+
| -------- | ------------------------------------------------------------------- |
|
|
22
|
+
| *(none)* | Start the MCP server over stdio (default — used by MCP clients) |
|
|
23
|
+
| `login` | Validate a token against the backend, store it in the keychain |
|
|
24
|
+
| `logout` | Remove the stored token |
|
|
25
|
+
| `status` | Check that the stored token is still valid |
|
|
26
|
+
|
|
27
|
+
## Token storage
|
|
28
|
+
|
|
29
|
+
1. `AGENT_TASKS_TOKEN` env var (if set, wins; cannot be overwritten by `login`)
|
|
30
|
+
2. OS keychain via `keytar` (macOS Keychain, Windows Credential Vault, libsecret)
|
|
31
|
+
3. File fallback at `${XDG_CONFIG_HOME:-~/.config}/agent-tasks/bridge-token` (mode `0600`) — used when the keytar native module is unavailable
|
|
32
|
+
|
|
33
|
+
## Overriding the backend
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
AGENT_TASKS_BASE_URL=https://staging.example.com npx -y @agent-tasks/mcp-bridge
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Uninstalling
|
|
40
|
+
|
|
41
|
+
`npm uninstall` / removing the `npx` cache does **not** delete the token from the OS keychain. Run `agent-tasks-mcp-bridge logout` first, or delete the keychain entry for service `agent-tasks-mcp-bridge` manually.
|
|
42
|
+
|
|
43
|
+
## License
|
|
44
|
+
|
|
45
|
+
Same as the parent repo.
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runStdioServer, DEFAULT_BASE_URL } from "@agent-tasks/mcp-server";
|
|
3
|
+
import { resolveTokenStore } from "./token-store.js";
|
|
4
|
+
import { runLogin, runLogout, runStatus } from "./login.js";
|
|
5
|
+
const USAGE = `agent-tasks-mcp-bridge — zero-setup MCP bridge for agent-tasks
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
agent-tasks-mcp-bridge Start MCP server over stdio (default)
|
|
9
|
+
agent-tasks-mcp-bridge login [--token <t>]
|
|
10
|
+
Store a token in the OS keychain (or file fallback)
|
|
11
|
+
agent-tasks-mcp-bridge logout Remove the stored token
|
|
12
|
+
agent-tasks-mcp-bridge status Validate the stored token against the backend
|
|
13
|
+
agent-tasks-mcp-bridge --help Show this help
|
|
14
|
+
|
|
15
|
+
Environment:
|
|
16
|
+
AGENT_TASKS_TOKEN If set, used directly (takes precedence over stored token)
|
|
17
|
+
AGENT_TASKS_BASE_URL Override backend base URL (default: ${DEFAULT_BASE_URL})
|
|
18
|
+
`;
|
|
19
|
+
function parseArgs(argv) {
|
|
20
|
+
if (argv.length === 0)
|
|
21
|
+
return { command: "serve" };
|
|
22
|
+
const [first, ...rest] = argv;
|
|
23
|
+
if (first === "--help" || first === "-h" || first === "help") {
|
|
24
|
+
return { command: "help" };
|
|
25
|
+
}
|
|
26
|
+
if (first === "login") {
|
|
27
|
+
let tokenFlag;
|
|
28
|
+
for (let i = 0; i < rest.length; i++) {
|
|
29
|
+
const arg = rest[i];
|
|
30
|
+
if (arg === "--token") {
|
|
31
|
+
tokenFlag = rest[i + 1];
|
|
32
|
+
i++;
|
|
33
|
+
}
|
|
34
|
+
else if (arg?.startsWith("--token=")) {
|
|
35
|
+
tokenFlag = arg.slice("--token=".length);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { command: "login", tokenFlag };
|
|
39
|
+
}
|
|
40
|
+
if (first === "logout")
|
|
41
|
+
return { command: "logout" };
|
|
42
|
+
if (first === "status")
|
|
43
|
+
return { command: "status" };
|
|
44
|
+
if (first === "serve")
|
|
45
|
+
return { command: "serve" };
|
|
46
|
+
throw new Error(`Unknown command: ${first}. Run with --help for usage.`);
|
|
47
|
+
}
|
|
48
|
+
async function main() {
|
|
49
|
+
const args = parseArgs(process.argv.slice(2));
|
|
50
|
+
if (args.command === "help") {
|
|
51
|
+
process.stdout.write(USAGE);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const baseUrl = process.env.AGENT_TASKS_BASE_URL ?? DEFAULT_BASE_URL;
|
|
55
|
+
const store = await resolveTokenStore();
|
|
56
|
+
if (args.command === "login") {
|
|
57
|
+
await runLogin({ baseUrl, store, tokenFromArg: args.tokenFlag });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (args.command === "logout") {
|
|
61
|
+
await runLogout(store);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (args.command === "status") {
|
|
65
|
+
await runStatus(baseUrl, store);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const token = await store.get();
|
|
69
|
+
if (!token) {
|
|
70
|
+
throw new Error("No token available. Run 'agent-tasks-mcp-bridge login' or set AGENT_TASKS_TOKEN.");
|
|
71
|
+
}
|
|
72
|
+
await runStdioServer({ token, baseUrl });
|
|
73
|
+
}
|
|
74
|
+
function sanitize(msg) {
|
|
75
|
+
return msg.replace(/(https?:\/\/[^\s?]+)\?[^\s]*/gi, "$1?[redacted]");
|
|
76
|
+
}
|
|
77
|
+
main().catch((err) => {
|
|
78
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
79
|
+
// eslint-disable-next-line no-console
|
|
80
|
+
console.error("[agent-tasks-mcp-bridge] fatal:", sanitize(raw));
|
|
81
|
+
process.exit(1);
|
|
82
|
+
});
|
|
83
|
+
//# 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":";AACA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5D,MAAM,KAAK,GAAG;;;;;;;;;;;;8DAYgD,gBAAgB;CAC7E,CAAC;AAOF,SAAS,SAAS,CAAC,IAAc;IAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IACnD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9B,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC;IACD,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACtB,IAAI,SAA6B,CAAC;QAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,SAAS,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACxB,CAAC,EAAE,CAAC;YACN,CAAC;iBAAM,IAAI,GAAG,EAAE,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACvC,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IACzC,CAAC;IACD,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IACrD,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IACrD,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IACnD,MAAM,IAAI,KAAK,CAAC,oBAAoB,KAAK,8BAA8B,CAAC,CAAC;AAC3E,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,gBAAgB,CAAC;IACrE,MAAM,KAAK,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAExC,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAChC,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;IACJ,CAAC;IACD,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC3B,OAAO,GAAG,CAAC,OAAO,CAAC,gCAAgC,EAAE,eAAe,CAAC,CAAC;AACxE,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,sCAAsC;IACtC,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/login.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TokenStore } from "./token-store.js";
|
|
2
|
+
export interface LoginOptions {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
store: TokenStore;
|
|
5
|
+
tokenFromArg?: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare function runLogin(options: LoginOptions): Promise<void>;
|
|
8
|
+
export declare function runLogout(store: TokenStore): Promise<void>;
|
|
9
|
+
export declare function runStatus(baseUrl: string, store: TokenStore): Promise<void>;
|
package/dist/login.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { stdin as input, stderr, stdout } from "node:process";
|
|
2
|
+
/**
|
|
3
|
+
* Read a token from stdin with real character masking.
|
|
4
|
+
*
|
|
5
|
+
* On a TTY: put stdin in raw mode, read byte-by-byte, echo `*` per printable
|
|
6
|
+
* char, handle Backspace/Ctrl-C/Enter. On failure (non-TTY, no setRawMode,
|
|
7
|
+
* exception mid-read) we fall back to a line read with a visibility warning —
|
|
8
|
+
* fake masking is worse than honest echo.
|
|
9
|
+
*/
|
|
10
|
+
function promptHiddenToken() {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
if (!input.isTTY || typeof input.setRawMode !== "function") {
|
|
13
|
+
stderr.write("warning: stdin is not a TTY — reading one line without masking.\n");
|
|
14
|
+
let buf = "";
|
|
15
|
+
let settled = false;
|
|
16
|
+
const detach = () => {
|
|
17
|
+
input.off("data", onData);
|
|
18
|
+
input.off("end", onEnd);
|
|
19
|
+
input.off("error", onErr);
|
|
20
|
+
};
|
|
21
|
+
const settle = (err, value) => {
|
|
22
|
+
if (settled)
|
|
23
|
+
return;
|
|
24
|
+
settled = true;
|
|
25
|
+
detach();
|
|
26
|
+
if (err)
|
|
27
|
+
reject(err);
|
|
28
|
+
else
|
|
29
|
+
resolve((value ?? "").trim());
|
|
30
|
+
};
|
|
31
|
+
const onData = (chunk) => {
|
|
32
|
+
buf += chunk.toString("utf8");
|
|
33
|
+
const nl = buf.indexOf("\n");
|
|
34
|
+
if (nl >= 0)
|
|
35
|
+
settle(null, buf.slice(0, nl));
|
|
36
|
+
};
|
|
37
|
+
const onEnd = () => settle(null, buf);
|
|
38
|
+
const onErr = (err) => settle(err);
|
|
39
|
+
input.on("data", onData);
|
|
40
|
+
input.on("end", onEnd);
|
|
41
|
+
input.on("error", onErr);
|
|
42
|
+
input.resume();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
stderr.write("Paste your agent-tasks token (hidden): ");
|
|
46
|
+
input.setRawMode(true);
|
|
47
|
+
input.resume();
|
|
48
|
+
input.setEncoding("utf8");
|
|
49
|
+
let entered = "";
|
|
50
|
+
let settled = false;
|
|
51
|
+
const cleanup = (err, value) => {
|
|
52
|
+
if (settled)
|
|
53
|
+
return;
|
|
54
|
+
settled = true;
|
|
55
|
+
input.off("data", onKey);
|
|
56
|
+
try {
|
|
57
|
+
input.setRawMode(false);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// ignore
|
|
61
|
+
}
|
|
62
|
+
input.pause();
|
|
63
|
+
stderr.write("\n");
|
|
64
|
+
if (err)
|
|
65
|
+
reject(err);
|
|
66
|
+
else
|
|
67
|
+
resolve((value ?? "").trim());
|
|
68
|
+
};
|
|
69
|
+
const onKey = (chunk) => {
|
|
70
|
+
for (const ch of chunk) {
|
|
71
|
+
const code = ch.charCodeAt(0);
|
|
72
|
+
if (ch === "\r" || ch === "\n") {
|
|
73
|
+
cleanup(null, entered);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (code === 3) {
|
|
77
|
+
// Ctrl-C
|
|
78
|
+
cleanup(new Error("Login cancelled"));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (code === 4) {
|
|
82
|
+
// Ctrl-D (EOF)
|
|
83
|
+
cleanup(entered.length === 0 ? new Error("Login cancelled") : null, entered);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (code === 127 || code === 8) {
|
|
87
|
+
// Backspace / DEL
|
|
88
|
+
if (entered.length > 0) {
|
|
89
|
+
entered = entered.slice(0, -1);
|
|
90
|
+
stderr.write("\b \b");
|
|
91
|
+
}
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (code < 32)
|
|
95
|
+
continue; // ignore other control chars
|
|
96
|
+
entered += ch;
|
|
97
|
+
stderr.write("*");
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
input.on("data", onKey);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function sanitizeForLog(message) {
|
|
104
|
+
// Strip query strings from any URL to avoid leaking accidentally-embedded secrets.
|
|
105
|
+
return message.replace(/(https?:\/\/[^\s?]+)\?[^\s]*/gi, "$1?[redacted]");
|
|
106
|
+
}
|
|
107
|
+
async function validateToken(baseUrl, token) {
|
|
108
|
+
let res;
|
|
109
|
+
try {
|
|
110
|
+
res = await fetch(`${baseUrl.replace(/\/$/, "")}/api/projects/available`, {
|
|
111
|
+
headers: { Authorization: `Bearer ${token}`, Accept: "application/json" },
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
throw new Error(`Token validation request failed: ${sanitizeForLog(err.message)}`);
|
|
116
|
+
}
|
|
117
|
+
if (!res.ok) {
|
|
118
|
+
throw new Error(`Token validation failed: HTTP ${res.status}. Check the token and base URL.`);
|
|
119
|
+
}
|
|
120
|
+
// Sanity check the body shape so an accidentally-public endpoint cannot
|
|
121
|
+
// silently accept a bogus token.
|
|
122
|
+
const body = (await res.json().catch(() => null));
|
|
123
|
+
const ok = Array.isArray(body) ||
|
|
124
|
+
(body !== null && typeof body === "object" && "projects" in body);
|
|
125
|
+
if (!ok) {
|
|
126
|
+
throw new Error("Token validation response did not match expected shape; refusing to store.");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export async function runLogin(options) {
|
|
130
|
+
if (options.store.kind === "env") {
|
|
131
|
+
stderr.write("AGENT_TASKS_TOKEN is set in the environment; login is not needed (and cannot overwrite an env token). Unset it first to store in the keychain.\n");
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const token = options.tokenFromArg && options.tokenFromArg.length > 0
|
|
135
|
+
? options.tokenFromArg
|
|
136
|
+
: await promptHiddenToken();
|
|
137
|
+
if (!token) {
|
|
138
|
+
throw new Error("No token provided.");
|
|
139
|
+
}
|
|
140
|
+
if (/\s/.test(token)) {
|
|
141
|
+
throw new Error("Token contains whitespace or newlines — pasted input may have been truncated. Re-run login and ensure the whole token is on a single line.");
|
|
142
|
+
}
|
|
143
|
+
if (token.length < 16) {
|
|
144
|
+
throw new Error("Token is suspiciously short (<16 chars) — refusing to store. Check that the whole token was captured.");
|
|
145
|
+
}
|
|
146
|
+
await validateToken(options.baseUrl, token);
|
|
147
|
+
await options.store.set(token);
|
|
148
|
+
stderr.write(`Token stored via ${options.store.kind} store. Run 'agent-tasks-mcp-bridge status' to verify.\n`);
|
|
149
|
+
}
|
|
150
|
+
export async function runLogout(store) {
|
|
151
|
+
if (store.kind === "env") {
|
|
152
|
+
stderr.write("Token is provided by AGENT_TASKS_TOKEN env var; unset it in your shell to log out. Nothing to clear in the keychain.\n");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
await store.clear();
|
|
156
|
+
stderr.write("Token cleared.\n");
|
|
157
|
+
}
|
|
158
|
+
export async function runStatus(baseUrl, store) {
|
|
159
|
+
const token = await store.get();
|
|
160
|
+
if (!token) {
|
|
161
|
+
stderr.write(`No token stored (${store.kind}). Run 'login' first.\n`);
|
|
162
|
+
process.exitCode = 1;
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
await validateToken(baseUrl, token);
|
|
167
|
+
stdout.write(`ok (store: ${store.kind})\n`);
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
stderr.write(`Token present (${store.kind}) but validation failed: ${sanitizeForLog(err.message)}\n`);
|
|
171
|
+
process.exitCode = 1;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface TokenStore {
|
|
2
|
+
kind: "keytar" | "file" | "env";
|
|
3
|
+
get(): Promise<string | null>;
|
|
4
|
+
set(token: string): Promise<void>;
|
|
5
|
+
clear(): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
declare class EnvStore implements TokenStore {
|
|
8
|
+
private readonly value;
|
|
9
|
+
readonly kind: "env";
|
|
10
|
+
constructor(value: string);
|
|
11
|
+
get(): Promise<string>;
|
|
12
|
+
set(): Promise<void>;
|
|
13
|
+
clear(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
declare class KeytarStore implements TokenStore {
|
|
16
|
+
private readonly keytar;
|
|
17
|
+
readonly kind: "keytar";
|
|
18
|
+
constructor(keytar: any);
|
|
19
|
+
get(): Promise<any>;
|
|
20
|
+
set(token: string): Promise<void>;
|
|
21
|
+
clear(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
declare function fileStorePath(): string;
|
|
24
|
+
declare class FileStore implements TokenStore {
|
|
25
|
+
private readonly path;
|
|
26
|
+
readonly kind: "file";
|
|
27
|
+
constructor(path: string);
|
|
28
|
+
get(): Promise<string | null>;
|
|
29
|
+
set(token: string): Promise<void>;
|
|
30
|
+
clear(): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export declare function resolveTokenStore(options?: {
|
|
33
|
+
envToken?: string | undefined;
|
|
34
|
+
filePath?: string;
|
|
35
|
+
}): Promise<TokenStore>;
|
|
36
|
+
export declare const __testing: {
|
|
37
|
+
FileStore: typeof FileStore;
|
|
38
|
+
EnvStore: typeof EnvStore;
|
|
39
|
+
KeytarStore: typeof KeytarStore;
|
|
40
|
+
fileStorePath: typeof fileStorePath;
|
|
41
|
+
};
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile, rm, chmod, rename } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const SERVICE = "agent-tasks-mcp-bridge";
|
|
5
|
+
const ACCOUNT = "default";
|
|
6
|
+
class EnvStore {
|
|
7
|
+
value;
|
|
8
|
+
kind = "env";
|
|
9
|
+
constructor(value) {
|
|
10
|
+
this.value = value;
|
|
11
|
+
}
|
|
12
|
+
async get() {
|
|
13
|
+
return this.value;
|
|
14
|
+
}
|
|
15
|
+
async set() {
|
|
16
|
+
throw new Error("Token was provided via AGENT_TASKS_TOKEN env var; refusing to overwrite. Unset the env var to use the keychain store.");
|
|
17
|
+
}
|
|
18
|
+
async clear() {
|
|
19
|
+
throw new Error("Token was provided via AGENT_TASKS_TOKEN env var; nothing to clear in the keychain.");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
class KeytarStore {
|
|
23
|
+
keytar;
|
|
24
|
+
kind = "keytar";
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
constructor(keytar) {
|
|
27
|
+
this.keytar = keytar;
|
|
28
|
+
}
|
|
29
|
+
async get() {
|
|
30
|
+
return (await this.keytar.getPassword(SERVICE, ACCOUNT)) ?? null;
|
|
31
|
+
}
|
|
32
|
+
async set(token) {
|
|
33
|
+
await this.keytar.setPassword(SERVICE, ACCOUNT, token);
|
|
34
|
+
}
|
|
35
|
+
async clear() {
|
|
36
|
+
await this.keytar.deletePassword(SERVICE, ACCOUNT);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function fileStorePath() {
|
|
40
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
41
|
+
const base = xdg && xdg.length > 0 ? xdg : join(homedir(), ".config");
|
|
42
|
+
return join(base, "agent-tasks", "bridge-token");
|
|
43
|
+
}
|
|
44
|
+
class FileStore {
|
|
45
|
+
path;
|
|
46
|
+
kind = "file";
|
|
47
|
+
constructor(path) {
|
|
48
|
+
this.path = path;
|
|
49
|
+
}
|
|
50
|
+
async get() {
|
|
51
|
+
try {
|
|
52
|
+
const content = await readFile(this.path, "utf8");
|
|
53
|
+
const trimmed = content.trim();
|
|
54
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
if (err.code === "ENOENT")
|
|
58
|
+
return null;
|
|
59
|
+
throw err;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async set(token) {
|
|
63
|
+
const dir = dirname(this.path);
|
|
64
|
+
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
65
|
+
await chmod(dir, 0o700).catch(() => {
|
|
66
|
+
// best-effort on filesystems without POSIX perms (e.g., some Windows)
|
|
67
|
+
});
|
|
68
|
+
const tmp = `${this.path}.${process.pid}.tmp`;
|
|
69
|
+
await writeFile(tmp, token, { encoding: "utf8", mode: 0o600 });
|
|
70
|
+
await chmod(tmp, 0o600).catch(() => {
|
|
71
|
+
// best-effort
|
|
72
|
+
});
|
|
73
|
+
await rename(tmp, this.path);
|
|
74
|
+
}
|
|
75
|
+
async clear() {
|
|
76
|
+
try {
|
|
77
|
+
await rm(this.path);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
if (err.code !== "ENOENT")
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export async function resolveTokenStore(options) {
|
|
86
|
+
const envToken = options?.envToken ?? process.env.AGENT_TASKS_TOKEN;
|
|
87
|
+
if (envToken && envToken.length > 0) {
|
|
88
|
+
return new EnvStore(envToken);
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const mod = (await import("keytar"));
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
93
|
+
const keytar = mod.getPassword ? mod : mod.default;
|
|
94
|
+
if (keytar?.getPassword) {
|
|
95
|
+
// Runtime probe: on Linux without libsecret-1 at runtime, keytar
|
|
96
|
+
// imports cleanly but throws on first call. Probe here so we can
|
|
97
|
+
// fall through to FileStore before returning a broken store.
|
|
98
|
+
await keytar.getPassword(SERVICE, ACCOUNT);
|
|
99
|
+
return new KeytarStore(keytar);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// keytar native module failed to load or probe — fall through to file store
|
|
104
|
+
}
|
|
105
|
+
return new FileStore(options?.filePath ?? fileStorePath());
|
|
106
|
+
}
|
|
107
|
+
export const __testing = { FileStore, EnvStore, KeytarStore, fileStorePath };
|
|
108
|
+
//# sourceMappingURL=token-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.js","sourceRoot":"","sources":["../src/token-store.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agent-tasks/mcp-bridge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Zero-setup MCP bridge for agent-tasks: npx-distributable wrapper around @agent-tasks/mcp-server with interactive login and OS-keychain token storage",
|
|
5
|
+
"homepage": "https://github.com/LanNguyenSi/agent-tasks/tree/master/mcp-bridge#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/LanNguyenSi/agent-tasks.git",
|
|
9
|
+
"directory": "mcp-bridge"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/LanNguyenSi/agent-tasks/issues"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"bin": {
|
|
17
|
+
"agent-tasks-mcp-bridge": "./dist/cli.js"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"dev": "npm run build --workspace=mcp-server --prefix .. && tsx src/cli.ts",
|
|
26
|
+
"start": "node dist/cli.js",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"typecheck": "tsc --noEmit"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@agent-tasks/mcp-server": "0.1.0"
|
|
32
|
+
},
|
|
33
|
+
"optionalDependencies": {
|
|
34
|
+
"keytar": "^7.9.0"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public",
|
|
38
|
+
"provenance": true
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "^22.0.0",
|
|
42
|
+
"tsx": "^4.19.0",
|
|
43
|
+
"typescript": "^5.6.0",
|
|
44
|
+
"vitest": "^2.1.0"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=22",
|
|
48
|
+
"npm": ">=8"
|
|
49
|
+
}
|
|
50
|
+
}
|