Skip to content

Russian docs translation #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<a href="#-what-is-mcp-ui">What's mcp-ui?</a> •
<a href="#-installation">Installation</a> •
<a href="#-quickstart">Quickstart</a> •
<a href="#-json-schema-generator">JSON Schema Generator</a> •
<a href="#-core-concepts">Core Concepts</a> •
<a href="#-examples">Examples</a> •
<a href="#-roadmap">Roadmap</a> •
Expand Down Expand Up @@ -60,7 +61,7 @@ interface HtmlResourceBlock {

It's rendered in the client with the `<HtmlResource>` React component.

The HTML method is limited, and the external app method isn't secure enough for untrusted 3rd party sites. We need a better method. Some ideas we should explore: RSC, remotedom, etc.
`HtmlResource` now supports an experimental `secure` render mode that sanitizes the HTML with DOMPurify instead of using an iframe. This avoids the security pitfalls of embedding untrusted sites. Future improvements may leverage React Server Components or Remote DOM for even better isolation.

### UI Action

Expand Down Expand Up @@ -127,6 +128,27 @@ yarn add @mcp-ui/server @mcp-ui/client
```

3. **Enjoy** interactive MCP UIs — no extra configuration required.
## 🧩 JSON Schema Generator

Generate simple React forms from JSON Schema using the `generateUI` API.

```tsx
import { generateUI } from "@mcp-ui/generator";

const schema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "number" },
color: { type: "string", enum: ["red", "green"] },
},
};

export default function MyForm() {
return generateUI(schema);
}
```


## 🌍 Examples

Expand All @@ -153,6 +175,10 @@ Drop those URLs into any MCP-compatible host to see `mcp-ui` in action.
- [ ] Expand UI Action API (beyond tool calls)
- [ ] Do more with Resources and Sampling

## 🌙 Документация на русском

- [План трансформации проекта](docs/src/ru/transformation-plan.md)

## 🤝 Contributing

Contributions, ideas, and bug reports are welcome! See the [contribution guidelines](https://github.com/idosal/mcp-ui/blob/main/.github/CONTRIBUTING.md) to get started.
Expand Down
93 changes: 67 additions & 26 deletions docs/src/.vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineConfig } from 'vitepress';

export default defineConfig({
lang: 'en-US',
lang: 'en-US', // Default language
title: 'MCP UI',
description: 'MCP-UI Client & Server SDK Documentation',
base: '/mcp-ui/', // For GitHub Pages deployment
Expand All @@ -12,6 +12,7 @@ export default defineConfig({
},

themeConfig: {
// Nav will be common for all locales, or can be localized if needed
nav: [
{ text: 'Home', link: '/' },
{ text: 'Guide', link: '/guide/introduction' },
Expand All @@ -23,37 +24,77 @@ export default defineConfig({
// ]}
],

sidebar: {
'/guide/': [
{
text: 'Overview',
items: [
{ text: 'Introduction', link: '/guide/introduction' },
{ text: 'Getting Started', link: '/guide/getting-started' },
{ text: 'Protocol Details', link: '/guide/protocol-details' },
],
},
{
text: 'Server SDK (@mcp-ui/server)',
items: [
{ text: 'Overview', link: '/guide/server/overview' },
{ text: 'Usage & Examples', link: '/guide/server/usage-examples' },
// { text: 'API', link: '/guide/server/api' } // Placeholder
// Locale specific configurations
locales: {
root: {
label: 'English',
lang: 'en-US',
sidebar: {
'/guide/': [
{
text: 'Overview',
items: [
{ text: 'Introduction', link: '/guide/introduction' },
{ text: 'Getting Started', link: '/guide/getting-started' },
{ text: 'Protocol Details', link: '/guide/protocol-details' },
],
},
{
text: 'Server SDK (@mcp-ui/server)',
items: [
{ text: 'Overview', link: '/guide/server/overview' },
{ text: 'Usage & Examples', link: '/guide/server/usage-examples' },
// { text: 'API', link: '/guide/server/api' } // Placeholder
],
},
{
text: 'Client SDK (@mcp-ui/client)',
items: [
{ text: 'Overview', link: '/guide/client/overview' },
{
text: 'HtmlResource Component',
link: '/guide/client/html-resource',
},
{ text: 'Usage & Examples', link: '/guide/client/usage-examples' },
// { text: 'API', link: '/guide/client/api' } // Placeholder
],
},
],
},
{
text: 'Client SDK (@mcp-ui/client)',
items: [
{ text: 'Overview', link: '/guide/client/overview' },
},
ru: {
label: 'Русский',
lang: 'ru-RU',
link: '/ru/guide/introduction', // Link for the language switcher
sidebar: {
'/ru/guide/': [
{
text: 'HtmlResource Component',
link: '/guide/client/html-resource',
text: 'Обзор', // Russian: Overview
items: [
{ text: 'Введение', link: '/ru/guide/introduction' }, // Russian: Introduction
{ text: 'Начало работы', link: '/ru/guide/getting-started' }, // Russian: Getting Started
// { text: 'Детали протокола', link: '/ru/guide/protocol-details' }, // Placeholder for future translation
],
},
{ text: 'Usage & Examples', link: '/guide/client/usage-examples' },
// { text: 'API', link: '/guide/client/api' } // Placeholder
// Add translated sections for Server and Client SDKs when available
// {
// text: 'Server SDK (@mcp-ui/server)',
// items: [
// { text: 'Обзор', link: '/ru/guide/server/overview' },
// { text: 'Использование и примеры', link: '/ru/guide/server/usage-examples' },
// ],
// },
// {
// text: 'Client SDK (@mcp-ui/client)',
// items: [
// { text: 'Обзор', link: '/ru/guide/client/overview' },
// { text: 'Компонент HtmlResource', link: '/ru/guide/client/html-resource' },
// { text: 'Использование и примеры', link: '/ru/guide/client/usage-examples' },
// ],
// },
],
},
],
}
},

socialLinks: [
Expand Down
59 changes: 12 additions & 47 deletions docs/src/guide/client/html-resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface HtmlResourceProps {
resource: Partial<Resource>;
onUiAction?: (result: UiActionResult) => Promise<any>;
style?: React.CSSProperties;
renderMode?: 'iframe' | 'secure';
}
```

Expand All @@ -25,6 +26,9 @@ export interface HtmlResourceProps {
```
If you don't provide a callback for a specific type, the default handler will be used.
- **`style`** (optional): Custom styles for the iframe.
- **`renderMode`** (optional): `'iframe'` (default) or `'secure'`. Secure mode
sanitizes the HTML and renders it directly without an iframe. Actions are
triggered by elements with `data-tool` and optional `data-params` attributes.

## How It Works

Expand Down Expand Up @@ -53,54 +57,15 @@ By default, the iframe stretches to 100% width and is at least 200px tall. You c

See [Client SDK Usage & Examples](./usage-examples.md).

## Recommended Usage Pattern
## Secure Renderer (Experimental)

Client-side hosts should check for the `ui://` URI scheme first to identify MCP-UI resources, rather than checking mimeType:

```tsx
function App({ mcpResource }) {
if (
mcpResource.type === 'resource' &&
mcpResource.resource.uri?.startsWith('ui://')
) {
return (
<HtmlResource
resource={mcpResource.resource}
onUiAction={(tool, params) => {
console.log('Action:', tool, params);
return { status: 'ok' };
}}
/>
);
}
return <p>Unsupported resource</p>;
}
```

This pattern allows the `HtmlResource` component to handle mimeType-based rendering internally, making your code more future-proof as new content types (like `application/javascript`) are added.

## Backwards Compatibility

The `HtmlResource` component maintains backwards compatibility with the legacy `ui-app://` URI scheme:

- **Legacy Support**: Resources with `ui-app://` URIs are automatically treated as URL content (equivalent to `mimeType: 'text/uri-list'`) even when they have the historically incorrect `mimeType: 'text/html'`
- **Automatic Detection**: The component detects legacy URIs and processes them correctly without requiring code changes
- **MimeType Override**: Ignores the incorrect `text/html` mimeType and treats content as URLs
- **Migration Encouragement**: A warning is logged when legacy URIs are detected, encouraging server updates
- **Seamless Transition**: Existing clients continue working with older servers during migration periods

### Legacy URI Handling

```tsx
// Both patterns work identically:
// Legacy (automatically detected and corrected):
<HtmlResource resource={{ uri: 'ui-app://widget/123', mimeType: 'text/html', text: 'https://example.com/widget' }} />
// Modern (recommended):
<HtmlResource resource={{ uri: 'ui://widget/123', mimeType: 'text/uri-list', text: 'https://example.com/widget' }} />
```
When `renderMode` is set to `"secure"`, the HTML is sanitized using
[`DOMPurify`](https://github.com/cure53/DOMPurify) and injected directly into the
page. No iframe is used. Interactive elements should emit actions by including a
`data-tool` attribute and an optional `data-params` JSON string.

## Security Notes

- **`sandbox` attribute**: Restricts what the iframe can do. `allow-scripts` is needed for interactivity. `allow-same-origin` is external apps. Caution - the external app method isn's not a secure way to render untrusted code. We're working on new methods to alleviate security concerns.
- **`postMessage` origin**: When sending messages from the iframe, always specify the target origin for safety. The component listens globally, so your iframe content should be explicit.
- **Content Sanitization**: HTML is rendered as-is. If you don't fully trust the source, sanitize the HTML before passing it in, or rely on the iframe's sandboxing.
- **`sandbox` attribute**: Restricts what the iframe can do. `allow-scripts` is needed for interactivity. `allow-same-origin` is only used for `ui-app://` URLs.
- **`postMessage` origin**: When sending messages from the iframe, always specify the target origin for safety.
- **Content Sanitization**: In `secure` mode the HTML is sanitized with DOMPurify before rendering. In `iframe` mode the HTML is rendered as-is and relies on the iframe's sandboxing.
2 changes: 1 addition & 1 deletion docs/src/guide/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This guide will walk you through setting up your development environment and usi
1. **Clone the Monorepo**:

```bash
git clone https://github.com/idosal/mcp-ui.git # TODO: Update this link
git clone https://github.com/idosal/mcp-ui.git
cd mcp-ui
```

Expand Down
Loading