trapic-mcp 0.1.1 → 0.1.3

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.
@@ -964,6 +964,26 @@ switch (command) {
964
964
  case "token":
965
965
  await cmdToken(args[1]);
966
966
  break;
967
+ case "upgrade":
968
+ case "update": {
969
+ const { execSync } = await import("child_process");
970
+ console.log("Checking for updates...");
971
+ try {
972
+ const latest = execSync("npm view trapic-mcp version", { encoding: "utf-8" }).trim();
973
+ const pkg = JSON.parse(await readFile(resolve(__dirname, "../package.json"), "utf-8"));
974
+ if (latest === pkg.version) {
975
+ console.log(`Already on latest version (${pkg.version})`);
976
+ } else {
977
+ console.log(`Upgrading ${pkg.version} → ${latest}...`);
978
+ execSync("npm install -g trapic-mcp@latest", { stdio: "inherit" });
979
+ console.log(`\nUpgraded to ${latest}`);
980
+ }
981
+ } catch (e) {
982
+ console.error("Upgrade failed:", e.message);
983
+ console.log("Try manually: npm install -g trapic-mcp@latest");
984
+ }
985
+ break;
986
+ }
967
987
  default:
968
988
  console.log(`trapic-mcp — CLI & MCP proxy for Trapic
969
989
 
@@ -980,6 +1000,7 @@ Usage:
980
1000
  trapic-mcp token list List API tokens
981
1001
  trapic-mcp token create [name] Create new API token
982
1002
  trapic-mcp token revoke <id> Revoke an API token
1003
+ trapic-mcp upgrade Upgrade to latest version
983
1004
  trapic-mcp serve:dev Start local dev MCP server
984
1005
 
985
1006
  Environment:
package/dist/worker.js CHANGED
@@ -296,21 +296,50 @@ export default {
296
296
  },
297
297
  });
298
298
  }
299
- // OAuth social callback — Supabase redirects here after GitHub/Google login
299
+ // OAuth social callback — client-side page that reads hash fragment token
300
300
  if (url.pathname === "/oauth/callback-social") {
301
- const accessToken = url.hash ? new URLSearchParams(url.hash.slice(1)).get("access_token") : url.searchParams.get("access_token");
301
+ // Serve a small HTML page that extracts access_token from hash and POSTs to server
302
+ const html = `<!DOCTYPE html><html><head><title>Authenticating...</title></head>
303
+ <body style="background:#0a0a0a;color:#e5e5e5;font-family:sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;">
304
+ <div style="text-align:center"><p>Authenticating...</p></div>
305
+ <script>
306
+ (function(){
307
+ var hash = window.location.hash.substring(1);
308
+ var params = new URLSearchParams(hash);
309
+ var accessToken = params.get('access_token');
310
+ var search = new URLSearchParams(window.location.search);
311
+ if (accessToken) {
312
+ // Forward to server endpoint with token in query
313
+ var url = '/oauth/complete-social?access_token=' + encodeURIComponent(accessToken)
314
+ + '&client_id=' + encodeURIComponent(search.get('client_id') || '')
315
+ + '&redirect_uri=' + encodeURIComponent(search.get('redirect_uri') || '')
316
+ + '&state=' + encodeURIComponent(search.get('state') || '')
317
+ + '&code_challenge=' + encodeURIComponent(search.get('code_challenge') || '')
318
+ + '&code_challenge_method=' + encodeURIComponent(search.get('code_challenge_method') || '');
319
+ window.location.replace(url);
320
+ } else {
321
+ document.body.innerHTML = '<div style="text-align:center;padding:2rem;"><p>Authentication failed. Please try again.</p><a href="/" style="color:#60a5fa;">Go back</a></div>';
322
+ }
323
+ })();
324
+ </script></body></html>`;
325
+ return new Response(html, { headers: { "Content-Type": "text/html; charset=utf-8" } });
326
+ }
327
+ // OAuth social complete — server receives access_token, issues auth code
328
+ if (url.pathname === "/oauth/complete-social") {
329
+ const accessToken = url.searchParams.get("access_token") || "";
302
330
  const clientId = url.searchParams.get("client_id") || "";
303
331
  const redirectUri = url.searchParams.get("redirect_uri") || "";
304
332
  const state = url.searchParams.get("state") || "";
305
333
  const codeChallenge = url.searchParams.get("code_challenge") || "";
306
- if (!redirectUri || !codeChallenge) {
307
- return new Response("Missing OAuth parameters", { status: 400 });
334
+ if (!redirectUri || !codeChallenge || !accessToken) {
335
+ return new Response("Missing parameters", { status: 400 });
336
+ }
337
+ if (!isValidRedirectUri(redirectUri)) {
338
+ return new Response("Invalid redirect_uri", { status: 400 });
308
339
  }
309
- // Get user from Supabase access token
310
340
  const supabase = getSupabase();
311
- const { data: { user: authUser }, error: authErr } = await supabase.auth.getUser(accessToken || "");
341
+ const { data: { user: authUser }, error: authErr } = await supabase.auth.getUser(accessToken);
312
342
  if (authErr || !authUser) {
313
- // Redirect back to authorize with error
314
343
  const backUrl = new URL(`${origin}/oauth/authorize`);
315
344
  backUrl.searchParams.set("client_id", clientId);
316
345
  backUrl.searchParams.set("redirect_uri", redirectUri);
@@ -320,7 +349,6 @@ export default {
320
349
  backUrl.searchParams.set("error", "Social login failed. Please try again.");
321
350
  return new Response(null, { status: 302, headers: { "Location": backUrl.toString() } });
322
351
  }
323
- // Generate signed auth code
324
352
  const code = await createAuthCode(env, authUser.id, codeChallenge, redirectUri);
325
353
  const redirectUrl = new URL(redirectUri);
326
354
  redirectUrl.searchParams.set("code", code);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trapic-mcp",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "AI knowledge management MCP server — automatically capture, search, and connect decisions, facts, and conventions across AI coding sessions",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",