@nooticr/mcp 1.26.75 → 1.26.76

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/auth.js CHANGED
@@ -225,17 +225,35 @@ export function createManagementTokenProvider(auth) {
225
225
  /**
226
226
  * Builds a TokenProvider for one caller's own API key — the headless path
227
227
  * through HTTP mode, where the bearer the client presented *is* the nooticr
228
- * credential. Deliberately not `createHttpTokenProvider`: that one falls back
229
- * to the operator's environment and credentials file, which would answer one
230
- * tenant's call with another's account.
228
+ * credential. Never the operator's environment or credentials file, which would
229
+ * answer one tenant's call with another's account.
231
230
  */
232
231
  export function createApiKeyTokenProvider(apiKey) {
233
232
  return { getAccessToken: async () => apiKey };
234
233
  }
235
- /** Builds a TokenProvider for HTTP mode: env > api key > file > per-session tokens. */
236
- export function createHttpTokenProvider(auth, session) {
234
+ /**
235
+ * Builds a TokenProvider for one OAuth session in HTTP mode: that session's
236
+ * nooticr tokens and nothing else. The environment and the credentials file
237
+ * belong to whoever runs the server; resolving them here answered every
238
+ * signed-in user as the operator. A refresh updates the session in place, so
239
+ * the next request from the same login carries the new token, and nothing is
240
+ * written to the operator's credentials file.
241
+ */
242
+ export function createSessionTokenProvider(baseUrl, session) {
237
243
  return {
238
- getAccessToken: async () => auth.getAccessToken(session),
239
- onUnauthorized: async () => auth.onUnauthorized(session),
244
+ getAccessToken: async () => session.nooticrAccessToken || undefined,
245
+ onUnauthorized: async () => {
246
+ if (!session.nooticrRefreshToken)
247
+ return false;
248
+ try {
249
+ const next = await NooticrClient.refreshSession(baseUrl, session.nooticrRefreshToken);
250
+ session.nooticrAccessToken = next.accessToken;
251
+ session.nooticrRefreshToken = next.refreshToken ?? session.nooticrRefreshToken;
252
+ return true;
253
+ }
254
+ catch {
255
+ return false;
256
+ }
257
+ },
240
258
  };
241
259
  }
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import { randomUUID } from "node:crypto";
14
14
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
15
15
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
16
16
  import { getBaseUrl, getPublicUrl, getPort, getCredentialsFile, getTransportMode, DEFAULT_PORT, } from "./config.js";
17
- import { AuthManager, NooticrAuthError, createApiKeyTokenProvider, createHttpTokenProvider, createManagementTokenProvider, createStdioTokenProvider, } from "./auth.js";
17
+ import { AuthManager, NooticrAuthError, createApiKeyTokenProvider, createSessionTokenProvider, createManagementTokenProvider, createStdioTokenProvider, } from "./auth.js";
18
18
  import { forwardedHeaders, forwardedSession, looksLikeApiKey } from "./shared/api-key.js";
19
19
  import { NooticrClient, NooticrError } from "./nooticr.js";
20
20
  import { OAuthManager, SCOPES } from "./oauth.js";
@@ -227,9 +227,6 @@ export async function runHttp(port, publicUrl) {
227
227
  client: new NooticrClient(baseUrl, {
228
228
  getAccessToken: async () => undefined,
229
229
  }),
230
- onSession: async (session) => {
231
- await auth.persistSession(session);
232
- },
233
230
  });
234
231
  const state = {
235
232
  oauth,
@@ -239,9 +236,9 @@ export async function runHttp(port, publicUrl) {
239
236
  serverFactory: () => createMcpServer((extra) => {
240
237
  const bearer = extra.authInfo?.token;
241
238
  // A caller who presented their own API key is answered as themselves.
242
- // Falling through to `createHttpTokenProvider` here would resolve the
243
- // *operator's* environment or credentials file instead — one tenant's
244
- // request served from another's account.
239
+ // No branch below falls back to the *operator's* environment or
240
+ // credentials file: that would serve one tenant's request from
241
+ // another's account.
245
242
  if (looksLikeApiKey(bearer)) {
246
243
  return new NooticrClient(baseUrl, createApiKeyTokenProvider(bearer));
247
244
  }
@@ -250,15 +247,13 @@ export async function runHttp(port, publicUrl) {
250
247
  if (forwarded) {
251
248
  return new NooticrClient(baseUrl, createApiKeyTokenProvider(forwarded.token), undefined, forwardedHeaders(forwarded));
252
249
  }
250
+ // An OAuth login of this server: only that session's own tokens.
253
251
  const session = bearer
254
252
  ? oauth.verifyToken(bearer)
255
253
  : undefined;
256
- return new NooticrClient(baseUrl, createHttpTokenProvider(auth, session
257
- ? {
258
- accessToken: session.nooticrAccessToken,
259
- refreshToken: session.nooticrRefreshToken,
260
- }
261
- : undefined));
254
+ return new NooticrClient(baseUrl, session
255
+ ? createSessionTokenProvider(baseUrl, session)
256
+ : { getAccessToken: async () => undefined });
262
257
  }),
263
258
  };
264
259
  const server = http.createServer((req, res) => {
@@ -36,7 +36,7 @@ import { registerAmazonTools } from "./amazon.js";
36
36
  import { registerMarketplaceTools } from "./marketplace.js";
37
37
  import { DEFAULT_NOOTICR_SETTINGS, DEFAULT_SOCIAL_PLATFORMS, MemorySettingsStore, SETTINGS_READ_TOOL, SETTINGS_UPDATE_TOOL, settingsOwnerFromAuth, } from "./settings.js";
38
38
  /** Current MCP server version — bumped on every deploy for traceability. */
39
- export const MCP_SERVER_VERSION = "1.26.75";
39
+ export const MCP_SERVER_VERSION = "1.26.76";
40
40
  /** MCP Apps extension identifier */
41
41
  const UI_EXTENSION = "io.modelcontextprotocol/ui";
42
42
  /** MIME type for MCP Apps HTML resources */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nooticr/mcp",
3
3
  "mcpName": "com.nooticr/mcp",
4
- "version": "1.26.75",
4
+ "version": "1.26.76",
5
5
  "description": "MCP server for nooticr - fetch, discover and understand TikTok/Instagram/YouTube/X/Reddit/LinkedIn/Weibo posts with AI (media metadata, niche discovery, brand monitoring, hook & viral analysis)",
6
6
  "homepage": "https://mcp.nooticr.com",
7
7
  "repository": {