FeaturesTemplatesShowcaseTownie
AI
BlogDocsPricing
Log inSign up
c15r
c15rChat
Public
Like
Chat
Home
Code
18
backend
1
frontend
6
shared
2
test
4
AFFORDANCE-COMPONENT-GUIDE.md
AFFORDANCE-FRAMEWORK.md
AFFORDANCE-IMPLEMENTATION-SUMMARY.md
COMMAND-PALETTE-REVIEW.md
DEPENDENCY-INJECTION-REVIEW.md
IMPLEMENTATION-SUMMARY-AFFORDANCES.md
IMPLEMENTATION-SUMMARY.md
NextSteps-Examples.md
NextSteps-README.md
README.md
ResourceViewer-README.md
TESTING.md
package.json
H
test-runner.ts
Branches
1
Pull requests
Remixes
1
History
Environment variables
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data โ€“ all from the browser, and deployed in milliseconds.
Sign up now
Code
/
ResourceViewer-README.md
Code
/
ResourceViewer-README.md
Search
6/17/2025
Viewing readonly version of main branch: v1234
View latest version
ResourceViewer-README.md

ResourceViewer Component

The ResourceViewer component provides intelligent display of file and resource content from MCP (Model Context Protocol) tools with syntax highlighting, fullscreen support, and adaptive rendering.

Overview

ResourceViewer automatically detects when MCP tools return file content references and fetches the actual content for display. It supports multiple rendering modes based on file type and provides a rich viewing experience with syntax highlighting powered by CodeMirror.

Features

  • ๐ŸŽจ Syntax Highlighting - Powered by CodeMirror with support for JavaScript, HTML, CSS, JSON, Markdown, Python, XML, and more
  • ๐Ÿ“ฑ Fullscreen Mode - Toggle fullscreen for better viewing of large files
  • ๐Ÿ”„ Smart Caching - Caches fetched content for 5 minutes to improve performance
  • ๐Ÿ” Retry Mechanism - Automatic retry functionality when resource fetching fails
  • ๐Ÿ“‹ Metadata Display - Shows file type, content type, and source server information
  • ๐ŸŽฏ Adaptive Rendering - Chooses optimal rendering mode based on file type and hints

Usage

ResourceViewer is automatically triggered when MCP tools return responses matching the FileViewerResult schema:

// Example MCP tool response that triggers ResourceViewer { "output": { "resourcePointer": { "sourceKey": "path/to/file.js", "contentType": "application/javascript", "fileType": "javascript", "renderHint": { "preferredRenderer": "code", "syntaxHighlight": true, "lineNumbers": true } }, "sourceKey": "path/to/file.js", "fileType": "javascript" } }

Schema Reference

FileViewerResult

The main response type that triggers ResourceViewer:

type FileViewerResult = | { output: FileViewerResponse } | { error: string; output: null };

FileViewerResponse

interface FileViewerResponse { resourcePointer: ResourcePointer; sourceKey: string; fileType: ResourcePointer['fileType']; }

ResourcePointer

interface ResourcePointer { sourceKey: string; // Path/key to the resource contentType: string; // MIME type (e.g., "application/javascript") fileType: FileType; // Detected file type for syntax highlighting renderHint: RenderHints; // Rendering preferences }

RenderHints

interface RenderHints { preferredRenderer: 'native' | 'code' | 'text'; syntaxHighlight: boolean; lineNumbers: boolean; }

Supported File Types

  • javascript - JavaScript files (.js, .jsx, .ts, .tsx)
  • html - HTML files (.html, .htm)
  • css - CSS files (.css, .scss, .sass)
  • json - JSON files (.json)
  • markdown - Markdown files (.md, .mdx)
  • python - Python files (.py)
  • xml - XML files (.xml, .svg)
  • text - Plain text files
  • unknown - Fallback for unrecognized types

Rendering Modes

Code Mode (preferredRenderer: 'code')

  • Uses CodeMirror editor with syntax highlighting
  • Supports line numbers when lineNumbers: true
  • Best for source code files

Native Mode (preferredRenderer: 'native')

  • Renders HTML/XML content in an iframe
  • Provides native browser rendering
  • Best for HTML documents and SVG files

Text Mode (preferredRenderer: 'text')

  • Plain text display with optional line numbers
  • Best for configuration files and plain text

Integration

Server Name Resolution

ResourceViewer automatically resolves the MCP server name by matching the tool_use_id from mcp_tool_result blocks with corresponding mcp_tool_use blocks:

// In Message.tsx const toolUseBlock = findToolUseBlock(blocks, blk.tool_use_id); const serverName = toolUseBlock?.server_name;

Resource Fetching

Resources are fetched using the MCP client's readResource() method:

const client = mcpClients.find(client => client.serverInfo?.name === serverName ); const content = await client.readResource(sourceKey);

Caching Strategy

  • Resources are cached in component state for 5 minutes
  • Cache key format: ${serverName}_${sourceKey}
  • Cache is cleared on retry to force fresh fetch

Error Handling

ResourceViewer provides comprehensive error handling:

  1. Parse Errors - Invalid FileViewerResult schema
  2. Server Not Found - MCP server unavailable
  3. Resource Not Found - Resource doesn't exist
  4. Network Errors - Connection issues

Error states show:

  • Clear error message
  • Retry button
  • Expandable metadata for debugging

Styling

ResourceViewer uses CSS classes for styling:

  • .resource-viewer - Main container
  • .resource-viewer-header - Header with metadata and controls
  • .resource-viewer-content - Content area
  • .resource-viewer-error - Error state styling
  • .resource-viewer.fullscreen - Fullscreen mode

Examples

JavaScript File Display

{ "output": { "resourcePointer": { "sourceKey": "src/components/App.tsx", "contentType": "application/typescript", "fileType": "javascript", "renderHint": { "preferredRenderer": "code", "syntaxHighlight": true, "lineNumbers": true } }, "sourceKey": "src/components/App.tsx", "fileType": "javascript" } }

HTML Document Display

{ "output": { "resourcePointer": { "sourceKey": "public/index.html", "contentType": "text/html", "fileType": "html", "renderHint": { "preferredRenderer": "native", "syntaxHighlight": false, "lineNumbers": false } }, "sourceKey": "public/index.html", "fileType": "html" } }

Configuration File Display

{ "output": { "resourcePointer": { "sourceKey": "package.json", "contentType": "application/json", "fileType": "json", "renderHint": { "preferredRenderer": "code", "syntaxHighlight": true, "lineNumbers": true } }, "sourceKey": "package.json", "fileType": "json" } }

Implementation Notes

  • ResourceViewer is integrated into the Message component's renderAnthropicBlocks() function
  • Detection happens in the mcp_tool_result case after NextSteps and before HTML detection
  • CodeMirror extensions are loaded dynamically based on file type
  • Fullscreen mode uses fixed positioning with high z-index
  • Mobile-responsive design with touch-friendly controls

Performance Optimizations

  • Memoized MCP Client Resolution - Client lookup is memoized to prevent unnecessary re-renders
  • Stable Reference Management - MCP clients array is memoized in the parent hook to prevent reload loops
  • Simplified Dependency Chains - Reduced nested useCallback dependencies to minimize effect re-executions
  • Optimized useEffect Dependencies - Removed function dependencies that caused infinite reload loops

Dependencies

  • CodeMirror 6 - Syntax highlighting and code editing
  • React 18 - Component framework
  • MCP Client - Resource fetching from MCP servers

Future Enhancements

  • Binary File Support - Display images, PDFs, etc.
  • Diff Viewer - Compare file versions
  • Search/Find - In-file search functionality
  • Download Support - Save resources locally
  • Collaborative Editing - Real-time editing capabilities
Go to top
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Product
FeaturesPricing
Developers
DocsStatusAPI ExamplesNPM Package Examples
Explore
ShowcaseTemplatesNewest ValsTrending ValsNewsletter
Company
AboutBlogCareersBrandhi@val.town
Terms of usePrivacy policyAbuse contact
ยฉ 2025 Val Town, Inc.