Skip to content

Add Apple Design docs and resource previews#49

Open
agoodkind wants to merge 19 commits into
kimsungwhee:mainfrom
agoodkind:agoodkind/apple-hig-docs
Open

Add Apple Design docs and resource previews#49
agoodkind wants to merge 19 commits into
kimsungwhee:mainfrom
agoodkind:agoodkind/apple-hig-docs

Conversation

@agoodkind

@agoodkind agoodkind commented Jul 1, 2026

Copy link
Copy Markdown

Summary

This change adds Apple Design support to the MCP server.

The server can now read Human Interface Guidelines pages, parse Apple Design pages, discover Design Resources, download direct Apple-hosted resource files, and return visual examples as MCP image blocks.

Change

The new Design tools search HIG JSON references, parse Apple Design HTML pages, list resource catalog entries with stable IDs, and fetch examples as MCP image content blocks.

Direct Apple-hosted downloads are cached outside the repository, returned as MCP resource_link blocks, and exposed through resources/list and resources/read as blob resources.

The HIG formatter renders common Apple content blocks, including headings, paragraphs, emphasis, strong text, references, images, lists, link grids, tables, asides, tabs, alerts, supported platforms, and change logs.

External Figma, Sketch web, and sketch:// links remain catalog metadata and preview sources. The server does not attempt authenticated browser downloads for them.

Hardening

Apple Design fetches now validate manual redirects, enforce byte limits for content, previews, and downloads, bound aggregate cache size, use exclusive cache writes, reuse in-flight same-URL downloads, and avoid inlining large downloaded images.

Resource IDs include stable item data and a URL hash so same-label resource entries do not drift when Apple reorders the catalog.

Testing

  • pnpm install
  • pnpm test --runInBand passed with 32 suites and 529 tests.
  • pnpm run build passed.
  • pnpm run lint exited 0 with warnings only.
  • git diff --check passed.

I ran a live MCP stdio end-to-end check against node dist/index.js with current Apple endpoints and a temporary cache directory.

The live check verified initialize declares resources: {}, tools/list exposes the five Apple Design tools, get_apple_design_content reads the live Layout HIG page, and get_apple_doc_content delegates /design/... URLs to the Design content path.

The live check also verified search_apple_design_docs, list_apple_design_resources, get_apple_design_examples, download_apple_design_resource, resources/list, and resources/read.

get_apple_design_examples returned a real image/png MCP image block. download_apple_design_resource downloaded a live Apple Design preview image, returned a resource_link, and resources/read returned blob content for the cached image.

I visually opened the downloaded preview image. It rendered correctly as an Apple Design UIKit thumbnail with three iPhone mockups.

Review

I ran blind Codex review subagents through tmux using codex exec in read-only mode, with no prior conversation context in the prompts.

Loops 45 through 100 covered repeated bug-focused and security-focused reviews. Reported findings were fixed, verified locally, and reviewed again. The final loop 100 results were clean: bug review found no bugs, and security review found no issues.

Summary by CodeRabbit

  • New Features
    • Added Apple Design & Human Interface Guidelines support across search, content viewing, resource browsing, downloads, and visual examples.
    • Introduced local caching for Apple Design content and downloadable design resources.
    • Extended available MCP tools/resources and updated the documented feature set and usage examples.
  • Bug Fixes
    • Improved redirect handling for design content downloads and ensured proper response formatting for additional content types.
    • Corrected cache statistics reporting to include design-related entries.
  • Tests
    • Added/expanded integration and unit coverage for Apple Design tools, resource caching, and URL/redirect behavior.
  • Documentation
    • Updated README with new tools, examples, and cache configuration details.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds Apple Design/HIG support to the MCP server: new schemas and tools for searching design docs, fetching content, listing/downloading resources, returning examples, exposing cached resources, and handling Apple Design URLs and redirects.

Changes

Apple Design Docs Feature

Layer / File(s) Summary
Schemas, constants, and tool registry
src/schemas/design.schema.ts, src/schemas/index.ts, src/tools/definitions.ts, src/utils/constants.ts, src/utils/cache.ts
Adds Apple Design request schemas, tool definitions, URL constants, cache TTL/size entries, and design content/resource cache instances.
Apple Design URL handling and redirect support
src/utils/url-converter.ts, src/utils/http-client.ts, src/__tests__/http-client-headers-integration.test.ts, tests/utils/url-converter.test.ts
Adds Apple Design URL conversion/detection, manual redirect handling in the HTTP client, and tests for both behaviors.
Design docs parsing and formatting
src/tools/design-docs.ts
Implements Apple Design JSON/HTML formatting, resource catalog parsing, and Markdown rendering helpers.
Design docs handlers and cache access
src/tools/design-docs.ts
Implements Apple Design search/content/list/download/examples handlers plus MCP resource list/read support, cache-backed downloads, and image candidate fetching.
Server and tool handler wiring
src/index.ts, src/tools/handlers.ts
Registers Apple Design resources and tools in the server, routes Apple Design URLs, updates handler typing, and adds cache stats for design caches.
Design tool and server tests
tests/index.test.ts, tests/response-format.test.ts, tests/tools/design-docs.test.ts, tests/tools/handlers.test.ts
Adds coverage for Apple Design tool wiring, resource handlers, response formatting, URL conversion, and design-docs behavior.
Docs and workspace config
README.md, pnpm-workspace.yaml
Documents the Apple Design features/tools/caching and disables builds for esbuild and unrs-resolver.

Estimated code review effort: 5 (Critical) | ~120 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: adding Apple Design docs support and resource preview functionality.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@agoodkind agoodkind marked this pull request as ready for review July 1, 2026 05:44
Copilot AI review requested due to automatic review settings July 1, 2026 05:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Apple Design support to the Apple Developer Documentation MCP server, including new tools for searching and reading Human Interface Guidelines (HIG) and Apple Design pages, listing Design Resources, downloading Apple-hosted resource files into an MCP-exposed cache, and returning visual previews as MCP image blocks.

Changes:

  • Introduces new Apple Design tools (search_apple_design_docs, get_apple_design_content, list_apple_design_resources, download_apple_design_resource, get_apple_design_examples) and wires them into the server/tool handler layer.
  • Adds a new Design docs implementation with HTML parsing, HIG JSON formatting, resource catalog parsing, manual redirect validation, byte limits, and a local cache exposed via MCP resources/list and resources/read.
  • Expands tests to cover the new tools, resource handlers, redirect handling, and response format validation (including image and resource_link blocks).

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/utils/url-converter.test.ts Adds coverage for HIG URL → design JSON API conversion and Apple Design URL detection.
tests/tools/handlers.test.ts Extends tool handler tests for new Apple Design tool routes and argument defaults.
tests/tools/design-docs.test.ts New comprehensive test suite for HIG formatting, HTML parsing, resource catalog parsing, downloads, caching, redirects, and examples.
tests/response-format.test.ts Updates response-format validation to accept image/resource_link/resource blocks and adds Apple Design tool validation.
tests/index.test.ts Verifies server registers MCP resources handlers and exposes Apple Design public methods.
src/utils/url-converter.ts Adds convertToDesignJsonApiUrl and isAppleDesignUrl; integrates design conversion into convertToJsonApiUrl.
src/utils/http-client.ts Adds manual redirect support (redirect, allowManualRedirect) so Design fetches can validate redirects safely.
src/utils/constants.ts Adds cache TTL/size constants and Apple Design URL constants.
src/utils/cache.ts Adds in-memory caches for Design content and Design resources.
src/tools/handlers.ts Extends tool dispatch for Apple Design tools and updates handler return type to CallToolResult.
src/tools/design-docs.ts New Apple Design implementation: search, content fetch/formatting, resource catalog, downloads/cache, examples, and MCP resources support.
src/tools/definitions.ts Adds MCP tool definitions and schemas for the five Apple Design tools.
src/schemas/index.ts Exports the new Apple Design zod schemas.
src/schemas/design.schema.ts Defines zod schemas for Apple Design tool inputs.
src/index.ts Wires in Design tools, delegates /design/... URLs, and adds MCP resources/list/resources/read handlers.
src/tests/http-client-headers-integration.test.ts Adds test ensuring redirect options are passed through to fetch.
README.md Documents Apple Design/HIG features, usage examples, and new tools.
pnpm-workspace.yaml Updates workspace config and adds build-allowlist entries.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/tools/design-docs.ts
@agoodkind

Copy link
Copy Markdown
Author

@kimsungwhee I made this PR to add Apple design docs to the MCP. If you have time I would love if you could take a look :) thanks for making this MCP!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (4)
src/utils/http-client.ts (1)

240-256: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Document the manual-redirect assumption
This path depends on redirect: 'manual' exposing the actual 3xx status and Location header; add a short note so future changes don’t assume browser-style opaque redirects.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/http-client.ts` around lines 240 - 256, The manual-redirect branch
in http-client’s redirect handling should be documented to make the
3xx/Location-header assumption explicit. Add a short comment near
isAllowedManualRedirect and the return response path explaining that
allowManualRedirect relies on fetch running with redirect: 'manual' so
response.status and Location remain accessible. Keep the note close to the
pool.markSuccess/pool.markFailure logic and the redirect check so future changes
to HttpClient don’t assume browser-style opaque redirects.
src/schemas/design.schema.ts (1)

14-14: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer Zod v4 top-level z.url() over deprecated .string().url().

Zod v4 deprecated the chained string-format methods (.string().url(), .string().email(), etc.) in favor of top-level functions (z.url()). The chained form still works but is marked for removal in a future major version.

♻️ Suggested refactor
 export const getAppleDesignContentSchema = z.object({
-  url: z.string().url().describe('Apple Design URL to read'),
+  url: z.url().describe('Apple Design URL to read'),
 });

Apply the same substitution at downloadAppleDesignResourceSchema.url (line 28) and getAppleDesignExamplesSchema.url (line 34).

Also applies to: 28-28, 34-34

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/schemas/design.schema.ts` at line 14, Update the URL fields in the Apple
design schemas to use Zod v4 top-level z.url() instead of the deprecated
z.string().url() chain. Apply this change in the relevant schema definitions
identified by design.schema.ts, including the url properties in the main schema,
downloadAppleDesignResourceSchema, and getAppleDesignExamplesSchema, so all URL
validation uses the modern API consistently.
src/index.ts (1)

216-275: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Inconsistent error handling for new Apple Design methods.

Unlike searchAppleDocs/getAppleDocContent (manual try/catch → createToolErrorResponse/createStandardErrorResponse) or other methods using this.handleAsyncOperation(...), these five new methods forward directly to the handle*AppleDesign* functions with no local error handling. Errors thrown by those handlers (e.g. handleDownloadAppleDesignResource throws a plain Error when neither resourceId nor url is supplied) will only be caught by the generic catch-all in setupTools()'s CallToolRequestSchema handler, which produces a bare Error: ${message} string without the tool-specific suggestions that createToolErrorResponse provides for the rest of the toolset.

♻️ Example fix pattern for one method (repeat for the others)
 public async downloadAppleDesignResource(
   resourceId?: string,
   url?: string,
   maxBytes?: number,
 ) {
-  return await handleDownloadAppleDesignResource({
-    resourceId,
-    url,
-    maxBytes,
-  });
+  try {
+    return await handleDownloadAppleDesignResource({
+      resourceId,
+      url,
+      maxBytes,
+    });
+  } catch (error) {
+    if (error && typeof error === 'object' && 'type' in error) {
+      return createToolErrorResponse(error as any, 'downloadAppleDesignResource') as CallToolResult;
+    }
+    return createStandardErrorResponse(error, 'downloadAppleDesignResource') as CallToolResult;
+  }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/index.ts` around lines 216 - 275, The new Apple Design methods in
handleSearchAppleDesignDocs, handleGetAppleDesignContent,
handleListAppleDesignResources, handleDownloadAppleDesignResource, and
handleGetAppleDesignExamples bypass the tool’s normal error handling path. Wrap
each method in the same pattern used by searchAppleDocs/getAppleDocContent or
route them through this.handleAsyncOperation so thrown errors are converted into
createToolErrorResponse/createStandardErrorResponse instead of falling through
to the generic setupTools catch-all. Ensure any validation errors from the
handle*AppleDesign* functions return tool-specific, user-friendly messages.
tests/tools/design-docs.test.ts (1)

265-327: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a collision-path test for parseDesignResourcesHtml.

The "keep resource IDs stable when same-label resources reorder" test (Lines 502-553) verifies stability across reordering, but doesn't exercise the seenResourceIds dedup map that parseDesignResourcesHtml maintains for exact duplicate category/platform/title/format/URL combinations. Adding a case with two truly identical grid-items would validate the collision-suffix behavior that underpins the "stable IDs" guarantee called out in the PR objectives.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/tools/design-docs.test.ts` around lines 265 - 327, Add a test coverage
case around parseDesignResourcesHtml that uses two truly identical grid items so
the seenResourceIds dedup path is exercised. Update the Apple Design document
formatting test suite to assert the collision-suffix behavior for duplicate
category/platform/title/format/URL combinations, alongside the existing
reorder-stability test, so the stable ID guarantee is verified for exact
duplicates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/tools/design-docs.ts`:
- Around line 2104-2109: The cache write path in the open/writeFile/close flow
can leave behind an orphaned file if writeFile throws after the wx file is
created. Update the logic around the fileHandle write in the design-docs cache
writer to keep track of filePath, catch write failures, remove the partially
written file with rm(..., { force: true }), and then rethrow so the caller still
sees the error.
- Around line 953-965: The query preview path in `design-docs.ts` is still
collecting too many candidates because `filterDesignResources()` does not honor
`args.limit`. Update the `args.query` handling in this block to cap the filtered
`resources` before pushing preview URLs into `candidates`, or add an explicit
attempt limit in this loop so only up to `limit` query-derived previews are
enqueued.
- Around line 1882-1895: In the redirect-handling flow around
isRedirectResponse, make sure any response that is not returned to the caller
has its body explicitly consumed or canceled before the code follows the
redirect or throws on MAX_APPLE_DESIGN_REDIRECTS. Update the logic in the
redirect loop to cancel the current response body on the early-exit paths,
including the non-final redirect branch and the over-limit error path, so
repeated calls do not রেখে open sockets/resources. Use the existing response,
currentUrl, and getAppleDesignRedirectUrl flow as the place to add the cleanup.
- Around line 1276-1278: Clamp the parsed heading level before using it in the
markdown heading renderer in design-docs.ts. In the logic that computes level
and returns the heading string, ensure the value derived from getNumber(record,
'level') and headingLevel is normalized to the 1..6 range before passing it to
'#'.repeat(), so invalid or negative JSON values cannot throw or generate
malformed headings.

---

Nitpick comments:
In `@src/index.ts`:
- Around line 216-275: The new Apple Design methods in
handleSearchAppleDesignDocs, handleGetAppleDesignContent,
handleListAppleDesignResources, handleDownloadAppleDesignResource, and
handleGetAppleDesignExamples bypass the tool’s normal error handling path. Wrap
each method in the same pattern used by searchAppleDocs/getAppleDocContent or
route them through this.handleAsyncOperation so thrown errors are converted into
createToolErrorResponse/createStandardErrorResponse instead of falling through
to the generic setupTools catch-all. Ensure any validation errors from the
handle*AppleDesign* functions return tool-specific, user-friendly messages.

In `@src/schemas/design.schema.ts`:
- Line 14: Update the URL fields in the Apple design schemas to use Zod v4
top-level z.url() instead of the deprecated z.string().url() chain. Apply this
change in the relevant schema definitions identified by design.schema.ts,
including the url properties in the main schema,
downloadAppleDesignResourceSchema, and getAppleDesignExamplesSchema, so all URL
validation uses the modern API consistently.

In `@src/utils/http-client.ts`:
- Around line 240-256: The manual-redirect branch in http-client’s redirect
handling should be documented to make the 3xx/Location-header assumption
explicit. Add a short comment near isAllowedManualRedirect and the return
response path explaining that allowManualRedirect relies on fetch running with
redirect: 'manual' so response.status and Location remain accessible. Keep the
note close to the pool.markSuccess/pool.markFailure logic and the redirect check
so future changes to HttpClient don’t assume browser-style opaque redirects.

In `@tests/tools/design-docs.test.ts`:
- Around line 265-327: Add a test coverage case around parseDesignResourcesHtml
that uses two truly identical grid items so the seenResourceIds dedup path is
exercised. Update the Apple Design document formatting test suite to assert the
collision-suffix behavior for duplicate category/platform/title/format/URL
combinations, alongside the existing reorder-stability test, so the stable ID
guarantee is verified for exact duplicates.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c092c4c4-adfc-4537-9706-c4ebdb32ca00

📥 Commits

Reviewing files that changed from the base of the PR and between 28c06cb and cc15d2f.

📒 Files selected for processing (18)
  • README.md
  • pnpm-workspace.yaml
  • src/__tests__/http-client-headers-integration.test.ts
  • src/index.ts
  • src/schemas/design.schema.ts
  • src/schemas/index.ts
  • src/tools/definitions.ts
  • src/tools/design-docs.ts
  • src/tools/handlers.ts
  • src/utils/cache.ts
  • src/utils/constants.ts
  • src/utils/http-client.ts
  • src/utils/url-converter.ts
  • tests/index.test.ts
  • tests/response-format.test.ts
  • tests/tools/design-docs.test.ts
  • tests/tools/handlers.test.ts
  • tests/utils/url-converter.test.ts

Comment thread src/tools/design-docs.ts
Comment thread src/tools/design-docs.ts Outdated
Comment thread src/tools/design-docs.ts
Comment thread src/tools/design-docs.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants