mcp-yoto 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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../packages/core/dist/prompts.js","../../../packages/core/dist/yoto/types.js","../../../packages/core/dist/yoto/endpoints.js","../../../packages/core/dist/resources.js","../../../packages/core/dist/errors.js","../../../packages/core/dist/tools/_helpers.js","../../../packages/core/dist/tools/auth.js","../../../packages/core/dist/schemas/index.js","../../../packages/core/dist/tools/library.js","../../../packages/core/dist/tools/content.js","../../../packages/core/dist/tools/devices.js","../../../packages/core/dist/tools/icons.js","../../../packages/core/dist/yoto/media.js","../../../packages/core/dist/tools/media.js","../../../packages/core/dist/tools/index.js","../../../packages/core/dist/auth.js","../../../packages/core/dist/logging.js","../../../packages/core/dist/yoto/client.js","../../../packages/core/dist/index.js","../src/auth/loopback.ts","../src/auth/open-browser.ts","../src/auth/pkce.ts","../src/auth/token-exchange.ts","../src/auth/session.ts","../src/auth/token-store.ts","../src/auth/adapter.ts","../src/config.ts","../src/resolve.ts","../src/server.ts","../src/main.ts"],"names":["z","READ_ONLY_ANNOTATIONS","httpsUrl","defaultSleep","createServer","DEFAULT_ICON_BASE_URL","homedir","resolvePath","readFile","require","createRequire","version"],"mappings":"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","file":"main.js","sourcesContent":["import { z } from \"zod\";\n/**\n * Registers the 2 prompts from the plan: `bedtime_playlist_card` (build a\n * new card from a list of tracks) and `audit_card` (review one card for\n * anything that looks off). Both just draft an instruction for the model\n * to follow using the 14 tools -- neither touches the Yoto API itself.\n */\nexport function registerPrompts(server) {\n server.registerPrompt(\"bedtime_playlist_card\", {\n title: \"Bedtime playlist card\",\n description: \"Draft a new Yoto card from a list of audio files or URLs, ready to upload as a bedtime playlist.\",\n argsSchema: {\n files: z\n .string()\n .describe(\"The audio files/URLs to include, one per line or comma-separated, in play order.\"),\n childName: z\n .string()\n .optional()\n .describe(\"The child's name, for a personalised card title.\"),\n },\n }, async (args) => {\n const childPart = args.childName ? ` for ${args.childName}` : \"\";\n const titleHint = args.childName ? ` mentioning ${args.childName}` : \"\";\n return {\n messages: [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Build a bedtime playlist card${childPart} from these tracks, in order:\\n\\n${args.files}\\n\\n` +\n \"For each one: call yoto_upload_audio (or yoto_add_track once the card exists) to get a \" +\n \"mediaRef, then call yoto_create_card with all the resulting tracks. Give the card a warm, \" +\n `bedtime-appropriate title${titleHint}, and ask before uploading anything.`,\n },\n },\n ],\n };\n });\n server.registerPrompt(\"audit_card\", {\n title: \"Audit a Yoto card\",\n description: \"Review one Yoto card's chapters, tracks and icons for anything that looks off.\",\n argsSchema: {\n cardId: z.string().describe(\"The Yoto card to audit.\"),\n },\n }, async (args) => ({\n messages: [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Call yoto_get_card with cardId \"${args.cardId}\", then check: every chapter has a title and ` +\n \"at least one track; track durations look sensible (not zero, not implausibly long); icons \" +\n \"(icon16x16) are set where it would help a child navigate; chapter and track ordering makes \" +\n \"sense. Report anything worth fixing, and ask before calling yoto_update_card.\",\n },\n },\n ],\n }));\n}\n","/**\n * Zod schemas for Yoto API payloads, shaped against\n * https://yoto.dev/openapi.json (fetched 2026-09-13) plus the fields the old\n * `yoto-mcp-server` was already relying on. Every object schema is\n * `z.looseObject(...)` -- Yoto's API returns plenty of fields we don't model\n * (club availability, cover art, edit settings, ...) and a strict schema\n * would throw those away or reject them outright. We parse, don't trust,\n * but we also don't want an API field Yoto adds tomorrow to break every\n * tool today.\n */\nimport { z } from \"zod\";\nconst displaySchema = z\n .looseObject({ icon16x16: z.string().nullable().optional() })\n .nullable()\n .optional();\nexport const trackSchema = z.looseObject({\n key: z.string(),\n title: z.string(),\n trackUrl: z.string(),\n type: z.string().optional(),\n duration: z.number().optional(),\n fileSize: z.number().optional(),\n channels: z.string().optional(),\n format: z.string().optional(),\n overlayLabel: z.string().optional(),\n display: displaySchema,\n});\nexport const chapterSchema = z.looseObject({\n key: z.string(),\n title: z.string(),\n overlayLabel: z.string().optional(),\n tracks: z.array(trackSchema).default([]),\n duration: z.number().optional(),\n fileSize: z.number().optional(),\n display: displaySchema,\n});\nexport const cardContentSchema = z.looseObject({\n chapters: z.array(chapterSchema).default([]),\n});\n/** A card as it appears in `GET /content/mine` or the full `GET /content/{cardId}`. */\nexport const cardSchema = z.looseObject({\n cardId: z.string(),\n title: z.string(),\n createdAt: z.string().optional(),\n updatedAt: z.string().optional(),\n deleted: z.boolean().optional(),\n content: cardContentSchema.optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n/** Alias kept for callers that only ever see the list shape (same schema -- see module doc). */\nexport const cardListItemSchema = cardSchema;\nexport const listCardsResponseSchema = z.looseObject({ cards: z.array(cardSchema).default([]) });\nexport const getCardResponseSchema = z.looseObject({ card: cardSchema });\nexport const upsertCardResponseSchema = z.looseObject({ card: cardSchema });\nexport const deviceSchema = z.looseObject({\n deviceId: z.string(),\n name: z.string().optional(),\n online: z.boolean().optional(),\n deviceFamily: z.string().optional(),\n deviceType: z.string().optional(),\n releaseChannel: z.string().optional(),\n description: z.string().optional(),\n});\nexport const listDevicesResponseSchema = z.looseObject({\n devices: z.array(deviceSchema).default([]),\n});\n/**\n * Device config is deliberately fully unknown-tolerant: it's a large,\n * beta, frequently-changing bag of player settings (clock face, volume\n * limits, daily/radio links, ...) that this server only ever passes through\n * read-only via `yoto_get_device_config` -- see the plan's scope decision\n * (we don't request `family:devices:manage`, so writes are out of scope).\n */\nexport const deviceConfigSchema = z.record(z.string(), z.unknown());\nexport const getDeviceConfigResponseSchema = z.looseObject({\n device: z\n .looseObject({\n deviceId: z.string().optional(),\n config: deviceConfigSchema.optional(),\n })\n .optional(),\n});\nexport const iconSchema = z.looseObject({\n mediaId: z.string(),\n displayIconId: z.string().optional(),\n title: z.string().optional(),\n url: z.string().optional(),\n publicTags: z.array(z.string()).optional(),\n});\nexport const listPublicIconsResponseSchema = z.looseObject({\n displayIcons: z.array(iconSchema).default([]),\n});\nexport const uploadIconResponseSchema = z.looseObject({ displayIcon: iconSchema });\nexport const familyLibraryGroupSchema = z.looseObject({\n groupId: z.string().optional(),\n name: z.string().optional(),\n});\nexport const listFamilyLibraryResponseSchema = z.looseObject({\n groups: z.array(familyLibraryGroupSchema).default([]),\n});\nexport const uploadUrlResponseSchema = z.looseObject({\n upload: z.looseObject({\n uploadId: z.string(),\n uploadUrl: z.string().nullable(),\n }),\n});\n/**\n * `GET /media/upload/{uploadId}/transcoded` -- undocumented in\n * yoto.dev/openapi.json but proven in production by the old\n * `yoto-mcp-server` (see its `uploadAndTranscodeAudio`). Ported as-is per\n * the plan's instruction to port \"the upload/transcode flow and endpoint\n * knowledge\" from that server.\n */\nexport const transcodedResponseSchema = z.looseObject({\n transcode: z.looseObject({\n transcodedSha256: z.string().optional(),\n transcodedInfo: z\n .looseObject({\n duration: z.number().optional(),\n fileSize: z.number().optional(),\n channels: z.string().optional(),\n format: z.string().optional(),\n })\n .optional(),\n }),\n});\n","/**\n * Thin, typed wrappers around the Yoto endpoints the 14 tools need. Paths\n * and operationIds confirmed against https://yoto.dev/openapi.json\n * (fetched 2026-09-13) except where noted.\n */\nimport { getCardResponseSchema, getDeviceConfigResponseSchema, listCardsResponseSchema, listDevicesResponseSchema, listFamilyLibraryResponseSchema, listPublicIconsResponseSchema, transcodedResponseSchema, uploadIconResponseSchema, uploadUrlResponseSchema, upsertCardResponseSchema, } from \"./types.js\";\n/** GET /content/mine (operationId `getUserSMyoContent`) -- scope `user:content:view`. */\nexport async function listMyCards(client) {\n const result = await client.request({\n method: \"GET\",\n path: \"/content/mine\",\n schema: listCardsResponseSchema,\n });\n return result.cards;\n}\n/** GET /content/{cardId} (operationId `getContent`) -- scope `user:content:view`. */\nexport async function getCard(client, cardId) {\n const result = await client.request({\n method: \"GET\",\n path: `/content/${encodeURIComponent(cardId)}`,\n schema: getCardResponseSchema,\n });\n return result.card;\n}\n/**\n * POST /content (operationId `createOrUpdateContent`) -- scope\n * `user:content:manage`. Creates a card when `body.cardId` is omitted,\n * updates it in place when present. Only retried on 5xx/network when\n * `body.cardId` is set (an update is idempotent; a create is not).\n */\nexport async function upsertCard(client, body) {\n const result = await client.request({\n method: \"POST\",\n path: \"/content\",\n body,\n schema: upsertCardResponseSchema,\n idempotent: typeof body.cardId === \"string\" && body.cardId.length > 0,\n });\n return result.card;\n}\n/** DELETE /content/{cardId} (operationId `deleteContent`) -- scope `user:content:manage`. */\nexport async function deleteCard(client, cardId) {\n await client.request({\n method: \"DELETE\",\n path: `/content/${encodeURIComponent(cardId)}`,\n idempotent: true,\n });\n}\n/** GET /media/displayIcons/user/yoto (operationId `getPublicIcons`) -- scope `user:icons:manage`. */\nexport async function listPublicIcons(client) {\n const result = await client.request({\n method: \"GET\",\n path: \"/media/displayIcons/user/yoto\",\n schema: listPublicIconsResponseSchema,\n });\n return result.displayIcons;\n}\n/**\n * POST /media/displayIcons/user/me/upload (operationId `uploadCustomIcon`) --\n * scope `user:icons:manage`. Takes raw image bytes; the only documented\n * query params are `autoConvert` and `filename` (no `title` field exists on\n * this endpoint, so the tool's `title` input is sent as `filename`).\n */\nexport async function uploadCustomIcon(client, bytes, contentType, options = {}) {\n const result = await client.request({\n method: \"POST\",\n path: \"/media/displayIcons/user/me/upload\",\n query: { autoConvert: options.autoConvert ?? false, filename: options.filename },\n // Wrapped in a Blob rather than passed as a raw Uint8Array: TypeScript's\n // lib.dom BodyInit union doesn't line up with the generic-parameterised\n // Uint8Array<ArrayBufferLike> this project's TS/lib versions infer for a\n // bare `Uint8Array` type, but a Blob sidesteps that friction cleanly and\n // uploads the identical bytes.\n rawBody: new Blob([bytes]),\n contentType,\n schema: uploadIconResponseSchema,\n });\n return result.displayIcon;\n}\n/** GET /device-v2/devices/mine (operationId `getDevices`) -- scope `family:devices:view`. */\nexport async function listDevices(client) {\n const result = await client.request({\n method: \"GET\",\n path: \"/device-v2/devices/mine\",\n schema: listDevicesResponseSchema,\n });\n return result.devices;\n}\n/**\n * GET /device-v2/{deviceId}/config (operationId `getDeviceConfig`) -- scope\n * `family:devices:manage`, which this server never requests (see\n * auth.ts's YOTO_SCOPES). Expect a FORBIDDEN_SCOPE YotoError from\n * YotoClient in practice; tools/devices.ts turns that into a friendly hint.\n */\nexport async function getDeviceConfig(client, deviceId) {\n const result = await client.request({\n method: \"GET\",\n path: `/device-v2/${encodeURIComponent(deviceId)}/config`,\n schema: getDeviceConfigResponseSchema,\n });\n return result.device?.config ?? {};\n}\n/** GET /card/family/library/groups (operationId `getGroups`) -- scope `family:library:view`. */\nexport async function listFamilyLibrary(client) {\n const result = await client.request({\n method: \"GET\",\n path: \"/card/family/library/groups\",\n schema: listFamilyLibraryResponseSchema,\n });\n return result.groups;\n}\n/** GET /media/transcode/audio/uploadUrl (operationId `getAnUploadUrl`) -- scope `user:content:manage`. */\nexport async function getUploadUrl(client, options = {}) {\n return client.request({\n method: \"GET\",\n path: \"/media/transcode/audio/uploadUrl\",\n query: options,\n schema: uploadUrlResponseSchema,\n });\n}\n/**\n * GET /media/upload/{uploadId}/transcoded -- NOT in yoto.dev/openapi.json,\n * but proven in production by the old `yoto-mcp-server` (its\n * `uploadAndTranscodeAudio` polls this exact path). Ported per the plan's\n * instruction to carry over known-good endpoint behaviour the public spec\n * doesn't document.\n */\nexport async function getTranscodedStatus(client, uploadId, loudnorm) {\n return client.request({\n method: \"GET\",\n path: `/media/upload/${encodeURIComponent(uploadId)}/transcoded`,\n query: { loudnorm },\n schema: transcodedResponseSchema,\n idempotent: true,\n });\n}\n","import { ResourceTemplate } from \"@modelcontextprotocol/server\";\nimport { getCard, listMyCards, listPublicIcons } from \"./yoto/endpoints.js\";\n/**\n * Registers the 3 read-only resources from the plan: `yoto://cards`,\n * `yoto://card/{cardId}`, and `yoto://icons/public`. All three are thin\n * JSON views over the same endpoints the tools use -- useful for a client\n * that wants to browse context without making a tool call.\n */\nexport function registerResources(server, deps) {\n server.registerResource(\"yoto-cards\", \"yoto://cards\", {\n title: \"Your Yoto cards\",\n description: \"The signed-in parent's MYO (Make Your Own) cards.\",\n mimeType: \"application/json\",\n }, async (uri) => {\n const cards = await listMyCards(deps.client);\n return {\n contents: [\n {\n uri: uri.toString(),\n mimeType: \"application/json\",\n text: JSON.stringify(cards, null, 2),\n },\n ],\n };\n });\n server.registerResource(\"yoto-card\", new ResourceTemplate(\"yoto://card/{cardId}\", { list: undefined }), {\n title: \"A Yoto card\",\n description: \"One card's full details -- every chapter and track.\",\n mimeType: \"application/json\",\n }, async (uri, variables) => {\n const cardId = Array.isArray(variables.cardId) ? variables.cardId[0] : variables.cardId;\n const card = await getCard(deps.client, String(cardId));\n return {\n contents: [\n {\n uri: uri.toString(),\n mimeType: \"application/json\",\n text: JSON.stringify(card, null, 2),\n },\n ],\n };\n });\n server.registerResource(\"yoto-icons-public\", \"yoto://icons/public\", {\n title: \"Yoto's public icon catalogue\",\n description: \"Searchable 16x16 pixel-art icons available to every account.\",\n mimeType: \"application/json\",\n }, async (uri) => {\n const icons = await listPublicIcons(deps.client);\n return {\n contents: [\n {\n uri: uri.toString(),\n mimeType: \"application/json\",\n text: JSON.stringify(icons, null, 2),\n },\n ],\n };\n });\n}\n","export class YotoError extends Error {\n code;\n retryable;\n hint;\n status;\n constructor(message, options) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = \"YotoError\";\n this.code = options.code;\n this.retryable = options.retryable ?? false;\n this.hint = options.hint;\n this.status = options.status;\n }\n}\nexport function isYotoError(value) {\n return value instanceof YotoError;\n}\nexport function toToolResult(error) {\n if (isYotoError(error)) {\n const suffix = error.hint ? ` (${error.hint})` : \"\";\n return {\n isError: true,\n content: [{ type: \"text\", text: `${error.code}: ${error.message}${suffix}` }],\n structuredContent: { code: error.code, message: error.message, hint: error.hint },\n };\n }\n const message = error instanceof Error ? error.message : String(error);\n return {\n isError: true,\n content: [{ type: \"text\", text: `UPSTREAM_ERROR: ${message}` }],\n structuredContent: { code: \"UPSTREAM_ERROR\", message },\n };\n}\n","import { isYotoError, toToolResult, YotoError } from \"../errors.js\";\nexport const DEFAULT_ICON_BASE_URL = \"https://raw.githubusercontent.com/danpillay87/mcp-yoto/main/apps/worker/public/icons\";\n/**\n * Registers one tool spec onto a real `McpServer`, matching the actual SDK\n * v2 `registerTool(name, config, cb)` API (confirmed against\n * node_modules/@modelcontextprotocol/server/dist/mcp-*.mjs): `config` takes\n * `{title, description, inputSchema, outputSchema, annotations, icons}` and\n * `inputSchema`/`outputSchema` accept a `z.object({...})` directly (no raw\n * shape needed -- `normalizeRawShapeSchema` inside the SDK accepts either).\n *\n * The SDK validates input against `inputSchema` and, on success, skips its\n * own output validation whenever the handler returns `isError: true` (see\n * `McpServer.validateToolOutput`) -- so returning a `YotoError`-shaped\n * result from a tool with an `outputSchema` is safe. Business-rule\n * failures the input schema itself can't express (e.g. \"confirm must be\n * true\") are surfaced as our own `VALIDATION` `YotoError`, not the SDK's\n * generic schema-mismatch error.\n */\nexport function defineTool(server, spec, deps) {\n const iconBaseUrl = deps.iconBaseUrl ?? DEFAULT_ICON_BASE_URL;\n // Cast to a looser call signature at this one boundary: the real SDK's\n // `registerTool` overloads resolve a generic `TInput`/`TOutput` pair from\n // its own type parameters, which fights a *wrapper* function that is\n // itself generic over the same kind of schema. The runtime call is\n // unchanged (config/callback shapes match the SDK exactly, verified by\n // the contract test actually driving `tools/list`/`tools/call` over\n // `InMemoryTransport`) -- this only relaxes what the compiler checks here.\n const registerTool = server.registerTool.bind(server);\n registerTool(spec.name, {\n title: spec.title,\n description: spec.description,\n inputSchema: spec.inputSchema,\n outputSchema: spec.outputSchema,\n annotations: spec.annotations,\n icons: [{ src: `${iconBaseUrl}/${spec.group}.png`, mimeType: \"image/png\", sizes: [\"64x64\"] }],\n }, async (args) => {\n try {\n const output = await spec.handler(args, { logger: deps.logger });\n const text = spec.summary(output, args);\n return { content: [{ type: \"text\", text }], structuredContent: output };\n }\n catch (error) {\n if (isYotoError(error))\n return toToolResult(error);\n deps.logger.error(`Tool ${spec.name} failed unexpectedly`, {\n error: error instanceof Error ? error.message : String(error),\n });\n return toToolResult(new YotoError(error instanceof Error ? error.message : String(error), {\n code: \"UPSTREAM_ERROR\",\n }));\n }\n });\n}\n","import { z } from \"zod\";\nimport { YotoError } from \"../errors.js\";\nimport { listMyCards } from \"../yoto/endpoints.js\";\nconst READ_ONLY_ANNOTATIONS = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n};\nexport function createAuthTools(deps) {\n const yotoStatus = {\n name: \"yoto_status\",\n title: \"Check Yoto sign-in status\",\n description: \"Reports whether this connection is signed in to Yoto, which mode it's running in \" +\n \"(cli or remote), where the credential is stored, its granted scopes, and whether \" +\n \"the Yoto API is currently reachable.\",\n group: \"auth\",\n annotations: READ_ONLY_ANNOTATIONS,\n inputSchema: z.object({}),\n outputSchema: z.object({\n signedIn: z.boolean(),\n mode: z.enum([\"cli\", \"remote\"]),\n tokenStore: z.enum([\"keychain\", \"file\", \"remote\"]).optional(),\n expiresAt: z.number().optional(),\n scopes: z.array(z.string()).optional(),\n hint: z.string().optional(),\n apiReachable: z.boolean().optional(),\n }),\n summary: (output) => output.signedIn\n ? `Signed in to Yoto (${output.mode} mode)${output.apiReachable === false ? \" -- API unreachable right now\" : \"\"}.`\n : `Not signed in to Yoto.${output.hint ? ` ${output.hint}` : \"\"}`,\n handler: async () => {\n const status = await deps.auth.status();\n let apiReachable;\n if (status.signedIn) {\n try {\n await listMyCards(deps.client);\n apiReachable = true;\n }\n catch {\n apiReachable = false;\n }\n }\n return { ...status, apiReachable };\n },\n };\n const yotoSignIn = {\n name: \"yoto_sign_in\",\n title: \"Sign in to Yoto\",\n description: \"CLI mode: launches a local PKCE sign-in flow (opens your browser to Yoto's login \" +\n \"page and waits for the callback). Remote mode: this connector runs on a server \" +\n \"with nothing to launch, so it returns instructions to sign in from your AI client's \" +\n \"connector settings instead -- that flow redirects to Yoto's own login page too.\",\n group: \"auth\",\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n inputSchema: z.object({\n openBrowser: z\n .boolean()\n .optional()\n .describe(\"CLI only: open the sign-in URL automatically. Default true.\"),\n }),\n outputSchema: z.object({\n url: z.string().optional(),\n message: z.string(),\n }),\n // Include the URL in the tool's text, not just structuredContent.url --\n // an MCP client typically only renders the text back to the human, and\n // that's the one thing a headless/no-default-browser box needs to see.\n summary: (output) => (output.url ? `${output.message}\\n\\n${output.url}` : output.message),\n handler: async (args) => {\n if (deps.mode === \"remote\") {\n return {\n message: \"This is a remote connector -- sign in from your AI client's connector/integration \" +\n \"settings, which redirects you to Yoto's own login page. There's nothing to run here.\",\n };\n }\n if (!deps.auth.signIn) {\n throw new YotoError(\"Sign-in isn't available on this connection.\", {\n code: \"UNSUPPORTED_IN_MODE\",\n });\n }\n return deps.auth.signIn({ openBrowser: args.openBrowser });\n },\n };\n const yotoSignOut = {\n name: \"yoto_sign_out\",\n title: \"Sign out of Yoto\",\n description: \"CLI mode: deletes the locally stored Yoto credential (keychain or file). Remote \" +\n \"mode: this server never stores your Yoto token at all, so it returns instructions \" +\n \"for disconnecting from your AI client and revoking access at Yoto directly. \" +\n \"Requires confirm: true.\",\n group: \"auth\",\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: true,\n },\n inputSchema: z.object({\n confirm: z.boolean().describe(\"Must be true -- this clears your stored Yoto credential.\"),\n }),\n outputSchema: z.object({ message: z.string() }),\n summary: (output) => output.message,\n handler: async (args) => {\n if (!args.confirm) {\n throw new YotoError(\"Pass confirm: true to sign out.\", {\n code: \"VALIDATION\",\n hint: \"This clears your locally stored Yoto credential.\",\n });\n }\n if (deps.mode === \"remote\") {\n return {\n message: \"This server never stores your Yoto token -- disconnect it from your AI client's \" +\n \"connector settings, and optionally revoke access in your Yoto account's security settings.\",\n };\n }\n if (!deps.auth.signOut) {\n throw new YotoError(\"Sign-out isn't available on this connection.\", {\n code: \"UNSUPPORTED_IN_MODE\",\n });\n }\n await deps.auth.signOut();\n return { message: \"Signed out of Yoto. Run yoto_sign_in to reconnect.\" };\n },\n };\n return [yotoStatus, yotoSignIn, yotoSignOut];\n}\n","import { z } from \"zod\";\n/**\n * Placeholder schemas for Phase 0. The real Yoto content/card/device/icon\n * schemas that back all 14 `yoto_*` tools land in Phase 1\n * (packages/core/src/yoto/types.ts), built out alongside YotoClient.\n */\nexport const cardIdSchema = z.string().min(1, \"cardId must not be empty\");\n","/**\n * Family-library support for `yoto_list_cards(source: \"family\")`. Kept\n * separate from tools/content.ts (which owns the 5 MYO-card tools) per the\n * plan's repo layout (`src/tools/{..., library}.ts`) since a family\n * \"group\" is a different shape from a MYO card -- a shared collection, not\n * something you can hand to `yoto_get_card`.\n */\nimport { z } from \"zod\";\nimport { listFamilyLibrary } from \"../yoto/endpoints.js\";\nimport { familyLibraryGroupSchema } from \"../yoto/types.js\";\nexport const familyLibrarySummarySchema = z.object({\n groups: z.array(familyLibraryGroupSchema),\n note: z.string(),\n});\nconst FAMILY_LIBRARY_NOTE = \"Family library groups are shared collections, not individual MYO cards -- \" +\n 'use yoto_get_card only with a cardId from source: \"myo\".';\nexport async function summariseFamilyLibrary(client) {\n const groups = await listFamilyLibrary(client);\n return { groups, note: FAMILY_LIBRARY_NOTE };\n}\n","import { z } from \"zod\";\nimport { YotoError } from \"../errors.js\";\nimport { cardIdSchema } from \"../schemas/index.js\";\nimport { deleteCard, getCard, listMyCards, upsertCard } from \"../yoto/endpoints.js\";\nimport { cardSchema } from \"../yoto/types.js\";\nimport { summariseFamilyLibrary } from \"./library.js\";\nexport function createContentTools(deps) {\n const yotoListCards = {\n name: \"yoto_list_cards\",\n title: \"List your Yoto cards\",\n description: \"Lists cards in your own MYO (Make Your Own) library, or the shared family \" +\n \"library's groups. Family groups are collections, not individual cards -- see \" +\n 'the returned note when source is \"family\".',\n group: \"content\",\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n inputSchema: z.object({\n source: z.enum([\"myo\", \"family\"]).default(\"myo\"),\n limit: z.number().int().positive().max(200).optional(),\n cursor: z.string().optional().describe(\"Reserved for future pagination; currently unused.\"),\n }),\n outputSchema: z.object({\n source: z.enum([\"myo\", \"family\"]),\n cards: z.array(cardSchema).optional(),\n groups: z\n .array(z.looseObject({ groupId: z.string().optional(), name: z.string().optional() }))\n .optional(),\n note: z.string().optional(),\n }),\n summary: (output) => output.source === \"family\"\n ? `${output.groups?.length ?? 0} family library group(s).`\n : `${output.cards?.length ?? 0} card(s) in your MYO library.`,\n handler: async (args) => {\n if (args.source === \"family\") {\n const { groups, note } = await summariseFamilyLibrary(deps.client);\n return { source: \"family\", groups, note };\n }\n const cards = await listMyCards(deps.client);\n return { source: \"myo\", cards: args.limit ? cards.slice(0, args.limit) : cards };\n },\n };\n const yotoGetCard = {\n name: \"yoto_get_card\",\n title: \"Get a Yoto card's details\",\n description: \"Fetches one MYO card's full details, including every chapter and track.\",\n group: \"content\",\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n inputSchema: z.object({ cardId: cardIdSchema }),\n outputSchema: z.object({ card: cardSchema }),\n summary: (output) => `\"${output.card.title}\" -- ${output.card.content?.chapters.length ?? 0} chapter(s).`,\n handler: async (args) => ({ card: await getCard(deps.client, args.cardId) }),\n };\n const yotoCreateCard = {\n name: \"yoto_create_card\",\n title: \"Create a new Yoto card\",\n description: \"Creates a new MYO card with the given title, and optionally an initial set of \" +\n \"tracks (each a mediaRef from yoto_upload_audio, one track per chapter) and a \" +\n \"default icon for those chapters.\",\n group: \"content\",\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n inputSchema: z.object({\n title: z.string().min(1),\n tracks: z\n .array(z.object({\n mediaRef: z\n .string()\n .min(1)\n .describe(\"A yoto:#<sha256> reference from yoto_upload_audio.\"),\n title: z.string().optional(),\n }))\n .optional(),\n iconRef: z\n .string()\n .optional()\n .describe(\"A yoto:#<mediaId> icon reference, e.g. from yoto_upload_icon.\"),\n }),\n outputSchema: z.object({ card: cardSchema }),\n summary: (output) => `Created \"${output.card.title}\" (${output.card.cardId}).`,\n handler: async (args) => {\n const tracks = args.tracks ?? [];\n const chapters = tracks.map((track, index) => {\n const key = String(index + 1).padStart(2, \"0\");\n const title = track.title ?? args.title;\n return {\n key,\n title,\n overlayLabel: String(index + 1),\n ...(args.iconRef ? { display: { icon16x16: args.iconRef } } : {}),\n tracks: [\n {\n key,\n title,\n trackUrl: track.mediaRef,\n type: \"audio\",\n overlayLabel: String(index + 1),\n ...(args.iconRef ? { display: { icon16x16: args.iconRef } } : {}),\n },\n ],\n };\n });\n const card = await upsertCard(deps.client, { title: args.title, content: { chapters } });\n return { card };\n },\n };\n const yotoUpdateCard = {\n name: \"yoto_update_card\",\n title: \"Update a Yoto card\",\n description: \"Shallow-merges patch fields (e.g. title, or a full replacement content.chapters \" +\n \"array to rename/reorder tracks or set icons) onto an existing card, then saves it.\",\n group: \"content\",\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: true,\n },\n inputSchema: z.object({\n cardId: cardIdSchema,\n patch: z\n .record(z.string(), z.unknown())\n .describe(\"Fields to merge onto the existing card, e.g. { title } or { content }.\"),\n }),\n outputSchema: z.object({ card: cardSchema }),\n summary: (output) => `Updated \"${output.card.title}\" (${output.card.cardId}).`,\n handler: async (args) => {\n const existing = await getCard(deps.client, args.cardId);\n const merged = { ...existing, ...args.patch, cardId: args.cardId };\n const card = await upsertCard(deps.client, merged);\n return { card };\n },\n };\n const yotoDeleteCard = {\n name: \"yoto_delete_card\",\n title: \"Delete a Yoto card\",\n description: \"Permanently deletes a MYO card from the parent's Yoto library. Requires confirm: true.\",\n group: \"content\",\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: true,\n },\n inputSchema: z.object({\n cardId: cardIdSchema,\n confirm: z.boolean().describe(\"Must be true -- this permanently deletes the card.\"),\n }),\n outputSchema: z.object({ cardId: z.string(), deleted: z.boolean() }),\n summary: (output) => `Deleted card ${output.cardId}.`,\n handler: async (args) => {\n if (!args.confirm) {\n throw new YotoError(\"Pass confirm: true to delete this card.\", {\n code: \"VALIDATION\",\n hint: \"This permanently deletes the card from the parent's Yoto library.\",\n });\n }\n await deleteCard(deps.client, args.cardId);\n return { cardId: args.cardId, deleted: true };\n },\n };\n return [yotoListCards, yotoGetCard, yotoCreateCard, yotoUpdateCard, yotoDeleteCard];\n}\n","import { z } from \"zod\";\nimport { isYotoError, YotoError } from \"../errors.js\";\nimport { getDeviceConfig, listDevices } from \"../yoto/endpoints.js\";\nimport { deviceSchema } from \"../yoto/types.js\";\nconst READ_ONLY_ANNOTATIONS = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n};\nexport function createDeviceTools(deps) {\n const yotoListDevices = {\n name: \"yoto_list_devices\",\n title: \"List your Yoto devices\",\n description: \"Lists the family's Yoto players -- name, online status, and device type. View-only.\",\n group: \"devices\",\n annotations: READ_ONLY_ANNOTATIONS,\n inputSchema: z.object({}),\n outputSchema: z.object({ devices: z.array(deviceSchema) }),\n summary: (output) => `${output.devices.length} device(s).`,\n handler: async () => ({ devices: await listDevices(deps.client) }),\n };\n const yotoGetDeviceConfig = {\n name: \"yoto_get_device_config\",\n title: \"Get a Yoto device's configuration\",\n description: \"Fetches one player's device configuration (clock face, volume limits, right-hand-\" +\n \"button shortcuts, etc). This is a beta Yoto endpoint that needs a device-management \" +\n \"scope this server intentionally never requests, so expect a FORBIDDEN_SCOPE result \" +\n \"with a hint rather than data.\",\n group: \"devices\",\n annotations: READ_ONLY_ANNOTATIONS,\n inputSchema: z.object({ deviceId: z.string().min(1) }),\n outputSchema: z.object({ config: z.record(z.string(), z.unknown()) }),\n summary: () => \"Fetched device configuration.\",\n handler: async (args) => {\n try {\n return { config: await getDeviceConfig(deps.client, args.deviceId) };\n }\n catch (error) {\n if (isYotoError(error) && error.code === \"FORBIDDEN_SCOPE\") {\n throw new YotoError(\"Device configuration needs a scope this connection doesn't have.\", {\n code: \"FORBIDDEN_SCOPE\",\n status: error.status,\n hint: \"Yoto's device-config endpoint is in beta and requires family:devices:manage, \" +\n \"which this server deliberately doesn't request (it only asks for \" +\n \"family:devices:view, to stay eligible for Yoto's Verified listing). Use the \" +\n \"Yoto app's right-hand-button shortcuts screen instead.\",\n });\n }\n throw error;\n }\n },\n };\n return [yotoListDevices, yotoGetDeviceConfig];\n}\n","import { z } from \"zod\";\nimport { listPublicIcons, uploadCustomIcon } from \"../yoto/endpoints.js\";\nimport { iconSchema } from \"../yoto/types.js\";\nconst httpsUrl = z\n .string()\n .url()\n .refine((value) => value.startsWith(\"https://\"), { message: \"Must be an https:// URL.\" });\nexport function createIconTools(deps) {\n const yotoSearchIcons = {\n name: \"yoto_search_icons\",\n title: \"Search Yoto's icon catalogue\",\n description: \"Searches Yoto's public catalogue of 16x16 pixel-art icons by title or tag, for use \" +\n \"as a chapter/track icon (iconRef) when creating or updating a card.\",\n group: \"icons\",\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n inputSchema: z.object({\n query: z.string().optional().describe(\"Free-text match against the icon's title and tags.\"),\n tags: z.array(z.string()).optional().describe(\"Icon must carry every one of these tags.\"),\n limit: z.number().int().positive().max(100).optional(),\n }),\n outputSchema: z.object({ icons: z.array(iconSchema) }),\n summary: (output) => `${output.icons.length} icon(s) found.`,\n handler: async (args) => {\n const all = await listPublicIcons(deps.client);\n let filtered = all;\n if (args.query) {\n const query = args.query.toLowerCase();\n filtered = filtered.filter((icon) => icon.title?.toLowerCase().includes(query) ||\n icon.publicTags?.some((tag) => tag.toLowerCase().includes(query)));\n }\n if (args.tags?.length) {\n const wantedTags = args.tags;\n filtered = filtered.filter((icon) => wantedTags.every((tag) => icon.publicTags?.includes(tag)));\n }\n return { icons: args.limit ? filtered.slice(0, args.limit) : filtered };\n },\n };\n const imageInputShape = deps.mode === \"cli\"\n ? {\n imagePath: z\n .string()\n .min(1)\n .describe(\"Absolute path to a local image file (PNG, JPEG, or SVG).\"),\n }\n : {\n imageUrl: httpsUrl.describe(\"An https:// URL to an image file (PNG, JPEG, or SVG) -- this connector runs \" +\n \"remotely, so give a link, not a file path.\"),\n };\n const yotoUploadIcon = {\n name: \"yoto_upload_icon\",\n title: \"Upload a custom Yoto icon\",\n description: \"Uploads a custom 16x16 pixel-art icon to your Yoto account, returning a mediaId \" +\n \"usable as an iconRef on cards and tracks. \" +\n (deps.mode === \"cli\"\n ? \"Runs locally, so it takes a file path.\"\n : \"This connector runs remotely, so it takes a link, not a file path.\"),\n group: \"icons\",\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n inputSchema: z.object({\n ...imageInputShape,\n title: z.string().min(1).describe(\"Sent to Yoto as the uploaded file's name.\"),\n autoConvert: z\n .boolean()\n .optional()\n .describe(\"Let Yoto auto-convert the image to its 16x16 icon format. Default false.\"),\n }),\n outputSchema: z.object({ mediaId: z.string(), url: z.string().optional() }),\n summary: (output) => `Uploaded icon -- ${output.mediaId}.`,\n handler: async (args) => {\n const input = deps.mode === \"cli\" ? { imagePath: args.imagePath } : { imageUrl: args.imageUrl };\n const image = await deps.resolveImage(input);\n const icon = await uploadCustomIcon(deps.client, image.bytes, image.contentType, {\n filename: args.title,\n autoConvert: args.autoConvert,\n });\n return { mediaId: icon.mediaId, url: icon.url };\n },\n };\n return [yotoSearchIcons, yotoUploadIcon];\n}\n","import { YotoError } from \"../errors.js\";\nimport { getTranscodedStatus, getUploadUrl } from \"./endpoints.js\";\nfunction defaultSleep(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n/**\n * `GET uploadUrl` -> `PUT` the bytes -> poll `GET .../transcoded` until\n * `transcodedSha256` shows up. Mirrors the old `yoto-mcp-server`'s\n * `uploadAndTranscodeAudio`, generalised to stream from either a local file\n * (CLI) or a fetched remote URL (Worker) via the injected `AudioSource`.\n */\nexport async function uploadAudio(client, source, options = {}) {\n const pollIntervalMs = options.pollIntervalMs ?? 750;\n const timeoutMs = options.timeoutMs ?? 60_000;\n const loudnorm = options.loudnorm ?? false;\n const now = options.now ?? (() => Date.now());\n const sleep = options.sleep ?? defaultSleep;\n const { upload } = await getUploadUrl(client, { filename: source.filename });\n if (upload.uploadUrl) {\n const putHeaders = { \"Content-Type\": source.contentType };\n const putResponse = await client.fetchImpl(upload.uploadUrl, {\n method: \"PUT\",\n // `duplex: \"half\"` is required by fetch implementations (undici, the\n // Workers runtime) to stream a body, but isn't in lib.dom's RequestInit\n // type yet.\n // biome-ignore lint/suspicious/noExplicitAny: streaming-body fetch option missing from lib.dom types.\n ...{ duplex: \"half\" },\n body: source.stream,\n headers: putHeaders,\n });\n if (!putResponse.ok) {\n throw new YotoError(`Uploading audio to Yoto's storage failed (HTTP ${putResponse.status})`, {\n code: \"UPSTREAM_ERROR\",\n retryable: true,\n status: putResponse.status,\n });\n }\n }\n // `uploadUrl: null` means Yoto already has a file matching this content's\n // SHA256 (dedup) -- nothing to PUT, go straight to polling transcode status.\n const deadline = now() + timeoutMs;\n for (;;) {\n const status = await getTranscodedStatus(client, upload.uploadId, loudnorm);\n const sha = status.transcode.transcodedSha256;\n if (sha) {\n return { mediaRef: `yoto:#${sha}`, transcodedInfo: status.transcode.transcodedInfo ?? {} };\n }\n if (now() >= deadline) {\n throw new YotoError(\"Yoto didn't finish transcoding the audio in time\", {\n code: \"TRANSCODE_TIMEOUT\",\n retryable: true,\n hint: \"Try again, or upload a shorter/smaller file.\",\n });\n }\n await sleep(pollIntervalMs);\n }\n}\nfunction bytesStartWith(bytes, offset, pattern) {\n if (bytes.length < offset + pattern.length)\n return false;\n for (let i = 0; i < pattern.length; i++) {\n if (bytes[offset + i] !== pattern[i])\n return false;\n }\n return true;\n}\nconst ASCII = (text) => Array.from(text, (c) => c.charCodeAt(0));\n/**\n * Sniffs an audio file's real format from its first bytes, independent of\n * whatever extension the filename claims -- so a `.txt` renamed to `.mp3`\n * fails fast as INVALID_AUDIO before any network call, per the plan's\n * verification checklist.\n */\nexport function sniffAudio(bytes, filename) {\n if (bytesStartWith(bytes, 0, ASCII(\"ID3\")))\n return { valid: true, format: \"mp3\" };\n if (bytes.length >= 2 && bytes[0] === 0xff && ((bytes[1] ?? 0) & 0xe0) === 0xe0)\n return { valid: true, format: \"mp3\" };\n if (bytesStartWith(bytes, 4, ASCII(\"ftyp\")))\n return { valid: true, format: \"m4a\" };\n if (bytesStartWith(bytes, 0, ASCII(\"RIFF\")) && bytesStartWith(bytes, 8, ASCII(\"WAVE\"))) {\n return { valid: true, format: \"wav\" };\n }\n if (bytesStartWith(bytes, 0, ASCII(\"OggS\")))\n return { valid: true, format: \"ogg\" };\n throw new YotoError(`Could not recognise${filename ? ` \"${filename}\"` : \" this file\"} as a supported audio format`, { code: \"INVALID_AUDIO\", hint: \"Supported formats: MP3, M4A/AAC, WAV, OGG.\" });\n}\n/** Sniffs an image's real format from its first bytes for icon uploads. */\nexport function sniffImage(bytes, filename) {\n if (bytesStartWith(bytes, 0, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) {\n return { valid: true, format: \"png\" };\n }\n if (bytesStartWith(bytes, 0, [0xff, 0xd8, 0xff]))\n return { valid: true, format: \"jpeg\" };\n const head = new TextDecoder(\"utf-8\", { fatal: false })\n .decode(bytes.slice(0, 256))\n .trimStart()\n .toLowerCase();\n if (head.startsWith(\"<?xml\") || head.startsWith(\"<svg\"))\n return { valid: true, format: \"svg\" };\n throw new YotoError(`Could not recognise${filename ? ` \"${filename}\"` : \" this file\"} as a supported image format`, { code: \"INVALID_IMAGE\", hint: \"Supported formats: PNG, JPEG, SVG.\" });\n}\n","import { z } from \"zod\";\nimport { cardIdSchema } from \"../schemas/index.js\";\nimport { getCard, upsertCard } from \"../yoto/endpoints.js\";\nimport { uploadAudio } from \"../yoto/media.js\";\nimport { cardSchema } from \"../yoto/types.js\";\nconst httpsUrl = z\n .string()\n .url()\n .refine((value) => value.startsWith(\"https://\"), { message: \"Must be an https:// URL.\" });\n/**\n * Mode-aware media input: the CLI can read a local file, so it exposes\n * `audioFilePath`; the remote connector has no filesystem, so it exposes\n * `audioUrl` instead (declared openly in each tool's description, per the\n * plan's correction that claude.ai/ChatGPT uploads take a URL, not a path).\n */\nfunction audioInputSchema(mode) {\n return mode === \"cli\"\n ? z.object({\n audioFilePath: z\n .string()\n .min(1)\n .describe(\"Absolute path to a local audio file (MP3, M4A/AAC, WAV, or OGG).\"),\n })\n : z.object({\n audioUrl: httpsUrl.describe(\"An https:// URL to an audio file (MP3, M4A/AAC, WAV, or OGG) -- this connector \" +\n \"runs remotely, so give a link, not a file path.\"),\n });\n}\nfunction toAudioInput(mode, args) {\n return mode === \"cli\"\n ? { audioFilePath: args.audioFilePath }\n : { audioUrl: args.audioUrl };\n}\nexport function createMediaTools(deps) {\n const yotoUploadAudio = {\n name: \"yoto_upload_audio\",\n title: \"Upload audio to Yoto\",\n description: \"Uploads an audio file to Yoto and waits for it to finish transcoding, returning a \" +\n \"yoto:#<sha256> mediaRef usable as a track when creating or updating a card. \" +\n (deps.mode === \"cli\"\n ? \"Runs locally, so it takes a file path.\"\n : \"This connector runs remotely, so it takes a link, not a file path.\"),\n group: \"media\",\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n inputSchema: audioInputSchema(deps.mode).extend({\n loudnorm: z.boolean().optional().describe(\"Apply loudness normalisation. Default false.\"),\n }),\n outputSchema: z.object({\n mediaRef: z.string(),\n duration: z.number().optional(),\n fileSize: z.number().optional(),\n format: z.string().optional(),\n }),\n summary: (output) => `Uploaded audio -- ${output.mediaRef}${output.duration ? ` (${output.duration}s)` : \"\"}.`,\n handler: async (args) => {\n const source = await deps.resolveAudio(toAudioInput(deps.mode, args));\n const result = await uploadAudio(deps.client, source, { loudnorm: args.loudnorm });\n return {\n mediaRef: result.mediaRef,\n duration: result.transcodedInfo.duration,\n fileSize: result.transcodedInfo.fileSize,\n format: result.transcodedInfo.format,\n };\n },\n };\n const yotoAddTrack = {\n name: \"yoto_add_track\",\n title: \"Add a track to a Yoto card\",\n description: \"Uploads an audio file and appends it as a new chapter/track on an existing MYO card. \" +\n (deps.mode === \"cli\"\n ? \"Runs locally, so it takes a file path.\"\n : \"This connector runs remotely, so it takes a link, not a file path.\"),\n group: \"media\",\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n inputSchema: audioInputSchema(deps.mode).extend({\n cardId: cardIdSchema,\n trackTitle: z.string().optional(),\n iconRef: z\n .string()\n .optional()\n .describe(\"A yoto:#<mediaId> icon reference, e.g. from yoto_upload_icon.\"),\n }),\n outputSchema: z.object({ card: cardSchema }),\n summary: (output) => `Added a track to \"${output.card.title}\" (${output.card.cardId}).`,\n handler: async (args) => {\n const source = await deps.resolveAudio(toAudioInput(deps.mode, args));\n const uploaded = await uploadAudio(deps.client, source);\n const existing = await getCard(deps.client, args.cardId);\n const chapters = existing.content?.chapters ?? [];\n const nextNumber = chapters.length + 1;\n const key = String(nextNumber).padStart(2, \"0\");\n const title = args.trackTitle ?? source.filename ?? `Track ${nextNumber}`;\n const newChapter = {\n key,\n title,\n overlayLabel: String(nextNumber),\n ...(args.iconRef ? { display: { icon16x16: args.iconRef } } : {}),\n tracks: [\n {\n key,\n title,\n trackUrl: uploaded.mediaRef,\n type: \"audio\",\n overlayLabel: String(nextNumber),\n ...(args.iconRef ? { display: { icon16x16: args.iconRef } } : {}),\n },\n ],\n };\n const card = await upsertCard(deps.client, {\n ...existing,\n cardId: args.cardId,\n content: { ...existing.content, chapters: [...chapters, newChapter] },\n });\n return { card };\n },\n };\n return [yotoUploadAudio, yotoAddTrack];\n}\n","import { createAuthTools } from \"./auth.js\";\nimport { createContentTools } from \"./content.js\";\nimport { createDeviceTools } from \"./devices.js\";\nimport { createIconTools } from \"./icons.js\";\nimport { createMediaTools } from \"./media.js\";\n/**\n * Builds all 14 `yoto_*` tool specs (see the plan's tool table), mode-aware\n * where the CLI and remote connector differ (file path vs. https URL for\n * media inputs; sign-in/out behaviour). None of this touches a real\n * `McpServer` -- that's `registerAll()` in index.ts, which calls\n * `defineTool()` on each spec this returns.\n */\nexport function createTools(deps) {\n return [\n ...createAuthTools(deps),\n ...createContentTools(deps),\n ...createMediaTools(deps),\n ...createIconTools(deps),\n ...createDeviceTools(deps),\n ];\n}\n","import { z } from \"zod\";\n/**\n * The scopes this server ever requests. Deliberately excludes\n * `family:devices:control` and `family:devices:manage` -- see the plan's\n * \"Scopes\" decision row: no device-control scopes, so the server is\n * eligible for Yoto's Verified listing. `yoto_get_device_config` therefore\n * expects a 403 in practice (device config needs `family:devices:manage`)\n * and turns that into a friendly FORBIDDEN_SCOPE result rather than a raw\n * failure -- see tools/devices.ts.\n */\nexport const YOTO_SCOPES = [\n \"profile\",\n \"offline_access\",\n \"user:content:view\",\n \"user:content:manage\",\n \"user:icons:manage\",\n \"family:library:view\",\n \"family:devices:view\",\n];\nexport const authStatusSchema = z.object({\n signedIn: z.boolean(),\n mode: z.enum([\"cli\", \"remote\"]),\n tokenStore: z.enum([\"keychain\", \"file\", \"remote\"]).optional(),\n expiresAt: z.number().optional(),\n scopes: z.array(z.string()).optional(),\n hint: z.string().optional(),\n});\nexport const signInResultSchema = z.object({\n url: z.string().optional(),\n message: z.string(),\n});\n","const LEVEL_ORDER = { debug: 0, info: 1, warn: 2, error: 3 };\nconst TOKEN_PATTERN = /eyJ[a-zA-Z0-9_-]{10,}(?:\\.[a-zA-Z0-9_-]{10,}){0,2}|[a-zA-Z0-9_-]{32,}/g;\nexport function redact(input) {\n return input.replace(TOKEN_PATTERN, \"[redacted]\");\n}\nfunction redactValue(value) {\n if (typeof value === \"string\")\n return redact(value);\n return JSON.parse(redact(JSON.stringify(value)));\n}\nconst NOOP_SINK = () => { };\nexport function createLogger(options = {}) {\n const minLevel = options.level ?? \"info\";\n const sink = options.sink ?? NOOP_SINK;\n function write(level, message, data) {\n if (LEVEL_ORDER[level] < LEVEL_ORDER[minLevel])\n return;\n const safeMessage = redact(message);\n const safeData = data === undefined ? undefined : redactValue(data);\n sink({ level, message: safeMessage, data: safeData });\n }\n return {\n debug: (message, data) => write(\"debug\", message, data),\n info: (message, data) => write(\"info\", message, data),\n warn: (message, data) => write(\"warn\", message, data),\n error: (message, data) => write(\"error\", message, data),\n };\n}\n/** A logger that discards everything -- the default handed to code in tests. */\nexport const noopLogger = createLogger({ sink: NOOP_SINK });\n","import { isYotoError, YotoError } from \"../errors.js\";\nimport { noopLogger } from \"../logging.js\";\nconst MAX_ATTEMPTS = 3;\nconst RETRY_AFTER_CAP_MS = 30_000;\nconst BACKOFF_BASE_MS = 300;\nconst BACKOFF_CAP_MS = 8_000;\n/**\n * Full-jitter backoff delay for retry attempt `attempt` (1-based): a random\n * value in `[0, min(cap, base * 2^(attempt-1))]`. Exported standalone so\n * tests can exercise the maths with an injected `random` and without real\n * timers. See https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/\n */\nexport function computeFullJitterDelayMs(attempt, options = {}) {\n const base = options.base ?? BACKOFF_BASE_MS;\n const cap = options.cap ?? BACKOFF_CAP_MS;\n const random = options.random ?? Math.random;\n const upperBound = Math.min(cap, base * 2 ** (attempt - 1));\n return random() * upperBound;\n}\n/** Parses a `Retry-After` header (seconds, or an HTTP-date) into milliseconds. */\nexport function parseRetryAfterMs(value, now) {\n if (!value)\n return undefined;\n const asSeconds = Number(value);\n if (!Number.isNaN(asSeconds))\n return Math.max(0, asSeconds * 1000);\n const asDate = Date.parse(value);\n if (!Number.isNaN(asDate))\n return Math.max(0, asDate - now());\n return undefined;\n}\nconst HINTS = {\n AUTH_EXPIRED: \"Run yoto_sign_in to refresh your Yoto session.\",\n FORBIDDEN_SCOPE: \"This connection doesn't have the Yoto scope this action needs.\",\n RATE_LIMITED: \"Yoto is rate-limiting requests right now; try again shortly.\",\n NOT_FOUND: \"That Yoto resource wasn't found.\",\n UPSTREAM_ERROR: \"Yoto's API returned an unexpected error.\",\n};\nfunction defaultSleep(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\nexport class YotoClient {\n getToken;\n fetchImpl;\n baseUrl;\n logger;\n now;\n sleepImpl;\n constructor(options) {\n this.getToken = options.getToken;\n this.fetchImpl = options.fetchImpl ?? globalThis.fetch;\n this.baseUrl = options.baseUrl ?? \"https://api.yotoplay.com\";\n this.logger = options.logger ?? noopLogger;\n this.now = options.now ?? (() => Date.now());\n this.sleepImpl = options.sleep ?? defaultSleep;\n }\n buildUrl(path, query) {\n const url = new URL(path.startsWith(\"http\") ? path : `${this.baseUrl}${path}`);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined)\n url.searchParams.set(key, String(value));\n }\n }\n return url.toString();\n }\n async toUpstreamError(response, code) {\n let detail = \"\";\n try {\n const text = await response.text();\n if (text) {\n try {\n const parsed = JSON.parse(text);\n detail = parsed.message ?? parsed.error ?? text;\n }\n catch {\n detail = text;\n }\n }\n }\n catch {\n // Body already consumed or unreadable -- fall back to a status-only message.\n }\n const retryable = code === \"RATE_LIMITED\" || code === \"UPSTREAM_ERROR\";\n return new YotoError(`Yoto API returned ${response.status}${detail ? `: ${detail}` : \"\"}`, {\n code,\n retryable,\n status: response.status,\n hint: HINTS[code],\n });\n }\n async parseBody(response, schema, method, path) {\n if (response.status === 204)\n return undefined;\n const text = await response.text();\n let json;\n try {\n json = text ? JSON.parse(text) : undefined;\n }\n catch (cause) {\n throw new YotoError(`Yoto returned invalid JSON for ${method} ${path}`, {\n code: \"UPSTREAM_ERROR\",\n cause,\n hint: \"This may be a transient Yoto API issue -- try again.\",\n });\n }\n if (!schema)\n return json;\n const result = schema.safeParse(json);\n if (!result.success) {\n throw new YotoError(`Yoto's response for ${method} ${path} didn't match the expected shape`, {\n code: \"UPSTREAM_ERROR\",\n cause: result.error,\n hint: \"Yoto may have changed their API response shape.\",\n });\n }\n return result.data;\n }\n async request(options) {\n const idempotent = options.idempotent ?? options.method === \"GET\";\n const url = this.buildUrl(options.path, options.query);\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n let response;\n try {\n const token = await this.getToken();\n const headers = {\n Authorization: `Bearer ${token}`,\n Accept: \"application/json\",\n ...options.headers,\n };\n let body;\n if (options.rawBody !== undefined) {\n body = options.rawBody;\n if (options.contentType)\n headers[\"Content-Type\"] = options.contentType;\n }\n else if (options.body !== undefined) {\n body = JSON.stringify(options.body);\n headers[\"Content-Type\"] = \"application/json\";\n }\n response = await this.fetchImpl(url, { method: options.method, headers, body });\n }\n catch (cause) {\n if (isYotoError(cause))\n throw cause;\n if (!idempotent || attempt >= MAX_ATTEMPTS) {\n throw new YotoError(`Network request to Yoto failed: ${options.method} ${options.path}`, {\n code: \"UPSTREAM_ERROR\",\n retryable: true,\n cause,\n hint: \"Check network connectivity and try again.\",\n });\n }\n this.logger.warn(\"Yoto request failed, retrying\", {\n method: options.method,\n path: options.path,\n attempt,\n });\n await this.sleepImpl(computeFullJitterDelayMs(attempt));\n continue;\n }\n if (response.ok) {\n return this.parseBody(response, options.schema, options.method, options.path);\n }\n if (response.status === 429) {\n if (!idempotent || attempt >= MAX_ATTEMPTS) {\n throw await this.toUpstreamError(response, \"RATE_LIMITED\");\n }\n const retryAfterMs = parseRetryAfterMs(response.headers.get(\"retry-after\"), this.now);\n await this.sleepImpl(Math.min(retryAfterMs ?? computeFullJitterDelayMs(attempt), RETRY_AFTER_CAP_MS));\n continue;\n }\n if (response.status >= 500) {\n if (!idempotent || attempt >= MAX_ATTEMPTS) {\n throw await this.toUpstreamError(response, \"UPSTREAM_ERROR\");\n }\n await this.sleepImpl(computeFullJitterDelayMs(attempt));\n continue;\n }\n if (response.status === 401)\n throw await this.toUpstreamError(response, \"AUTH_EXPIRED\");\n if (response.status === 403)\n throw await this.toUpstreamError(response, \"FORBIDDEN_SCOPE\");\n if (response.status === 404)\n throw await this.toUpstreamError(response, \"NOT_FOUND\");\n throw await this.toUpstreamError(response, \"UPSTREAM_ERROR\");\n }\n // Unreachable -- the loop above always returns or throws -- but keeps the\n // function's return type honest without a non-null assertion.\n throw new YotoError(`Request to Yoto failed after ${MAX_ATTEMPTS} attempts`, {\n code: \"UPSTREAM_ERROR\",\n });\n }\n /**\n * Generic cursor-pagination helper. None of the 14 tools' endpoints\n * currently paginate (Yoto returns full collections for content/devices/\n * icons), but this keeps the shape ready for the day one does, and is\n * exercised directly in tests.\n */\n async *paginate(fetchPage) {\n let cursor;\n do {\n const page = await fetchPage(cursor);\n for (const item of page.items)\n yield item;\n cursor = page.nextCursor;\n } while (cursor);\n }\n}\n","import { McpServer } from \"@modelcontextprotocol/server\";\nimport { registerPrompts } from \"./prompts.js\";\nimport { registerResources } from \"./resources.js\";\nimport { DEFAULT_ICON_BASE_URL, defineTool } from \"./tools/_helpers.js\";\nimport { createTools } from \"./tools/index.js\";\nexport { authStatusSchema, signInResultSchema, YOTO_SCOPES } from \"./auth.js\";\nexport { isYotoError, toToolResult, YotoError } from \"./errors.js\";\nexport { createLogger, noopLogger, redact } from \"./logging.js\";\nexport { registerPrompts } from \"./prompts.js\";\nexport { registerResources } from \"./resources.js\";\nexport { cardIdSchema } from \"./schemas/index.js\";\nexport { DEFAULT_ICON_BASE_URL, defineTool } from \"./tools/_helpers.js\";\nexport { createTools } from \"./tools/index.js\";\nexport { computeFullJitterDelayMs, parseRetryAfterMs, YotoClient } from \"./yoto/client.js\";\nexport { deleteCard, getCard, getDeviceConfig, getTranscodedStatus, getUploadUrl, listDevices, listFamilyLibrary, listMyCards, listPublicIcons, uploadCustomIcon, upsertCard, } from \"./yoto/endpoints.js\";\nexport { sniffAudio, sniffImage, uploadAudio } from \"./yoto/media.js\";\nexport * from \"./yoto/types.js\";\n/**\n * Registers all 14 tools, the 3 resources, and the 2 prompts onto an\n * already-constructed `McpServer`. Split out from `createServer()` so a\n * caller that needs to build the `McpServer` itself (e.g. to pass\n * transport-specific options the plan hasn't decided on yet) can still\n * reuse this.\n */\nexport function registerAll(server, deps) {\n const iconBaseUrl = deps.iconBaseUrl ?? DEFAULT_ICON_BASE_URL;\n for (const spec of createTools(deps)) {\n defineTool(server, spec, { logger: deps.logger, iconBaseUrl });\n }\n registerResources(server, deps);\n registerPrompts(server);\n}\n/**\n * Constructs the `McpServer` (server-level `name`/`title`/`icons`/\n * `websiteUrl`, per the plan's Implementation schema) and registers\n * everything onto it. Both `apps/cli` and `apps/worker` call this with\n * their own `deps` (a CLI or remote `AuthAdapter`, a `YotoClient`, and\n * runtime-specific `resolveAudio`/`resolveImage`) -- packages/core never\n * constructs any of those itself.\n */\nexport function createServer(deps, options) {\n const iconBaseUrl = deps.iconBaseUrl ?? options.iconBaseUrl ?? DEFAULT_ICON_BASE_URL;\n const server = new McpServer({\n name: options.name,\n title: options.title ?? \"Yoto\",\n version: options.version,\n icons: [{ src: `${iconBaseUrl}/server.png`, mimeType: \"image/png\", sizes: [\"64x64\"] }],\n websiteUrl: options.websiteUrl ?? \"https://github.com/danpillay87/mcp-yoto\",\n }, { capabilities: { tools: {}, resources: {}, prompts: {} } });\n registerAll(server, { ...deps, iconBaseUrl });\n return server;\n}\n","/**\n * The CLI's one-shot loopback HTTP server: binds `127.0.0.1:<port>` FIRST\n * (so a busy port fails loud and fast, before the browser even opens),\n * waits for exactly one `/callback` request carrying `state` + `code`, and\n * always closes the server afterwards -- on success, on a state mismatch,\n * on an upstream error, or on timeout.\n */\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\n\n/** Distinguishes the two CLI-only failure shapes from the shared `YotoErrorCode` union in packages/core. */\nexport type LoopbackErrorCode = \"PORT_IN_USE\" | \"AUTH_TIMEOUT\" | \"CALLBACK_ERROR\";\n\nexport class LoopbackError extends Error {\n readonly code: LoopbackErrorCode;\n readonly hint: string | undefined;\n\n constructor(message: string, code: LoopbackErrorCode, hint?: string) {\n super(message);\n this.name = \"LoopbackError\";\n this.code = code;\n this.hint = hint;\n }\n}\n\nexport interface LoopbackOptions {\n port: number;\n expectedState: string;\n /** How long to wait for the callback before giving up. Default 300_000ms (300s). */\n timeoutMs?: number;\n /** Injected timer functions, for deterministic tests with fake timers. */\n setTimeoutImpl?: typeof setTimeout;\n clearTimeoutImpl?: typeof clearTimeout;\n}\n\nexport interface LoopbackResult {\n code: string;\n}\n\nconst SUCCESS_HTML =\n '<!doctype html><html><head><meta charset=\"utf-8\"><title>Signed in to Yoto</title></head>' +\n '<body style=\"font-family:system-ui,sans-serif;padding:3rem;max-width:32rem;margin:0 auto\">' +\n \"<h1>You're signed in — you can close this tab.</h1>\" +\n \"<p>Head back to your AI client -- mcp-yoto is ready.</p></body></html>\";\n\nfunction failureHtml(message: string): string {\n return (\n '<!doctype html><html><head><meta charset=\"utf-8\"><title>Sign-in failed</title></head>' +\n '<body style=\"font-family:system-ui,sans-serif;padding:3rem;max-width:32rem;margin:0 auto\">' +\n \"<h1>Sign-in failed</h1>\" +\n `<p>${escapeHtml(message)}</p></body></html>`\n );\n}\n\nconst HTML_ESCAPES: Record<string, string> = {\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&#39;\",\n};\n\nfunction escapeHtml(value: string): string {\n return value.replace(/[&<>\"']/g, (ch) => HTML_ESCAPES[ch] ?? ch);\n}\n\nfunction sendHtml(res: ServerResponse, status: number, body: string): void {\n res.writeHead(status, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(body);\n}\n\n/**\n * Waits for the single OAuth callback this sign-in attempt expects.\n *\n * Binds the port before returning, so a caller can `await` this and only\n * then open the browser / print the sign-in URL, confident the redirect has\n * somewhere to land. Every exit path (success, state mismatch, upstream\n * `error=`, bind failure, timeout) closes the server exactly once.\n */\nexport function awaitLoopbackCallback(options: LoopbackOptions): Promise<LoopbackResult> {\n const timeoutMs = options.timeoutMs ?? 300_000;\n const setTimeoutImpl = options.setTimeoutImpl ?? setTimeout;\n const clearTimeoutImpl = options.clearTimeoutImpl ?? clearTimeout;\n\n return new Promise<LoopbackResult>((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const server: Server = createServer(handleRequest);\n\n function finish(action: () => void): void {\n if (settled) return;\n settled = true;\n if (timer !== undefined) clearTimeoutImpl(timer);\n server.close();\n action();\n }\n\n function handleRequest(req: IncomingMessage, res: ServerResponse): void {\n const url = new URL(req.url ?? \"/\", `http://127.0.0.1:${options.port}`);\n if (url.pathname !== \"/callback\") {\n res.writeHead(404).end();\n return;\n }\n\n const upstreamError = url.searchParams.get(\"error\");\n if (upstreamError) {\n sendHtml(res, 200, failureHtml(`Yoto returned an error: ${upstreamError}`));\n finish(() =>\n reject(\n new LoopbackError(\n `Yoto returned an error during sign-in: ${upstreamError}`,\n \"CALLBACK_ERROR\",\n ),\n ),\n );\n return;\n }\n\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n if (!code || state !== options.expectedState) {\n sendHtml(res, 400, failureHtml(\"This sign-in link is stale or was tampered with.\"));\n finish(() =>\n reject(\n new LoopbackError(\n \"Sign-in callback state did not match -- stale or invalid attempt.\",\n \"CALLBACK_ERROR\",\n \"Run yoto_sign_in again.\",\n ),\n ),\n );\n return;\n }\n\n sendHtml(res, 200, SUCCESS_HTML);\n finish(() => resolve({ code }));\n }\n\n server.once(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n finish(() =>\n reject(\n new LoopbackError(\n `Port ${options.port} is already in use.`,\n \"PORT_IN_USE\",\n \"Set YOTO_REDIRECT_PORT to a free port that's also registered at Yoto, or close whatever's using it.\",\n ),\n ),\n );\n return;\n }\n finish(() => reject(new LoopbackError(err.message, \"CALLBACK_ERROR\")));\n });\n\n server.listen(options.port, \"127.0.0.1\", () => {\n timer = setTimeoutImpl(() => {\n finish(() =>\n reject(\n new LoopbackError(\n \"Timed out waiting for the Yoto sign-in callback.\",\n \"AUTH_TIMEOUT\",\n \"Run yoto_sign_in again.\",\n ),\n ),\n );\n }, timeoutMs);\n });\n });\n}\n","/**\n * Best-effort cross-platform \"open this URL in the default browser\". Never\n * throws: the sign-in URL is always returned/printed alongside this call\n * too (see adapter.ts), so a headless box or a missing `xdg-open` degrades\n * to \"copy this link\" rather than a hard failure.\n */\nimport { spawn } from \"node:child_process\";\n\nexport function openInBrowser(url: string): void {\n try {\n let child: ReturnType<typeof spawn>;\n if (process.platform === \"win32\") {\n // NOT `cmd /c start`: cmd.exe parses the command line itself, and it\n // treats every unquoted `&` as a command separator -- an OAuth\n // authorize URL is full of `&`-joined query params, so `cmd start`\n // silently truncated the URL at the first `&` (client_id,\n // redirect_uri, code_challenge, state all dropped) and Yoto's sign-in\n // page rendered with no way to authenticate. `rundll32.exe\n // url.dll,FileProtocolHandler <url>` hands the URL to the shell's own\n // protocol handler with no cmd/shell parsing involved, so the URL\n // reaches Edge byte-for-byte.\n child = spawn(\"rundll32.exe\", [\"url.dll,FileProtocolHandler\", url], {\n shell: false,\n detached: true,\n stdio: \"ignore\",\n });\n } else if (process.platform === \"darwin\") {\n child = spawn(\"open\", [url], { shell: false, detached: true, stdio: \"ignore\" });\n } else {\n child = spawn(\"xdg-open\", [url], { shell: false, detached: true, stdio: \"ignore\" });\n }\n // A missing binary (e.g. no xdg-open on a headless box) emits an async\n // `error` event rather than throwing -- swallow it the same way as the\n // synchronous catch below, since the URL is already on stderr for the\n // user to click (see login's stderr contract in adapter.ts).\n child.on(\"error\", () => {});\n child.unref();\n } catch {\n // Best-effort only.\n }\n}\n","/**\n * PKCE (RFC 7636) helpers for the CLI's loopback sign-in flow. Node-only\n * (`node:crypto`) -- apps/cli is allowed node: imports, unlike\n * packages/core, which stays fetch + WebCrypto only.\n */\nimport { createHash, randomBytes } from \"node:crypto\";\n\n/** RFC 7636 S256 `code_challenge` for a given `code_verifier`. Exported standalone for tests. */\nexport function codeChallengeFromVerifier(verifier: string): string {\n return createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\nexport interface PkcePair {\n verifier: string;\n challenge: string;\n}\n\n/** A fresh PKCE pair: a 32-byte random verifier (well within RFC 7636's 43-128 char range), S256 challenge. */\nexport function createPkcePair(): PkcePair {\n const verifier = randomBytes(32).toString(\"base64url\");\n return { verifier, challenge: codeChallengeFromVerifier(verifier) };\n}\n\n/** A single-use value correlating the loopback callback with the request that started it. */\nexport function createState(): string {\n return randomBytes(16).toString(\"base64url\");\n}\n","/**\n * Thin wrapper around Yoto's `POST /oauth/token` endpoint, shared by both\n * legs that call it: the authorization-code exchange (adapter.ts, once per\n * sign-in) and the refresh-token grant (session.ts, on every access-token\n * renewal). Kept deliberately dumb -- it does not interpret the response,\n * just forwards it -- so the two callers can apply their own (different)\n * error handling.\n */\n\nexport interface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n scope?: string;\n}\n\nexport interface TokenErrorBody {\n error?: string;\n error_description?: string;\n}\n\nexport type TokenResult =\n | { ok: true; data: TokenResponse }\n | { ok: false; status: number; error?: TokenErrorBody };\n\nexport async function postTokenRequest(\n fetchImpl: typeof fetch,\n tokenUrl: string,\n params: Record<string, string>,\n): Promise<TokenResult> {\n const response = await fetchImpl(tokenUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(params),\n });\n\n if (response.ok) {\n return { ok: true, data: (await response.json()) as TokenResponse };\n }\n\n let error: TokenErrorBody | undefined;\n try {\n error = (await response.json()) as TokenErrorBody;\n } catch {\n // Non-JSON error body -- leave `error` undefined, callers fall back to the status code alone.\n }\n return { ok: false, status: response.status, error };\n}\n","/**\n * Turns a `TokenStore` into a live access token: reads the JWT's own `exp`\n * claim and trusts it over whatever `expiresAt` was persisted (ported from\n * the old yoto-mcp-server, which found a stored placeholder `expiresAt`\n * making a perfectly live token look dead), refreshes 10 minutes early so a\n * rejected refresh never leaves the caller with zero working credential,\n * and collapses concurrent callers onto one in-flight refresh so three\n * simultaneous tool calls never race Yoto's rotating refresh token against\n * itself.\n */\nimport { YotoError } from \"@mcp-yoto/core\";\nimport { postTokenRequest } from \"./token-exchange.js\";\nimport type { StoredTokens, TokenStore } from \"./token-store.js\";\n\nconst REFRESH_SKEW_MS = 10 * 60 * 1000;\n\nexport interface SessionConfig {\n clientId: string;\n authBase: string;\n}\n\nexport interface SessionOptions {\n config: SessionConfig;\n tokenStore: TokenStore;\n /** Injected for tests; defaults to `globalThis.fetch`. */\n fetchImpl?: typeof fetch;\n /** Injected clock, for deterministic early-refresh tests. Defaults to `Date.now`. */\n now?: () => number;\n}\n\n/** Reads the `exp` claim (ms since epoch) out of a JWT's payload, unverified -- we trust it because Yoto issued it to us. */\nexport function decodeJwtExpMs(token: string): number | undefined {\n const parts = token.split(\".\");\n if (parts.length !== 3) return undefined;\n try {\n const payloadJson = Buffer.from(parts[1] ?? \"\", \"base64url\").toString(\"utf-8\");\n const payload = JSON.parse(payloadJson) as { exp?: number };\n return typeof payload.exp === \"number\" ? payload.exp * 1000 : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Manages the CLI's single Yoto session (there is only ever one -- no\n * multi-account support in this pass). One `Session` instance is created\n * per process and shared by every tool call via the `AuthAdapter`.\n */\nexport class Session {\n private readonly config: SessionConfig;\n private readonly tokenStore: TokenStore;\n private readonly fetchImpl: typeof fetch;\n private readonly now: () => number;\n private inFlightRefresh: Promise<string> | undefined;\n\n constructor(options: SessionOptions) {\n this.config = options.config;\n this.tokenStore = options.tokenStore;\n this.fetchImpl = options.fetchImpl ?? globalThis.fetch;\n this.now = options.now ?? (() => Date.now());\n }\n\n /**\n * Returns a live access token, refreshing first if the current one is\n * within 10 minutes of expiry (or the store carries no readable expiry\n * at all, which fails safe by treating it as due for refresh).\n */\n async getAccessToken(): Promise<string> {\n const stored = await this.tokenStore.load();\n if (!stored) {\n throw new YotoError(\"Not signed in to Yoto.\", {\n code: \"NOT_AUTHENTICATED\",\n hint: \"Run yoto_sign_in.\",\n });\n }\n\n const expiresAt = decodeJwtExpMs(stored.accessToken) ?? stored.expiresAt;\n const now = this.now();\n if (expiresAt !== undefined && expiresAt - REFRESH_SKEW_MS > now) {\n return stored.accessToken;\n }\n\n if (!stored.refreshToken) {\n // No refresh token on file: a live-but-soon-expiring token is still\n // usable, but once it's actually dead there is nothing left to try.\n if (expiresAt !== undefined && expiresAt > now) return stored.accessToken;\n throw new YotoError(\"Your Yoto session has expired.\", {\n code: \"AUTH_EXPIRED\",\n hint: \"Run yoto_sign_in.\",\n });\n }\n\n return this.refresh(stored.refreshToken);\n }\n\n /** Single-flight: concurrent callers share the one in-flight refresh instead of each starting their own. */\n private refresh(refreshToken: string): Promise<string> {\n if (!this.inFlightRefresh) {\n this.inFlightRefresh = this.doRefresh(refreshToken).finally(() => {\n this.inFlightRefresh = undefined;\n });\n }\n return this.inFlightRefresh;\n }\n\n private async doRefresh(refreshToken: string): Promise<string> {\n const result = await postTokenRequest(this.fetchImpl, `${this.config.authBase}/oauth/token`, {\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: this.config.clientId,\n });\n\n if (!result.ok) {\n if (result.error?.error === \"invalid_grant\") {\n // Yoto has already invalidated this refresh token server-side (it's\n // rotating) -- there is nothing to retry. Clear the local store so\n // yoto_status reports \"not signed in\" rather than a token we know is dead.\n await this.tokenStore.clear();\n throw new YotoError(\"Yoto rejected the stored refresh token.\", {\n code: \"AUTH_EXPIRED\",\n hint: \"Run yoto_sign_in.\",\n });\n }\n throw new YotoError(`Yoto token refresh failed (HTTP ${result.status}).`, {\n code: \"UPSTREAM_ERROR\",\n retryable: true,\n status: result.status,\n });\n }\n\n const data = result.data;\n const newTokens: StoredTokens = {\n accessToken: data.access_token,\n refreshToken: data.refresh_token ?? refreshToken,\n expiresAt: data.expires_in !== undefined ? this.now() + data.expires_in * 1000 : undefined,\n scope: data.scope,\n };\n // Persist BEFORE returning: if the process dies right after this call,\n // the rotating refresh token Yoto just invalidated server-side must not\n // be lost along with it -- the new one has to be on disk first.\n await this.tokenStore.save(newTokens);\n return newTokens.accessToken;\n }\n}\n","/**\n * Where the CLI's Yoto credential lives at rest: the OS keychain by\n * preference (`KeyringStore`, via `@napi-rs/keyring`), falling back to a\n * plain file (`FileStore`) when the keychain is unusable (no native\n * binding for this platform, a headless box with no keyring daemon, a\n * locked session). `createTokenStore()` is the one entry point that makes\n * that choice; everything else in this file is a plain, directly testable\n * `TokenStore` implementation.\n */\nimport { chmod, copyFile, mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { Logger } from \"@mcp-yoto/core\";\n\nexport interface StoredTokens {\n accessToken: string;\n refreshToken?: string;\n /** Unix milliseconds. Belt-and-braces alongside the JWT's own `exp` claim -- see session.ts. */\n expiresAt?: number;\n /** Space-separated scopes Yoto actually granted. */\n scope?: string;\n}\n\nexport interface TokenStore {\n readonly kind: \"keychain\" | \"file\";\n load(): Promise<StoredTokens | undefined>;\n save(tokens: StoredTokens): Promise<void>;\n clear(): Promise<void>;\n}\n\nconst SERVICE = \"mcp-yoto\";\n\n/**\n * OS keychain-backed store (Windows Credential Manager / macOS Keychain /\n * Secret Service on Linux) via `@napi-rs/keyring`.\n *\n * Imports the native module dynamically and lazily -- it's an\n * `optionalDependency` (see apps/cli/package.json), so a platform with no\n * prebuilt binding must still be able to `npm install` and run; the failure\n * surfaces here, at first use, and `createTokenStore()` catches it.\n */\nexport class KeyringStore implements TokenStore {\n readonly kind = \"keychain\" as const;\n\n constructor(private readonly account: string) {}\n\n private async entry(): Promise<import(\"@napi-rs/keyring\").AsyncEntry> {\n const { AsyncEntry } = await import(\"@napi-rs/keyring\");\n return new AsyncEntry(SERVICE, this.account);\n }\n\n async load(): Promise<StoredTokens | undefined> {\n const entry = await this.entry();\n const raw = await entry.getPassword();\n if (!raw) return undefined;\n try {\n return JSON.parse(raw) as StoredTokens;\n } catch {\n return undefined;\n }\n }\n\n async save(tokens: StoredTokens): Promise<void> {\n const entry = await this.entry();\n await entry.setPassword(JSON.stringify(tokens));\n }\n\n async clear(): Promise<void> {\n const entry = await this.entry();\n await entry.deletePassword();\n }\n}\n\n/** `~/.config/mcp-yoto/tokens.json`, or on Windows `%APPDATA%\\mcp-yoto\\tokens.json`. */\nexport function defaultTokenFilePath(): string {\n if (process.platform === \"win32\") {\n const appData = process.env.APPDATA || join(homedir(), \"AppData\", \"Roaming\");\n return join(appData, \"mcp-yoto\", \"tokens.json\");\n }\n return join(homedir(), \".config\", \"mcp-yoto\", \"tokens.json\");\n}\n\n/**\n * Plain-file fallback: crash-safe temp+rename writes with a `.last-good`\n * backup (ported from the old yoto-mcp-server's config store), 0600\n * permissions on POSIX (Windows ACLs already scope the file to the current\n * user's profile), and BOM-tolerant reads (a PowerShell-written file often\n * carries a UTF-8 BOM, which breaks a naive `JSON.parse`).\n */\nexport class FileStore implements TokenStore {\n readonly kind = \"file\" as const;\n private readonly filePath: string;\n\n constructor(filePath: string = defaultTokenFilePath()) {\n this.filePath = filePath;\n }\n\n async load(): Promise<StoredTokens | undefined> {\n const primary = await this.readFrom(this.filePath);\n if (primary) return primary;\n // The main file is missing or corrupt (e.g. a crash mid-write left a\n // truncated .tmp that never got renamed, or a partial write slipped\n // through) -- recover from the last file we know was ever written cleanly.\n return this.readFrom(`${this.filePath}.last-good`);\n }\n\n private async readFrom(path: string): Promise<StoredTokens | undefined> {\n let raw: string;\n try {\n raw = await readFile(path, \"utf-8\");\n } catch {\n return undefined;\n }\n const stripped = raw.replace(/^/, \"\");\n try {\n return JSON.parse(stripped) as StoredTokens;\n } catch {\n return undefined;\n }\n }\n\n async save(tokens: StoredTokens): Promise<void> {\n await mkdir(dirname(this.filePath), { recursive: true });\n try {\n await copyFile(this.filePath, `${this.filePath}.last-good`);\n } catch {\n // No existing file yet -- this is the first sign-in.\n }\n const tmp = `${this.filePath}.tmp`;\n await writeFile(tmp, JSON.stringify(tokens, null, 2), \"utf-8\");\n await rename(tmp, this.filePath);\n if (process.platform !== \"win32\") {\n await chmod(this.filePath, 0o600);\n }\n }\n\n async clear(): Promise<void> {\n for (const path of [this.filePath, `${this.filePath}.last-good`, `${this.filePath}.tmp`]) {\n try {\n await rm(path);\n } catch {\n // Already gone -- clearing an already-signed-out store is not an error.\n }\n }\n }\n}\n\nexport interface CreateTokenStoreOptions {\n /** Keychain account name -- the client id, per the plan's \"service mcp-yoto, account = client id\". */\n account: string;\n logger: Logger;\n /** Forces a `FileStore` at this exact path, skipping the keychain entirely. See config.ts's `tokenFileOverride`. */\n fileOverride?: string;\n}\n\n/**\n * Picks the token store for this run: the OS keychain when it works, a\n * plain file (with one loud stderr warning, surfaced again in\n * `yoto_status`) when it doesn't.\n *\n * The probe is `load()` itself: on a fresh machine with nothing stored yet,\n * `getPassword()` resolves to `undefined` rather than throwing (see\n * @napi-rs/keyring's own contract), so an empty-but-working keychain is\n * correctly told apart from a broken one.\n */\nexport async function createTokenStore(options: CreateTokenStoreOptions): Promise<TokenStore> {\n if (options.fileOverride) {\n return new FileStore(options.fileOverride);\n }\n try {\n const keyring = new KeyringStore(options.account);\n await keyring.load();\n return keyring;\n } catch (error) {\n const filePath = defaultTokenFilePath();\n options.logger.warn(\n `System keychain unavailable -- falling back to a local file at ${filePath} ` +\n \"(0600 permissions on macOS/Linux; scoped to your Windows user profile).\",\n { error: error instanceof Error ? error.message : String(error) },\n );\n return new FileStore(filePath);\n }\n}\n","/**\n * The CLI's `AuthAdapter` (see @mcp-yoto/core's auth.ts): PKCE + loopback +\n * OS keychain, wired together into the shape packages/core's tools expect.\n * apps/worker implements the same interface completely differently (it\n * never signs in locally at all -- see the plan's \"remote mode\" notes);\n * neither app ever sees the other's implementation.\n */\nimport {\n type AuthAdapter,\n type AuthStatus,\n type Logger,\n type SignInResult,\n YOTO_SCOPES,\n YotoError,\n} from \"@mcp-yoto/core\";\nimport type { CliConfig } from \"../config.js\";\nimport { awaitLoopbackCallback, LoopbackError } from \"./loopback.js\";\nimport { openInBrowser } from \"./open-browser.js\";\nimport { createPkcePair, createState } from \"./pkce.js\";\nimport { decodeJwtExpMs, Session } from \"./session.js\";\nimport { postTokenRequest } from \"./token-exchange.js\";\nimport { createTokenStore, type TokenStore } from \"./token-store.js\";\n\nexport interface CreateCliAuthAdapterOptions {\n config: CliConfig;\n logger: Logger;\n /** Injected for tests. */\n fetchImpl?: typeof fetch;\n now?: () => number;\n}\n\n/** The `AuthAdapter` plus the underlying store, so `main.ts`'s `status`/`logout` subcommands can report its kind directly. */\nexport interface CliAuthAdapter extends AuthAdapter {\n readonly tokenStore: TokenStore;\n /**\n * Widens the base `AuthAdapter.signIn` opts with a CLI-only hook: called\n * synchronously with the authorize URL as soon as it's built, before the\n * loopback callback is ever awaited -- so a caller (main.ts's `login`\n * command) can print it immediately instead of waiting for sign-in to\n * finish. Optional and additive; the `yoto_sign_in` tool path never sets it.\n */\n signIn?(opts?: {\n openBrowser?: boolean;\n onAuthorizeUrl?: (url: string) => void;\n }): Promise<SignInResult>;\n}\n\nfunction redirectUri(port: number): string {\n return `http://127.0.0.1:${port}/callback`;\n}\n\nfunction loopbackErrorToYotoError(error: unknown): YotoError {\n if (error instanceof LoopbackError) {\n if (error.code === \"PORT_IN_USE\") {\n return new YotoError(error.message, { code: \"PORT_IN_USE\", hint: error.hint, cause: error });\n }\n if (error.code === \"AUTH_TIMEOUT\") {\n return new YotoError(error.message, { code: \"VALIDATION\", hint: error.hint, cause: error });\n }\n return new YotoError(error.message, { code: \"UPSTREAM_ERROR\", hint: error.hint, cause: error });\n }\n const message = error instanceof Error ? error.message : String(error);\n return new YotoError(message, { code: \"UPSTREAM_ERROR\", cause: error });\n}\n\nexport async function createCliAuthAdapter(\n options: CreateCliAuthAdapterOptions,\n): Promise<CliAuthAdapter> {\n const fetchImpl = options.fetchImpl ?? globalThis.fetch;\n const now = options.now ?? (() => Date.now());\n const tokenStore = await createTokenStore({\n account: options.config.clientId,\n logger: options.logger,\n fileOverride: options.config.tokenFileOverride,\n });\n const session = new Session({\n config: { clientId: options.config.clientId, authBase: options.config.authBase },\n tokenStore,\n fetchImpl,\n now,\n });\n\n async function signIn(opts?: {\n openBrowser?: boolean;\n onAuthorizeUrl?: (url: string) => void;\n }): Promise<SignInResult> {\n const { verifier, challenge } = createPkcePair();\n const state = createState();\n const port = options.config.redirectPort;\n\n const authorizeUrl = new URL(`${options.config.authBase}/authorize`);\n authorizeUrl.searchParams.set(\"audience\", options.config.audience);\n authorizeUrl.searchParams.set(\"scope\", YOTO_SCOPES.join(\" \"));\n authorizeUrl.searchParams.set(\"response_type\", \"code\");\n authorizeUrl.searchParams.set(\"client_id\", options.config.clientId);\n authorizeUrl.searchParams.set(\"code_challenge\", challenge);\n authorizeUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authorizeUrl.searchParams.set(\"redirect_uri\", redirectUri(port));\n authorizeUrl.searchParams.set(\"state\", state);\n const url = authorizeUrl.toString();\n\n // Hand the URL to the caller synchronously, before anything below is\n // awaited -- so a caller who wants to print it (main.ts's `login`\n // command) can do so immediately, rather than waiting for the loopback\n // callback to land. The URL carries only a PKCE challenge and a state\n // nonce, both single-use and non-secret -- safe to print/log.\n opts?.onAuthorizeUrl?.(url);\n\n // Bind the loopback server BEFORE opening the browser -- a busy port\n // must fail loud, not send the user to a callback URL nothing is\n // listening on.\n const callbackPromise = awaitLoopbackCallback({ port, expectedState: state });\n\n const shouldOpenBrowser = (opts?.openBrowser ?? true) && !options.config.noBrowser;\n if (shouldOpenBrowser) openInBrowser(url);\n\n let code: string;\n try {\n ({ code } = await callbackPromise);\n } catch (error) {\n throw loopbackErrorToYotoError(error);\n }\n\n const result = await postTokenRequest(fetchImpl, `${options.config.authBase}/oauth/token`, {\n grant_type: \"authorization_code\",\n client_id: options.config.clientId,\n code,\n code_verifier: verifier,\n redirect_uri: redirectUri(port),\n });\n\n if (!result.ok) {\n throw new YotoError(\n `Yoto rejected the sign-in code (HTTP ${result.status}${result.error?.error ? `: ${result.error.error}` : \"\"}).`,\n { code: \"UPSTREAM_ERROR\", status: result.status },\n );\n }\n\n await tokenStore.save({\n accessToken: result.data.access_token,\n refreshToken: result.data.refresh_token,\n expiresAt:\n result.data.expires_in !== undefined ? now() + result.data.expires_in * 1000 : undefined,\n scope: result.data.scope ?? YOTO_SCOPES.join(\" \"),\n });\n\n // ALWAYS return the URL, even after opening the browser automatically --\n // if the browser didn't actually open (headless box, no default handler\n // registered), the caller still has something to paste.\n return { url, message: \"Signed in to Yoto.\" };\n }\n\n async function signOut(): Promise<void> {\n await tokenStore.clear();\n }\n\n return {\n mode: \"cli\",\n tokenStore,\n async getAccessToken() {\n return session.getAccessToken();\n },\n async status(): Promise<AuthStatus> {\n const stored = await tokenStore.load();\n if (!stored) {\n return {\n signedIn: false,\n mode: \"cli\",\n tokenStore: tokenStore.kind,\n hint: \"Run yoto_sign_in to connect your Yoto account.\",\n };\n }\n const expiresAt = decodeJwtExpMs(stored.accessToken) ?? stored.expiresAt;\n return {\n signedIn: true,\n mode: \"cli\",\n tokenStore: tokenStore.kind,\n expiresAt,\n scopes: stored.scope ? stored.scope.split(\" \") : undefined,\n };\n },\n signIn,\n signOut,\n };\n}\n","/**\n * Configuration for the `npx mcp-yoto` CLI, read from `process.env`.\n *\n * This is the ONE place in apps/cli that touches `process.env` directly --\n * every other module takes an explicit value (a `CliConfig`, a clock, a\n * `fetchImpl`) so it stays trivially testable without mutating globals.\n *\n * Mirrors apps/worker's config.ts decisions (same Yoto auth base, same\n * scope list) but is CLI-only: no KV, no OAuthProvider, no `Env` binding.\n */\nimport { YOTO_SCOPES } from \"@mcp-yoto/core\";\n\n/**\n * Yoto's public PKCE client for the CLI's existing dev app -- safe to ship\n * in source (no client secret; PKCE is the confidentiality mechanism).\n * Overridable via YOTO_CLIENT_ID for anyone running their own registered\n * Yoto dev app.\n */\nexport const DEFAULT_CLIENT_ID = \"xl4YsMpHEMnn7ubVhsRu8NhBwfUFPf8J\";\n\nexport const YOTO_AUTH_BASE = \"https://login.yotoplay.com\";\nexport const AUDIENCE = \"https://api.yotoplay.com\";\nexport const DEFAULT_REDIRECT_PORT = 8791;\nexport const DEFAULT_ICON_BASE_URL =\n \"https://raw.githubusercontent.com/danpillay87/mcp-yoto/main/apps/worker/public/icons\";\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface CliConfig {\n clientId: string;\n authBase: string;\n audience: string;\n /** Loopback port for PKCE sign-in. Must match the redirect URI registered at Yoto. */\n redirectPort: number;\n /** True when YOTO_NO_BROWSER is set -- print the sign-in URL instead of opening a browser. */\n noBrowser: boolean;\n logLevel: LogLevel;\n iconBaseUrl: string;\n /** Space-joined scopes this connection ever requests. Never devices:control/manage. */\n scope: string;\n /**\n * Advanced/testing override: forces the token store to a plain file at this\n * path, skipping the OS keychain entirely. Used by the stdio-purity test to\n * sandbox credential storage in a temp directory without touching a real\n * keychain or `~/.config/mcp-yoto`. Not documented as a normal user-facing\n * knob (see README's env var table), but harmless to set by hand too.\n */\n tokenFileOverride?: string;\n}\n\nfunction parsePort(raw: string | undefined, fallback: number): number {\n if (!raw) return fallback;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed <= 0 || parsed > 65535) {\n throw new Error(\n `YOTO_REDIRECT_PORT must be an integer between 1 and 65535, got ${JSON.stringify(raw)}.`,\n );\n }\n return parsed;\n}\n\nfunction parseLogLevel(raw: string | undefined): LogLevel {\n return raw === \"debug\" || raw === \"warn\" || raw === \"error\" ? raw : \"info\";\n}\n\nfunction parseBoolFlag(raw: string | undefined): boolean {\n return raw === \"1\" || raw?.toLowerCase() === \"true\";\n}\n\n/** Reads and validates configuration from `env` (defaults to `process.env`). */\nexport function loadConfig(env: NodeJS.ProcessEnv = process.env): CliConfig {\n return {\n clientId: env.YOTO_CLIENT_ID || DEFAULT_CLIENT_ID,\n authBase: YOTO_AUTH_BASE,\n audience: AUDIENCE,\n redirectPort: parsePort(env.YOTO_REDIRECT_PORT, DEFAULT_REDIRECT_PORT),\n noBrowser: parseBoolFlag(env.YOTO_NO_BROWSER),\n logLevel: parseLogLevel(env.LOG_LEVEL),\n iconBaseUrl: env.MCP_YOTO_ICON_BASE || DEFAULT_ICON_BASE_URL,\n scope: YOTO_SCOPES.join(\" \"),\n tokenFileOverride: env.MCP_YOTO_TOKEN_FILE || undefined,\n };\n}\n","/**\n * Turns a `yoto_upload_audio`/`yoto_upload_icon`-style CLI input\n * (`audioFilePath` / `imagePath`) into the streamable bytes packages/core's\n * tools expect (`AudioSource` / `ImageSource`), per `CreateToolsDeps`'s\n * `resolveAudio`/`resolveImage` in `@mcp-yoto/core`. The remote connector\n * has its own version of this file that fetches an `https://` URL instead\n * -- this one only ever touches the local filesystem, and never makes a\n * network call, so it can (and must) reject an unsupported file before any\n * upload attempt.\n */\nimport { createReadStream } from \"node:fs\";\nimport { open, readFile, stat } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { basename, isAbsolute, resolve as resolvePath } from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport {\n type AudioInput,\n type AudioSource,\n type ImageInput,\n type ImageSource,\n sniffAudio,\n sniffImage,\n YotoError,\n} from \"@mcp-yoto/core\";\n\nconst MAX_AUDIO_BYTES = 500 * 1024 * 1024;\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\nconst SNIFF_BYTES = 4096;\n\n/** Expands a leading `~` to the user's home directory. Exported for tests. */\nexport function expandHome(rawPath: string): string {\n if (rawPath === \"~\") return homedir();\n if (rawPath.startsWith(\"~/\") || rawPath.startsWith(\"~\\\\\")) {\n return resolvePath(homedir(), rawPath.slice(2));\n }\n return rawPath;\n}\n\n/** `~` expansion, then absolute-as-is (including UNC `\\\\server\\share\\...`), else resolved against the cwd. Exported for tests. */\nexport function toAbsolutePath(rawPath: string): string {\n const expanded = expandHome(rawPath);\n if (expanded.startsWith(\"\\\\\\\\\") || isAbsolute(expanded)) return expanded;\n return resolvePath(process.cwd(), expanded);\n}\n\nasync function readHead(path: string, length: number): Promise<Uint8Array> {\n const handle = await open(path, \"r\");\n try {\n const buffer = Buffer.alloc(length);\n const { bytesRead } = await handle.read(buffer, 0, length, 0);\n return buffer.subarray(0, bytesRead);\n } finally {\n await handle.close();\n }\n}\n\nasync function statOrValidationError(path: string, label: string): Promise<{ size: number }> {\n let stats: Awaited<ReturnType<typeof stat>>;\n try {\n stats = await stat(path);\n } catch (error) {\n throw new YotoError(`Could not find the ${label} at \"${path}\".`, {\n code: \"VALIDATION\",\n cause: error,\n hint: \"Check the path and try again.\",\n });\n }\n if (!stats.isFile()) {\n throw new YotoError(`\"${path}\" is not a file.`, { code: \"VALIDATION\" });\n }\n return { size: stats.size };\n}\n\nfunction audioContentType(format: string): string {\n switch (format) {\n case \"mp3\":\n return \"audio/mpeg\";\n case \"m4a\":\n return \"audio/mp4\";\n case \"wav\":\n return \"audio/wav\";\n case \"ogg\":\n return \"audio/ogg\";\n default:\n return \"application/octet-stream\";\n }\n}\n\nfunction imageContentType(format: string): string {\n switch (format) {\n case \"png\":\n return \"image/png\";\n case \"jpeg\":\n return \"image/jpeg\";\n case \"svg\":\n return \"image/svg+xml\";\n default:\n return \"application/octet-stream\";\n }\n}\n\n/**\n * Resolves a `yoto_upload_audio`/`yoto_add_track` input to a streamed local\n * file. Sniffs the real format from the file's first bytes -- not the\n * extension -- and throws `INVALID_AUDIO` before opening a stream or\n * touching the network, so a `.txt` renamed to `.mp3` fails fast.\n */\nexport async function resolveAudio(input: AudioInput): Promise<AudioSource> {\n if (\"audioUrl\" in input) {\n throw new YotoError(\"This CLI reads local files -- pass audioFilePath, not audioUrl.\", {\n code: \"VALIDATION\",\n hint: \"audioUrl is for the remote (paste-a-link) connector only.\",\n });\n }\n const path = toAbsolutePath(input.audioFilePath);\n const { size } = await statOrValidationError(path, \"audio file\");\n if (size > MAX_AUDIO_BYTES) {\n throw new YotoError(\n `\"${path}\" is ${(size / (1024 * 1024)).toFixed(1)} MB, over the 500 MB limit.`,\n {\n code: \"VALIDATION\",\n },\n );\n }\n\n const head = await readHead(path, SNIFF_BYTES);\n const sniffed = sniffAudio(head as Uint8Array<ArrayBuffer>, basename(path));\n\n const stream = Readable.toWeb(createReadStream(path)) as unknown as ReadableStream<Uint8Array>;\n return {\n stream,\n size,\n contentType: audioContentType(sniffed.format),\n filename: basename(path),\n };\n}\n\n/**\n * Resolves a `yoto_upload_icon` input to fully-buffered local bytes (icons\n * are small -- no need to stream). Same sniff-before-anything-else\n * discipline as `resolveAudio`.\n */\nexport async function resolveImage(input: ImageInput): Promise<ImageSource> {\n if (\"imageUrl\" in input) {\n throw new YotoError(\"This CLI reads local files -- pass imagePath, not imageUrl.\", {\n code: \"VALIDATION\",\n hint: \"imageUrl is for the remote (paste-a-link) connector only.\",\n });\n }\n const path = toAbsolutePath(input.imagePath);\n const { size } = await statOrValidationError(path, \"image file\");\n if (size > MAX_IMAGE_BYTES) {\n throw new YotoError(`\"${path}\" is over the 5 MB icon limit.`, { code: \"VALIDATION\" });\n }\n\n const buffer = await readFile(path);\n const bytes = new Uint8Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength,\n ) as Uint8Array<ArrayBuffer>;\n const sniffed = sniffImage(bytes, basename(path));\n\n return { bytes, contentType: imageContentType(sniffed.format), filename: basename(path) };\n}\n","/**\n * Builds the CLI's `McpServer` (all 14 `yoto_*` tools + resources + prompts,\n * via `@mcp-yoto/core`'s `createServer`) and serves it over stdio.\n *\n * `StdioServerTransport` lives at `@modelcontextprotocol/server/stdio`, NOT\n * `@modelcontextprotocol/node` (that package is Node-specific HTTP\n * transports for a server that speaks Streamable HTTP over `node:http` --\n * apps/worker's Cloudflare-hosted equivalent is `@modelcontextprotocol/hono`;\n * neither is stdio). Confirmed against the installed package's own\n * `dist/stdio.d.mts` -- see the report handed back after this phase.\n */\n\nimport { createRequire } from \"node:module\";\nimport { type AuthAdapter, createServer, type Logger, type YotoClient } from \"@mcp-yoto/core\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/server/stdio\";\nimport { resolveAudio, resolveImage } from \"./resolve.js\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nexport interface CreateCliServerOptions {\n auth: AuthAdapter;\n client: YotoClient;\n logger: Logger;\n iconBaseUrl?: string;\n}\n\nexport function createCliServer(options: CreateCliServerOptions) {\n return createServer(\n {\n auth: options.auth,\n client: options.client,\n logger: options.logger,\n iconBaseUrl: options.iconBaseUrl,\n resolveAudio,\n resolveImage,\n mode: \"cli\",\n },\n {\n name: \"mcp-yoto\",\n version,\n title: \"Yoto (Works with Yoto)\",\n iconBaseUrl: options.iconBaseUrl,\n websiteUrl: \"https://github.com/danpillay87/mcp-yoto\",\n },\n );\n}\n\n/** Connects the server to the current process's stdin/stdout. Never resolves until the transport closes. */\nexport async function runStdioServer(options: CreateCliServerOptions): Promise<void> {\n const server = createCliServer(options);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","/**\n * `npx mcp-yoto` entrypoint (invoked via bin/mcp-yoto.mjs).\n *\n * stdout is reserved for JSON-RPC frames when running as an MCP server\n * (the default, no-subcommand mode) -- every diagnostic goes to stderr.\n * `status` is the one deliberate exception: it prints its `AuthStatus` JSON\n * to stdout, because it's meant to be piped/parsed by a human or script\n * checking sign-in state, not read by an MCP client. See test/stdio-purity.test.ts.\n */\n\nimport { createRequire } from \"node:module\";\nimport { type LogLevel as CoreLogLevel, createLogger, YotoClient } from \"@mcp-yoto/core\";\nimport { createCliAuthAdapter } from \"./auth/adapter.js\";\nimport { DEFAULT_CLIENT_ID, loadConfig } from \"./config.js\";\nimport { runStdioServer } from \"./server.js\";\n\nexport { DEFAULT_CLIENT_ID };\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nconst HELP_TEXT = `mcp-yoto ${version} -- MCP server for Yoto (cards, tracks, icons, devices)\n\nUsage:\n npx mcp-yoto Run the MCP server over stdio (for MCP clients)\n npx mcp-yoto login Sign in to Yoto (opens your browser)\n npx mcp-yoto logout Remove the locally stored Yoto credential\n npx mcp-yoto status Print sign-in status as JSON (to stdout)\n npx mcp-yoto --version Print the installed version\n npx mcp-yoto --help Show this help\n\nEnvironment variables:\n YOTO_CLIENT_ID Override the Yoto dev-app client id\n YOTO_REDIRECT_PORT Loopback port used during sign-in (default 8791;\n must match the redirect URI registered at Yoto)\n YOTO_NO_BROWSER Set to 1 to print the sign-in URL instead of\n opening a browser automatically\n LOG_LEVEL debug | info | warn | error (default info)\n MCP_YOTO_ICON_BASE Base URL tool icons are served from\n\nYour Yoto credential is stored in your OS keychain when available, or in a\nlocal file otherwise (run \"status\" to see which). Nothing is ever printed\nto stdout except JSON-RPC frames (default mode) or the \"status\" JSON.\n`;\n\nfunction stderrLogSink(line: {\n level: string;\n message: string;\n data?: Record<string, unknown>;\n}): void {\n const suffix = line.data ? ` ${JSON.stringify(line.data)}` : \"\";\n process.stderr.write(`[mcp-yoto] ${line.level}: ${line.message}${suffix}\\n`);\n}\n\nexport async function main(argv: string[] = process.argv.slice(2)): Promise<void> {\n const [command] = argv;\n\n // --version/--help are diagnostics, not protocol traffic or the `status`\n // exception -- they go to stderr too, so stdout's contract never has a\n // third case to reason about.\n if (command === \"--version\" || command === \"-v\") {\n console.error(version);\n return;\n }\n if (command === \"--help\" || command === \"-h\") {\n console.error(HELP_TEXT);\n return;\n }\n\n const config = loadConfig();\n const logLevel: CoreLogLevel = config.logLevel;\n const logger = createLogger({ level: logLevel, sink: stderrLogSink });\n\n const auth = await createCliAuthAdapter({ config, logger });\n const client = new YotoClient({\n getToken: () => auth.getAccessToken(),\n baseUrl: config.audience,\n logger,\n });\n\n if (command === \"login\") {\n if (!auth.signIn) throw new Error(\"Sign-in isn't available on this connection.\");\n const result = await auth.signIn({\n openBrowser: !config.noBrowser,\n // Fires synchronously as soon as the authorize URL is built, well\n // before the loopback callback ever arrives -- see adapter.ts. With\n // YOTO_NO_BROWSER=1 (or no default handler registered) this is the\n // only place the user ever sees the link.\n onAuthorizeUrl: (url) => {\n process.stderr.write(\n \"Sign in to Yoto in your browser. If it did not open, use this link:\\n\",\n );\n process.stderr.write(`${url}\\n`);\n },\n });\n if (result.url) process.stderr.write(`Sign-in URL: ${result.url}\\n`);\n process.stderr.write(`${result.message}\\n`);\n return;\n }\n\n if (command === \"logout\") {\n if (!auth.signOut) throw new Error(\"Sign-out isn't available on this connection.\");\n await auth.signOut();\n process.stderr.write(\"Signed out of Yoto.\\n\");\n return;\n }\n\n if (command === \"status\") {\n const status = await auth.status();\n // The one deliberate non-MCP use of stdout -- see the file header comment.\n console.log(JSON.stringify(status, null, 2));\n return;\n }\n\n if (command) {\n process.stderr.write(`Unknown command: ${command}\\n\\n${HELP_TEXT}`);\n process.exitCode = 1;\n return;\n }\n\n await runStdioServer({ auth, client, logger, iconBaseUrl: config.iconBaseUrl });\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { type AudioInput, type AudioSource, type ImageInput, type ImageSource } from "@mcp-yoto/core";
2
+ /** Expands a leading `~` to the user's home directory. Exported for tests. */
3
+ export declare function expandHome(rawPath: string): string;
4
+ /** `~` expansion, then absolute-as-is (including UNC `\\server\share\...`), else resolved against the cwd. Exported for tests. */
5
+ export declare function toAbsolutePath(rawPath: string): string;
6
+ /**
7
+ * Resolves a `yoto_upload_audio`/`yoto_add_track` input to a streamed local
8
+ * file. Sniffs the real format from the file's first bytes -- not the
9
+ * extension -- and throws `INVALID_AUDIO` before opening a stream or
10
+ * touching the network, so a `.txt` renamed to `.mp3` fails fast.
11
+ */
12
+ export declare function resolveAudio(input: AudioInput): Promise<AudioSource>;
13
+ /**
14
+ * Resolves a `yoto_upload_icon` input to fully-buffered local bytes (icons
15
+ * are small -- no need to stream). Same sniff-before-anything-else
16
+ * discipline as `resolveAudio`.
17
+ */
18
+ export declare function resolveImage(input: ImageInput): Promise<ImageSource>;
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Turns a `yoto_upload_audio`/`yoto_upload_icon`-style CLI input
3
+ * (`audioFilePath` / `imagePath`) into the streamable bytes packages/core's
4
+ * tools expect (`AudioSource` / `ImageSource`), per `CreateToolsDeps`'s
5
+ * `resolveAudio`/`resolveImage` in `@mcp-yoto/core`. The remote connector
6
+ * has its own version of this file that fetches an `https://` URL instead
7
+ * -- this one only ever touches the local filesystem, and never makes a
8
+ * network call, so it can (and must) reject an unsupported file before any
9
+ * upload attempt.
10
+ */
11
+ import { createReadStream } from "node:fs";
12
+ import { open, readFile, stat } from "node:fs/promises";
13
+ import { homedir } from "node:os";
14
+ import { basename, isAbsolute, resolve as resolvePath } from "node:path";
15
+ import { Readable } from "node:stream";
16
+ import { sniffAudio, sniffImage, YotoError, } from "@mcp-yoto/core";
17
+ const MAX_AUDIO_BYTES = 500 * 1024 * 1024;
18
+ const MAX_IMAGE_BYTES = 5 * 1024 * 1024;
19
+ const SNIFF_BYTES = 4096;
20
+ /** Expands a leading `~` to the user's home directory. Exported for tests. */
21
+ export function expandHome(rawPath) {
22
+ if (rawPath === "~")
23
+ return homedir();
24
+ if (rawPath.startsWith("~/") || rawPath.startsWith("~\\")) {
25
+ return resolvePath(homedir(), rawPath.slice(2));
26
+ }
27
+ return rawPath;
28
+ }
29
+ /** `~` expansion, then absolute-as-is (including UNC `\\server\share\...`), else resolved against the cwd. Exported for tests. */
30
+ export function toAbsolutePath(rawPath) {
31
+ const expanded = expandHome(rawPath);
32
+ if (expanded.startsWith("\\\\") || isAbsolute(expanded))
33
+ return expanded;
34
+ return resolvePath(process.cwd(), expanded);
35
+ }
36
+ async function readHead(path, length) {
37
+ const handle = await open(path, "r");
38
+ try {
39
+ const buffer = Buffer.alloc(length);
40
+ const { bytesRead } = await handle.read(buffer, 0, length, 0);
41
+ return buffer.subarray(0, bytesRead);
42
+ }
43
+ finally {
44
+ await handle.close();
45
+ }
46
+ }
47
+ async function statOrValidationError(path, label) {
48
+ let stats;
49
+ try {
50
+ stats = await stat(path);
51
+ }
52
+ catch (error) {
53
+ throw new YotoError(`Could not find the ${label} at "${path}".`, {
54
+ code: "VALIDATION",
55
+ cause: error,
56
+ hint: "Check the path and try again.",
57
+ });
58
+ }
59
+ if (!stats.isFile()) {
60
+ throw new YotoError(`"${path}" is not a file.`, { code: "VALIDATION" });
61
+ }
62
+ return { size: stats.size };
63
+ }
64
+ function audioContentType(format) {
65
+ switch (format) {
66
+ case "mp3":
67
+ return "audio/mpeg";
68
+ case "m4a":
69
+ return "audio/mp4";
70
+ case "wav":
71
+ return "audio/wav";
72
+ case "ogg":
73
+ return "audio/ogg";
74
+ default:
75
+ return "application/octet-stream";
76
+ }
77
+ }
78
+ function imageContentType(format) {
79
+ switch (format) {
80
+ case "png":
81
+ return "image/png";
82
+ case "jpeg":
83
+ return "image/jpeg";
84
+ case "svg":
85
+ return "image/svg+xml";
86
+ default:
87
+ return "application/octet-stream";
88
+ }
89
+ }
90
+ /**
91
+ * Resolves a `yoto_upload_audio`/`yoto_add_track` input to a streamed local
92
+ * file. Sniffs the real format from the file's first bytes -- not the
93
+ * extension -- and throws `INVALID_AUDIO` before opening a stream or
94
+ * touching the network, so a `.txt` renamed to `.mp3` fails fast.
95
+ */
96
+ export async function resolveAudio(input) {
97
+ if ("audioUrl" in input) {
98
+ throw new YotoError("This CLI reads local files -- pass audioFilePath, not audioUrl.", {
99
+ code: "VALIDATION",
100
+ hint: "audioUrl is for the remote (paste-a-link) connector only.",
101
+ });
102
+ }
103
+ const path = toAbsolutePath(input.audioFilePath);
104
+ const { size } = await statOrValidationError(path, "audio file");
105
+ if (size > MAX_AUDIO_BYTES) {
106
+ throw new YotoError(`"${path}" is ${(size / (1024 * 1024)).toFixed(1)} MB, over the 500 MB limit.`, {
107
+ code: "VALIDATION",
108
+ });
109
+ }
110
+ const head = await readHead(path, SNIFF_BYTES);
111
+ const sniffed = sniffAudio(head, basename(path));
112
+ const stream = Readable.toWeb(createReadStream(path));
113
+ return {
114
+ stream,
115
+ size,
116
+ contentType: audioContentType(sniffed.format),
117
+ filename: basename(path),
118
+ };
119
+ }
120
+ /**
121
+ * Resolves a `yoto_upload_icon` input to fully-buffered local bytes (icons
122
+ * are small -- no need to stream). Same sniff-before-anything-else
123
+ * discipline as `resolveAudio`.
124
+ */
125
+ export async function resolveImage(input) {
126
+ if ("imageUrl" in input) {
127
+ throw new YotoError("This CLI reads local files -- pass imagePath, not imageUrl.", {
128
+ code: "VALIDATION",
129
+ hint: "imageUrl is for the remote (paste-a-link) connector only.",
130
+ });
131
+ }
132
+ const path = toAbsolutePath(input.imagePath);
133
+ const { size } = await statOrValidationError(path, "image file");
134
+ if (size > MAX_IMAGE_BYTES) {
135
+ throw new YotoError(`"${path}" is over the 5 MB icon limit.`, { code: "VALIDATION" });
136
+ }
137
+ const buffer = await readFile(path);
138
+ const bytes = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
139
+ const sniffed = sniffImage(bytes, basename(path));
140
+ return { bytes, contentType: imageContentType(sniffed.format), filename: basename(path) };
141
+ }