@apex-inc/mcp-server 0.9.2 → 0.9.4
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/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +46 -16
- package/dist/api-client.js.map +1 -1
- package/dist/auth.d.ts +37 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +221 -0
- package/dist/auth.js.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/api-client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAYA,UAAU,OAAO;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxE;AAED,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAID,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,QAEtD;AAED,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAEvD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,QAMzC;AAED,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAEjD;AAED,wBAAgB,cAAc,IAAI,WAAW,GAAG,SAAS,CAExD;AAiBD;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAsCnE;AA2BD,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAUrD;AAiED,wBAAsB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAIxD;AAED,wBAAsB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAQxE;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3D;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAQzE"}
|
package/dist/api-client.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MCP_SERVER_VERSION } from "./version.js";
|
|
2
|
+
import { ensureAuth, getAuthToken, reauthAfterFailure, hasStoredCredential, } from "./auth.js";
|
|
2
3
|
const BASE_URL = process.env.APEX_URL || process.env.APEX_API_URL || "http://localhost:3001";
|
|
3
4
|
let activeWorkspaceKey = (process.env.APEX_WORKSPACE_KEY || process.env.APEX_PROJECT_KEY);
|
|
4
5
|
let activeOrgId;
|
|
@@ -23,7 +24,9 @@ export function getUserContext() {
|
|
|
23
24
|
return userContext;
|
|
24
25
|
}
|
|
25
26
|
function authHeaders() {
|
|
26
|
-
|
|
27
|
+
// Static APEX_API_KEY, or the current device-flow access token. Both go in
|
|
28
|
+
// the `x-api-key` header so they share the backend's resolution path.
|
|
29
|
+
const key = getAuthToken();
|
|
27
30
|
const headers = {
|
|
28
31
|
"x-apex-source": "mcp-server",
|
|
29
32
|
// OPW-QA-002 — version handshake: the setup page warns when a
|
|
@@ -41,9 +44,23 @@ function authHeaders() {
|
|
|
41
44
|
* Only works with user keys (apex_uk_). Falls back gracefully for org keys.
|
|
42
45
|
*/
|
|
43
46
|
export async function discoverContext() {
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
// Don't trigger the device flow at startup — only greet when we already
|
|
48
|
+
// hold a credential. First tool call drives auth (URL surfaces in chat).
|
|
49
|
+
if (!hasStoredCredential()) {
|
|
50
|
+
return "Ready. Run any Apex tool to connect — you'll get a one-time approval link.";
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
await ensureAuth();
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return "Run any Apex tool to finish connecting (you'll get an approval link).";
|
|
57
|
+
}
|
|
58
|
+
const key = getAuthToken();
|
|
59
|
+
// User-scoped credentials (static user key OR device access token) carry an
|
|
60
|
+
// org graph; org keys (apex_sk_) don't.
|
|
61
|
+
if (!key?.startsWith("apex_uk_") && !key?.startsWith("apex_at_")) {
|
|
46
62
|
return undefined;
|
|
63
|
+
}
|
|
47
64
|
try {
|
|
48
65
|
const res = await fetch(`${BASE_URL}/api/user/orgs`, {
|
|
49
66
|
headers: { ...authHeaders() },
|
|
@@ -129,18 +146,35 @@ async function throwForStatus(method, path, res) {
|
|
|
129
146
|
}
|
|
130
147
|
throw new Error(`${method} ${path} failed (${res.status}): ${text}`);
|
|
131
148
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Single fetch chokepoint: ensures a fresh credential first, and on a 401
|
|
151
|
+
* (device-token expired/revoked) attempts a refresh / re-auth and retries
|
|
152
|
+
* once. Static-key callers don't retry — their 401 is surfaced verbatim.
|
|
153
|
+
*/
|
|
154
|
+
async function fetchWithAuth(path, init) {
|
|
155
|
+
await ensureAuth();
|
|
156
|
+
const build = () => ({
|
|
157
|
+
...init,
|
|
158
|
+
headers: { ...init.headers, ...authHeaders() },
|
|
135
159
|
});
|
|
160
|
+
let res = await fetch(`${BASE_URL}${path}`, build());
|
|
161
|
+
if (res.status === 401 && !process.env.APEX_API_KEY) {
|
|
162
|
+
if (await reauthAfterFailure()) {
|
|
163
|
+
res = await fetch(`${BASE_URL}${path}`, build());
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return res;
|
|
167
|
+
}
|
|
168
|
+
export async function apiGet(path) {
|
|
169
|
+
const res = await fetchWithAuth(path, { method: "GET" });
|
|
136
170
|
if (!res.ok)
|
|
137
171
|
await throwForStatus("GET", path, res);
|
|
138
172
|
return res.json();
|
|
139
173
|
}
|
|
140
174
|
export async function apiPost(path, body) {
|
|
141
|
-
const res = await
|
|
175
|
+
const res = await fetchWithAuth(path, {
|
|
142
176
|
method: "POST",
|
|
143
|
-
headers: { "Content-Type": "application/json"
|
|
177
|
+
headers: { "Content-Type": "application/json" },
|
|
144
178
|
body: JSON.stringify(body),
|
|
145
179
|
});
|
|
146
180
|
if (!res.ok)
|
|
@@ -155,12 +189,11 @@ export async function apiPost(path, body) {
|
|
|
155
189
|
* `${runId}:${eventType}`).
|
|
156
190
|
*/
|
|
157
191
|
export async function postWithIdempotency(path, idempotencyKey, body) {
|
|
158
|
-
const res = await
|
|
192
|
+
const res = await fetchWithAuth(path, {
|
|
159
193
|
method: "POST",
|
|
160
194
|
headers: {
|
|
161
195
|
"Content-Type": "application/json",
|
|
162
196
|
"idempotency-key": idempotencyKey,
|
|
163
|
-
...authHeaders(),
|
|
164
197
|
},
|
|
165
198
|
body: JSON.stringify(body),
|
|
166
199
|
});
|
|
@@ -169,17 +202,14 @@ export async function postWithIdempotency(path, idempotencyKey, body) {
|
|
|
169
202
|
return res.json();
|
|
170
203
|
}
|
|
171
204
|
export async function apiDelete(path) {
|
|
172
|
-
const res = await
|
|
173
|
-
method: "DELETE",
|
|
174
|
-
headers: { ...authHeaders() },
|
|
175
|
-
});
|
|
205
|
+
const res = await fetchWithAuth(path, { method: "DELETE" });
|
|
176
206
|
if (!res.ok)
|
|
177
207
|
await throwForStatus("DELETE", path, res);
|
|
178
208
|
}
|
|
179
209
|
export async function apiPatch(path, body) {
|
|
180
|
-
const res = await
|
|
210
|
+
const res = await fetchWithAuth(path, {
|
|
181
211
|
method: "PATCH",
|
|
182
|
-
headers: { "Content-Type": "application/json"
|
|
212
|
+
headers: { "Content-Type": "application/json" },
|
|
183
213
|
body: JSON.stringify(body),
|
|
184
214
|
});
|
|
185
215
|
if (!res.ok)
|
package/dist/api-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Device-authorization auth for the Apex MCP server (RFC 8628), built for the
|
|
3
|
+
* editor/MCP model: NON-BLOCKING.
|
|
4
|
+
*
|
|
5
|
+
* The server starts and lists tools instantly. Auth is established lazily on
|
|
6
|
+
* the first tool call that needs the backend:
|
|
7
|
+
* - no creds → start a device request, kick off a background poller, and
|
|
8
|
+
* throw `AuthRequiredError` whose message (the approval URL) the tool
|
|
9
|
+
* handler returns AS A TOOL RESULT — visible in the chat, not buried in
|
|
10
|
+
* server logs. The user approves in the browser; the background poller
|
|
11
|
+
* stores the token; the next call just works.
|
|
12
|
+
* - APEX_API_KEY set → used as-is (static key, back-compat).
|
|
13
|
+
*
|
|
14
|
+
* Tokens persist to ~/.apex/credentials.json (per Apex URL) and refresh
|
|
15
|
+
* automatically. See plans/mcp-device-auth-flow-2026-06.md.
|
|
16
|
+
*/
|
|
17
|
+
/** Thrown when the user must approve in the browser. Message → tool result. */
|
|
18
|
+
export declare class AuthRequiredError extends Error {
|
|
19
|
+
constructor(verificationUriComplete: string, userCode: string);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Ensure a usable credential. Returns immediately when authed; throws
|
|
23
|
+
* `AuthRequiredError` (with the approval URL) when the user must approve.
|
|
24
|
+
* Never blocks waiting for approval.
|
|
25
|
+
*/
|
|
26
|
+
export declare function ensureAuth(): Promise<void>;
|
|
27
|
+
/** The credential to send (static key, or current device access token). */
|
|
28
|
+
export declare function getAuthToken(): string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Called after a 401. Try a refresh; if that fails, start a fresh device
|
|
31
|
+
* request and throw `AuthRequiredError` so the tool surfaces the URL.
|
|
32
|
+
* Returns true only when a refresh succeeded and the caller should retry.
|
|
33
|
+
*/
|
|
34
|
+
export declare function reauthAfterFailure(): Promise<boolean>;
|
|
35
|
+
/** True when we already hold a (possibly stale) credential — used by startup. */
|
|
36
|
+
export declare function hasStoredCredential(): boolean;
|
|
37
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAqCH,+EAA+E;AAC/E,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,uBAAuB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAS9D;AA6ID;;;;GAIG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAahD;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAEjD;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAM3D;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,IAAI,OAAO,CAO7C"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Device-authorization auth for the Apex MCP server (RFC 8628), built for the
|
|
3
|
+
* editor/MCP model: NON-BLOCKING.
|
|
4
|
+
*
|
|
5
|
+
* The server starts and lists tools instantly. Auth is established lazily on
|
|
6
|
+
* the first tool call that needs the backend:
|
|
7
|
+
* - no creds → start a device request, kick off a background poller, and
|
|
8
|
+
* throw `AuthRequiredError` whose message (the approval URL) the tool
|
|
9
|
+
* handler returns AS A TOOL RESULT — visible in the chat, not buried in
|
|
10
|
+
* server logs. The user approves in the browser; the background poller
|
|
11
|
+
* stores the token; the next call just works.
|
|
12
|
+
* - APEX_API_KEY set → used as-is (static key, back-compat).
|
|
13
|
+
*
|
|
14
|
+
* Tokens persist to ~/.apex/credentials.json (per Apex URL) and refresh
|
|
15
|
+
* automatically. See plans/mcp-device-auth-flow-2026-06.md.
|
|
16
|
+
*/
|
|
17
|
+
import { homedir } from "node:os";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync, chmodSync, } from "node:fs";
|
|
20
|
+
const BASE_URL = process.env.APEX_URL || process.env.APEX_API_URL || "http://localhost:3001";
|
|
21
|
+
let creds = null;
|
|
22
|
+
let loaded = false;
|
|
23
|
+
let pending = null;
|
|
24
|
+
let bgPolling = false;
|
|
25
|
+
const CRED_DIR = join(homedir(), ".apex");
|
|
26
|
+
const CRED_FILE = join(CRED_DIR, "credentials.json");
|
|
27
|
+
const credKey = () => BASE_URL.replace(/\/+$/, "");
|
|
28
|
+
/** Thrown when the user must approve in the browser. Message → tool result. */
|
|
29
|
+
export class AuthRequiredError extends Error {
|
|
30
|
+
constructor(verificationUriComplete, userCode) {
|
|
31
|
+
super(`Apex isn't connected to this editor yet. To authorize:\n` +
|
|
32
|
+
` 1. Open ${verificationUriComplete}\n` +
|
|
33
|
+
` 2. Sign in to Apex if needed, then click Approve (code ${userCode}).\n` +
|
|
34
|
+
`Then run this again — it connects automatically once approved.`);
|
|
35
|
+
this.name = "AuthRequiredError";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function loadCreds() {
|
|
39
|
+
try {
|
|
40
|
+
if (!existsSync(CRED_FILE))
|
|
41
|
+
return null;
|
|
42
|
+
const all = JSON.parse(readFileSync(CRED_FILE, "utf8"));
|
|
43
|
+
return all[credKey()] ?? null;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function saveCreds(next) {
|
|
50
|
+
creds = next;
|
|
51
|
+
try {
|
|
52
|
+
mkdirSync(CRED_DIR, { recursive: true });
|
|
53
|
+
let all = {};
|
|
54
|
+
if (existsSync(CRED_FILE)) {
|
|
55
|
+
try {
|
|
56
|
+
all = JSON.parse(readFileSync(CRED_FILE, "utf8"));
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
all = {};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
all[credKey()] = next;
|
|
63
|
+
writeFileSync(CRED_FILE, JSON.stringify(all, null, 2));
|
|
64
|
+
try {
|
|
65
|
+
chmodSync(CRED_FILE, 0o600);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
/* best-effort */
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
/* in-memory only this session */
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function applyTokenResponse(j) {
|
|
76
|
+
if (!j.access_token || !j.refresh_token)
|
|
77
|
+
return false;
|
|
78
|
+
saveCreds({
|
|
79
|
+
accessToken: j.access_token,
|
|
80
|
+
refreshToken: j.refresh_token,
|
|
81
|
+
expiresAt: Date.now() + (j.expires_in ?? 3600) * 1000,
|
|
82
|
+
});
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
86
|
+
async function tryRefresh() {
|
|
87
|
+
if (!creds?.refreshToken)
|
|
88
|
+
return false;
|
|
89
|
+
try {
|
|
90
|
+
const res = await fetch(`${BASE_URL}/api/auth/device/token`, {
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: { "Content-Type": "application/json" },
|
|
93
|
+
body: JSON.stringify({ grant_type: "refresh_token", refresh_token: creds.refreshToken }),
|
|
94
|
+
});
|
|
95
|
+
if (!res.ok)
|
|
96
|
+
return false;
|
|
97
|
+
return applyTokenResponse((await res.json()));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** Begin a device request (idempotent while one is live) + background poll. */
|
|
104
|
+
async function startDeviceRequest() {
|
|
105
|
+
if (pending && Date.now() < pending.expiresAt)
|
|
106
|
+
return pending;
|
|
107
|
+
const res = await fetch(`${BASE_URL}/api/auth/device/code`, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: { "Content-Type": "application/json" },
|
|
110
|
+
body: JSON.stringify({ client: "Apex MCP server" }),
|
|
111
|
+
});
|
|
112
|
+
if (!res.ok) {
|
|
113
|
+
throw new Error(`Couldn't start Apex device authorization (${res.status}). ` +
|
|
114
|
+
`Set APEX_API_KEY to connect with a static key instead.`);
|
|
115
|
+
}
|
|
116
|
+
const d = (await res.json());
|
|
117
|
+
pending = {
|
|
118
|
+
deviceCode: d.device_code,
|
|
119
|
+
userCode: d.user_code,
|
|
120
|
+
verificationUriComplete: d.verification_uri_complete,
|
|
121
|
+
expiresAt: Date.now() + d.expires_in * 1000,
|
|
122
|
+
};
|
|
123
|
+
// Hint in the logs too (some users watch them); the tool result is primary.
|
|
124
|
+
console.error(`[apex] Authorize this editor: open ${d.verification_uri_complete} and approve (code ${d.user_code}).`);
|
|
125
|
+
void backgroundPoll(d.interval || 5);
|
|
126
|
+
return pending;
|
|
127
|
+
}
|
|
128
|
+
/** Poll in the background so approval connects without the user re-triggering. */
|
|
129
|
+
async function backgroundPoll(intervalSec) {
|
|
130
|
+
if (bgPolling)
|
|
131
|
+
return;
|
|
132
|
+
bgPolling = true;
|
|
133
|
+
let intervalMs = intervalSec * 1000;
|
|
134
|
+
try {
|
|
135
|
+
while (pending && Date.now() < pending.expiresAt && !creds) {
|
|
136
|
+
await sleep(intervalMs);
|
|
137
|
+
if (!pending)
|
|
138
|
+
break;
|
|
139
|
+
try {
|
|
140
|
+
const res = await fetch(`${BASE_URL}/api/auth/device/token`, {
|
|
141
|
+
method: "POST",
|
|
142
|
+
headers: { "Content-Type": "application/json" },
|
|
143
|
+
body: JSON.stringify({ grant_type: "device_code", device_code: pending.deviceCode }),
|
|
144
|
+
});
|
|
145
|
+
const body = (await res.json().catch(() => ({})));
|
|
146
|
+
if (res.ok && applyTokenResponse(body)) {
|
|
147
|
+
console.error("[apex] Connected.");
|
|
148
|
+
pending = null;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const err = String(body.error ?? "");
|
|
152
|
+
if (err === "slow_down")
|
|
153
|
+
intervalMs += 5000;
|
|
154
|
+
else if (err === "authorization_pending")
|
|
155
|
+
continue;
|
|
156
|
+
else {
|
|
157
|
+
// expired / denied — stop; a later call starts a fresh request.
|
|
158
|
+
pending = null;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// transient — keep polling
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
finally {
|
|
168
|
+
bgPolling = false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Ensure a usable credential. Returns immediately when authed; throws
|
|
173
|
+
* `AuthRequiredError` (with the approval URL) when the user must approve.
|
|
174
|
+
* Never blocks waiting for approval.
|
|
175
|
+
*/
|
|
176
|
+
export async function ensureAuth() {
|
|
177
|
+
if (process.env.APEX_API_KEY)
|
|
178
|
+
return;
|
|
179
|
+
if (!loaded) {
|
|
180
|
+
creds = loadCreds();
|
|
181
|
+
loaded = true;
|
|
182
|
+
}
|
|
183
|
+
if (creds && Date.now() < creds.expiresAt - 60_000)
|
|
184
|
+
return;
|
|
185
|
+
if (creds) {
|
|
186
|
+
if (await tryRefresh())
|
|
187
|
+
return;
|
|
188
|
+
creds = null; // refresh failed — fall through to device flow
|
|
189
|
+
}
|
|
190
|
+
const p = await startDeviceRequest();
|
|
191
|
+
throw new AuthRequiredError(p.verificationUriComplete, p.userCode);
|
|
192
|
+
}
|
|
193
|
+
/** The credential to send (static key, or current device access token). */
|
|
194
|
+
export function getAuthToken() {
|
|
195
|
+
return process.env.APEX_API_KEY ?? creds?.accessToken;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Called after a 401. Try a refresh; if that fails, start a fresh device
|
|
199
|
+
* request and throw `AuthRequiredError` so the tool surfaces the URL.
|
|
200
|
+
* Returns true only when a refresh succeeded and the caller should retry.
|
|
201
|
+
*/
|
|
202
|
+
export async function reauthAfterFailure() {
|
|
203
|
+
if (process.env.APEX_API_KEY)
|
|
204
|
+
return false; // static key — nothing to refresh
|
|
205
|
+
if (await tryRefresh())
|
|
206
|
+
return true;
|
|
207
|
+
creds = null;
|
|
208
|
+
const p = await startDeviceRequest();
|
|
209
|
+
throw new AuthRequiredError(p.verificationUriComplete, p.userCode);
|
|
210
|
+
}
|
|
211
|
+
/** True when we already hold a (possibly stale) credential — used by startup. */
|
|
212
|
+
export function hasStoredCredential() {
|
|
213
|
+
if (process.env.APEX_API_KEY)
|
|
214
|
+
return true;
|
|
215
|
+
if (!loaded) {
|
|
216
|
+
creds = loadCreds();
|
|
217
|
+
loaded = true;
|
|
218
|
+
}
|
|
219
|
+
return creds != null;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,10 @@ server.prompt("experiment-review", "Review experiment results, see what you lear
|
|
|
49
49
|
async function main() {
|
|
50
50
|
const transport = new StdioServerTransport();
|
|
51
51
|
await server.connect(transport);
|
|
52
|
+
// NON-BLOCKING: never wait for browser approval at startup (Cursor treats a
|
|
53
|
+
// server that doesn't become ready quickly as failed). Auth is established
|
|
54
|
+
// lazily on the first tool call, which surfaces the approval URL in chat.
|
|
55
|
+
// discoverContext only runs when we already hold a credential.
|
|
52
56
|
const startupMsg = await discoverContext();
|
|
53
57
|
if (startupMsg) {
|
|
54
58
|
console.error(`[apex] ${startupMsg}`);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAC7C;IACE,YAAY,EAAE;QACZ,gGAAgG;QAChG,gGAAgG;QAChG,uGAAuG;QACvG,6FAA6F;QAC7F,uFAAuF;QACvF,kGAAkG;QAClG,uFAAuF;QACvF,+DAA+D;QAC/D,qFAAqF;QACrF,+EAA+E;KAChF,CAAC,IAAI,CAAC,GAAG,CAAC;CACZ,CACF,CAAC;AAEF,yBAAyB;AAEzB,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;IAC1D,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE;QAC3F,IAAI,CAAC;YACH,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,IAAa,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;gBAC/D,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,6BAA6B;AAE7B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC;IACrD,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,KAAK,IAAI,EAAE;QACtG,OAAO,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,2BAA2B;AAE3B,MAAM,CAAC,MAAM,CACX,gBAAgB,EAChB,+FAA+F,EAC/F,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,EACxE,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,IAA8B,CAAC,CACtF,CAAC;AAEF,MAAM,CAAC,MAAM,CACX,mBAAmB,EACnB,6EAA6E,EAC7E,EAAE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC,EAAE,EACpE,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,IAA8B,CAAC,CACzF,CAAC;AAEF,gBAAgB;AAEhB,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,UAAU,GAAG,MAAM,eAAe,EAAE,CAAC;IAC3C,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,UAAU,UAAU,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,eAAe,EAAE,CAAC;AACpB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|