@gradio/core 0.23.2 → 0.24.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.
- package/CHANGELOG.md +18 -0
- package/dist/src/api_docs/ApiBanner.svelte +1 -1
- package/dist/src/api_docs/ApiDocs.svelte +52 -270
- package/dist/src/api_docs/MCPSnippet.svelte +571 -0
- package/dist/src/api_docs/MCPSnippet.svelte.d.ts +47 -0
- package/package.json +32 -32
- package/src/api_docs/ApiBanner.svelte +1 -1
- package/src/api_docs/ApiDocs.svelte +58 -271
- package/src/api_docs/MCPSnippet.svelte +602 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @gradio/core
|
|
2
2
|
|
|
3
|
+
## 0.24.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- [#11651](https://github.com/gradio-app/gradio/pull/11651) [`5b0e212`](https://github.com/gradio-app/gradio/commit/5b0e212ec0d54b5d793985de94c216bc5a73f610) - Allow users choose the MCP tools from MCP docs pane. Thanks @abidlabs!
|
|
8
|
+
- [#11622](https://github.com/gradio-app/gradio/pull/11622) [`ae9aaee`](https://github.com/gradio-app/gradio/commit/ae9aaeea62974f1fb533946a2a7c8461572778ef) - Expose Streamable HTTP endpoint in MCP Server at `/mcp`. Thanks @abidlabs!
|
|
9
|
+
|
|
10
|
+
### Dependency updates
|
|
11
|
+
|
|
12
|
+
- @gradio/upload@0.16.12
|
|
13
|
+
- @gradio/video@0.14.22
|
|
14
|
+
- @gradio/code@0.14.12
|
|
15
|
+
- @gradio/client@1.15.7
|
|
16
|
+
- @gradio/gallery@0.15.28
|
|
17
|
+
- @gradio/image@0.22.14
|
|
18
|
+
- @gradio/button@0.5.8
|
|
19
|
+
- @gradio/file@0.12.25
|
|
20
|
+
|
|
3
21
|
## 0.23.2
|
|
4
22
|
|
|
5
23
|
### Fixes
|
|
@@ -13,6 +13,7 @@ import javascript from "./img/javascript.svg";
|
|
|
13
13
|
import bash from "./img/bash.svg";
|
|
14
14
|
import ResponseSnippet from "./ResponseSnippet.svelte";
|
|
15
15
|
import mcp from "./img/mcp.svg";
|
|
16
|
+
import MCPSnippet from "./MCPSnippet.svelte";
|
|
16
17
|
export let dependencies;
|
|
17
18
|
export let root;
|
|
18
19
|
export let app;
|
|
@@ -75,12 +76,35 @@ get_js_info().then((js_api_info) => {
|
|
|
75
76
|
js_info = js_api_info;
|
|
76
77
|
});
|
|
77
78
|
const dispatch = createEventDispatcher();
|
|
78
|
-
|
|
79
|
+
$:
|
|
80
|
+
selected_tools_array = Array.from(selected_tools);
|
|
81
|
+
$:
|
|
82
|
+
selected_tools_without_prefix = selected_tools_array.map(remove_tool_prefix);
|
|
83
|
+
$:
|
|
84
|
+
mcp_server_url = `${root}gradio_api/mcp/sse`;
|
|
85
|
+
$:
|
|
86
|
+
mcp_server_url_streamable = selected_tools_array.length > 0 && selected_tools_array.length < tools.length ? `${root}gradio_api/mcp/?tools=${selected_tools_without_prefix.join(",")}` : `${root}gradio_api/mcp/`;
|
|
87
|
+
$:
|
|
88
|
+
if (mcp_json_sse && selected_tools.size > 0) {
|
|
89
|
+
const baseUrl = selected_tools_array.length > 0 && selected_tools_array.length < tools.length ? `${root}gradio_api/mcp/sse?tools=${selected_tools_without_prefix.join(",")}` : `${root}gradio_api/mcp/sse`;
|
|
90
|
+
mcp_json_sse.mcpServers.gradio.url = baseUrl;
|
|
91
|
+
if (mcp_json_stdio) {
|
|
92
|
+
mcp_json_stdio.mcpServers.gradio.args[1] = baseUrl;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
79
95
|
let tools = [];
|
|
80
96
|
let headers = [];
|
|
81
97
|
let mcp_json_sse;
|
|
82
98
|
let mcp_json_stdio;
|
|
83
99
|
let file_data_present = false;
|
|
100
|
+
let selected_tools = /* @__PURE__ */ new Set();
|
|
101
|
+
let tool_prefix = space_id ? space_id.split("/").pop() + "_" : "";
|
|
102
|
+
function remove_tool_prefix(toolName) {
|
|
103
|
+
if (tool_prefix && toolName.startsWith(tool_prefix)) {
|
|
104
|
+
return toolName.slice(tool_prefix.length);
|
|
105
|
+
}
|
|
106
|
+
return toolName;
|
|
107
|
+
}
|
|
84
108
|
const upload_file_mcp_server = {
|
|
85
109
|
command: "uvx",
|
|
86
110
|
args: [
|
|
@@ -92,9 +116,10 @@ const upload_file_mcp_server = {
|
|
|
92
116
|
"<UPLOAD_DIRECTORY>"
|
|
93
117
|
]
|
|
94
118
|
};
|
|
95
|
-
async function
|
|
119
|
+
async function fetch_mcp_tools() {
|
|
96
120
|
try {
|
|
97
|
-
|
|
121
|
+
let schema_url = `${root}gradio_api/mcp/schema`;
|
|
122
|
+
const response = await fetch(schema_url);
|
|
98
123
|
const schema = await response.json();
|
|
99
124
|
file_data_present = schema.map((tool) => tool.meta?.file_data_present).some((present) => present);
|
|
100
125
|
tools = schema.map((tool) => ({
|
|
@@ -103,16 +128,20 @@ async function fetchMcpTools() {
|
|
|
103
128
|
parameters: tool.inputSchema?.properties || {},
|
|
104
129
|
expanded: false
|
|
105
130
|
}));
|
|
131
|
+
selected_tools = new Set(tools.map((tool) => tool.name));
|
|
106
132
|
headers = schema.map((tool) => tool.meta?.headers || []).flat();
|
|
107
133
|
if (headers.length > 0) {
|
|
108
134
|
mcp_json_sse = {
|
|
109
135
|
mcpServers: {
|
|
110
136
|
gradio: {
|
|
111
137
|
url: mcp_server_url,
|
|
112
|
-
headers: headers.reduce(
|
|
113
|
-
accumulator
|
|
114
|
-
|
|
115
|
-
|
|
138
|
+
headers: headers.reduce(
|
|
139
|
+
(accumulator, current_key) => {
|
|
140
|
+
accumulator[current_key] = "<YOUR_HEADER_VALUE>";
|
|
141
|
+
return accumulator;
|
|
142
|
+
},
|
|
143
|
+
{}
|
|
144
|
+
)
|
|
116
145
|
}
|
|
117
146
|
}
|
|
118
147
|
};
|
|
@@ -171,7 +200,7 @@ onMount(() => {
|
|
|
171
200
|
fetch(mcp_server_url).then((response) => {
|
|
172
201
|
mcp_server_active = response.ok;
|
|
173
202
|
if (mcp_server_active) {
|
|
174
|
-
|
|
203
|
+
fetch_mcp_tools();
|
|
175
204
|
if (!is_valid_language(lang_param)) {
|
|
176
205
|
current_language = "mcp";
|
|
177
206
|
}
|
|
@@ -268,135 +297,18 @@ onMount(() => {
|
|
|
268
297
|
target="_blank">docs</a
|
|
269
298
|
>) if you don't already have it installed.
|
|
270
299
|
{:else if current_language == "mcp"}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
</Block>
|
|
284
|
-
<p> </p>
|
|
285
|
-
<strong>Available MCP Tools</strong>
|
|
286
|
-
<div class="mcp-tools">
|
|
287
|
-
{#each tools as tool}
|
|
288
|
-
<div class="tool-item">
|
|
289
|
-
<button
|
|
290
|
-
class="tool-header"
|
|
291
|
-
on:click={() => (tool.expanded = !tool.expanded)}
|
|
292
|
-
>
|
|
293
|
-
<span
|
|
294
|
-
><span class="tool-name">{tool.name}</span>
|
|
295
|
-
<span class="tool-description"
|
|
296
|
-
>{tool.description
|
|
297
|
-
? tool.description
|
|
298
|
-
: "⚠︎ No description provided in function docstring"}</span
|
|
299
|
-
></span
|
|
300
|
-
>
|
|
301
|
-
<span class="tool-arrow"
|
|
302
|
-
>{tool.expanded ? "▼" : "▶"}</span
|
|
303
|
-
>
|
|
304
|
-
</button>
|
|
305
|
-
{#if tool.expanded}
|
|
306
|
-
<div class="tool-content">
|
|
307
|
-
{#if Object.keys(tool.parameters).length > 0}
|
|
308
|
-
<div class="tool-parameters">
|
|
309
|
-
{#each Object.entries(tool.parameters) as [name, param]}
|
|
310
|
-
<div class="parameter">
|
|
311
|
-
<code>{name}</code>
|
|
312
|
-
<span class="parameter-type">
|
|
313
|
-
({param.type}{param.default !== undefined
|
|
314
|
-
? `, default: ${JSON.stringify(param.default)}`
|
|
315
|
-
: ""})
|
|
316
|
-
</span>
|
|
317
|
-
<p class="parameter-description">
|
|
318
|
-
{param.description
|
|
319
|
-
? param.description
|
|
320
|
-
: "⚠︎ No description for this parameter in function docstring"}
|
|
321
|
-
</p>
|
|
322
|
-
</div>
|
|
323
|
-
{/each}
|
|
324
|
-
</div>
|
|
325
|
-
{:else}
|
|
326
|
-
<p>Takes no input parameters</p>
|
|
327
|
-
{/if}
|
|
328
|
-
</div>
|
|
329
|
-
{/if}
|
|
330
|
-
</div>
|
|
331
|
-
{/each}
|
|
332
|
-
</div>
|
|
333
|
-
<p> </p>
|
|
334
|
-
|
|
335
|
-
<strong>SSE Transport</strong>: To add this MCP to clients that
|
|
336
|
-
support SSE (e.g. Cursor, Windsurf, Cline), simply add the
|
|
337
|
-
following configuration to your MCP config.
|
|
338
|
-
<p> </p>
|
|
339
|
-
<Block>
|
|
340
|
-
<code>
|
|
341
|
-
<div class="copy">
|
|
342
|
-
<CopyButton
|
|
343
|
-
code={JSON.stringify(mcp_json_sse, null, 2)}
|
|
344
|
-
/>
|
|
345
|
-
</div>
|
|
346
|
-
<div>
|
|
347
|
-
<pre>{JSON.stringify(mcp_json_sse, null, 2)}</pre>
|
|
348
|
-
</div>
|
|
349
|
-
</code>
|
|
350
|
-
</Block>
|
|
351
|
-
{#if file_data_present}
|
|
352
|
-
<p> </p>
|
|
353
|
-
<em>Note about files</em>: Gradio MCP servers that have files
|
|
354
|
-
as inputs need the files as URLs, so the
|
|
355
|
-
<code>upload_files_to_gradio</code>
|
|
356
|
-
tool is included for your convenience. This tool can upload files
|
|
357
|
-
located in the specified <code>UPLOAD_DIRECTORY</code>
|
|
358
|
-
argument (an absolute path in your local machine) or any of its
|
|
359
|
-
subdirectories to the Gradio app. You can omit this tool if you
|
|
360
|
-
are fine manually uploading files yourself and providing the URLs.
|
|
361
|
-
Before using this tool, you must have
|
|
362
|
-
<a
|
|
363
|
-
href="https://docs.astral.sh/uv/getting-started/installation/"
|
|
364
|
-
target="_blank">uv installed</a
|
|
365
|
-
>.
|
|
366
|
-
<p> </p>
|
|
367
|
-
{/if}
|
|
368
|
-
|
|
369
|
-
<strong>STDIO Transport</strong>: For clients that only support
|
|
370
|
-
stdio (e.g. Claude Desktop), first
|
|
371
|
-
<a href="https://nodejs.org/en/download/" target="_blank"
|
|
372
|
-
>install Node.js</a
|
|
373
|
-
>. Then, you can use the following command:
|
|
374
|
-
<p> </p>
|
|
375
|
-
<Block>
|
|
376
|
-
<code>
|
|
377
|
-
<div class="copy">
|
|
378
|
-
<CopyButton
|
|
379
|
-
code={JSON.stringify(mcp_json_stdio, null, 2)}
|
|
380
|
-
/>
|
|
381
|
-
</div>
|
|
382
|
-
<div>
|
|
383
|
-
<pre>{JSON.stringify(mcp_json_stdio, null, 2)}</pre>
|
|
384
|
-
</div>
|
|
385
|
-
</code>
|
|
386
|
-
</Block>
|
|
387
|
-
<p> </p>
|
|
388
|
-
<p>
|
|
389
|
-
<a href={mcp_docs} target="_blank">
|
|
390
|
-
Read more about MCP in the Gradio docs
|
|
391
|
-
</a>
|
|
392
|
-
</p>
|
|
393
|
-
{:else}
|
|
394
|
-
This Gradio app can also serve as an MCP server, with an MCP
|
|
395
|
-
tool corresponding to each API endpoint. To enable this, launch
|
|
396
|
-
this Gradio app with <code>.launch(mcp_server=True)</code> or
|
|
397
|
-
set the <code>GRADIO_MCP_SERVER</code> env variable to
|
|
398
|
-
<code>"True"</code>.
|
|
399
|
-
{/if}
|
|
300
|
+
<MCPSnippet
|
|
301
|
+
{mcp_server_active}
|
|
302
|
+
{mcp_server_url}
|
|
303
|
+
{mcp_server_url_streamable}
|
|
304
|
+
tools={tools.filter((tool) => selected_tools.has(tool.name))}
|
|
305
|
+
all_tools={tools}
|
|
306
|
+
bind:selected_tools
|
|
307
|
+
{mcp_json_sse}
|
|
308
|
+
{mcp_json_stdio}
|
|
309
|
+
{file_data_present}
|
|
310
|
+
{mcp_docs}
|
|
311
|
+
/>
|
|
400
312
|
{:else}
|
|
401
313
|
1. Confirm that you have cURL installed on your system.
|
|
402
314
|
{/if}
|
|
@@ -570,6 +482,7 @@ onMount(() => {
|
|
|
570
482
|
color: var(--body-text-color);
|
|
571
483
|
line-height: 1;
|
|
572
484
|
user-select: none;
|
|
485
|
+
font-size: var(--text-lg);
|
|
573
486
|
}
|
|
574
487
|
|
|
575
488
|
.current-lang {
|
|
@@ -590,7 +503,8 @@ onMount(() => {
|
|
|
590
503
|
|
|
591
504
|
.snippet img {
|
|
592
505
|
margin-right: var(--size-1-5);
|
|
593
|
-
width: var(--size-
|
|
506
|
+
width: var(--size-4);
|
|
507
|
+
height: var(--size-4);
|
|
594
508
|
}
|
|
595
509
|
|
|
596
510
|
.header {
|
|
@@ -689,136 +603,4 @@ onMount(() => {
|
|
|
689
603
|
.api-name {
|
|
690
604
|
color: var(--color-accent);
|
|
691
605
|
}
|
|
692
|
-
|
|
693
|
-
.mcp-url {
|
|
694
|
-
padding: var(--size-2);
|
|
695
|
-
position: relative;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
.mcp-url label {
|
|
699
|
-
display: block;
|
|
700
|
-
margin-bottom: var(--size-2);
|
|
701
|
-
font-weight: 600;
|
|
702
|
-
color: var(--body-text-color);
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
.mcp-url .textbox {
|
|
706
|
-
display: flex;
|
|
707
|
-
align-items: center;
|
|
708
|
-
gap: var(--size-2);
|
|
709
|
-
border: 1px solid var(--border-color-primary);
|
|
710
|
-
border-radius: var(--radius-sm);
|
|
711
|
-
padding: var(--size-2);
|
|
712
|
-
background: var(--background-fill-primary);
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
.mcp-url input {
|
|
716
|
-
flex: 1;
|
|
717
|
-
border: none;
|
|
718
|
-
background: none;
|
|
719
|
-
color: var(--body-text-color);
|
|
720
|
-
font-family: var(--font-mono);
|
|
721
|
-
font-size: var(--text-md);
|
|
722
|
-
width: 100%;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
.mcp-url input:focus {
|
|
726
|
-
outline: none;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
.status-indicator {
|
|
730
|
-
display: inline-block;
|
|
731
|
-
margin-right: var(--size-1-5);
|
|
732
|
-
position: relative;
|
|
733
|
-
top: -1px;
|
|
734
|
-
font-size: 0.8em;
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
.status-indicator.active {
|
|
738
|
-
color: #4caf50;
|
|
739
|
-
animation: pulse 1s infinite;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
@keyframes pulse {
|
|
743
|
-
0% {
|
|
744
|
-
opacity: 1;
|
|
745
|
-
}
|
|
746
|
-
50% {
|
|
747
|
-
opacity: 0.6;
|
|
748
|
-
}
|
|
749
|
-
100% {
|
|
750
|
-
opacity: 1;
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
.mcp-tools {
|
|
755
|
-
margin-top: var(--size-4);
|
|
756
|
-
border: 1px solid var(--border-color-primary);
|
|
757
|
-
border-radius: var(--radius-md);
|
|
758
|
-
overflow: hidden;
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
.tool-item {
|
|
762
|
-
border-bottom: 1px solid var(--border-color-primary);
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
.tool-item:last-child {
|
|
766
|
-
border-bottom: none;
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
.tool-header {
|
|
770
|
-
width: 100%;
|
|
771
|
-
display: flex;
|
|
772
|
-
justify-content: space-between;
|
|
773
|
-
align-items: center;
|
|
774
|
-
padding: var(--size-3);
|
|
775
|
-
background: var(--background-fill-primary);
|
|
776
|
-
border: none;
|
|
777
|
-
cursor: pointer;
|
|
778
|
-
text-align: left;
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
.tool-header:hover {
|
|
782
|
-
background: var(--background-fill-secondary);
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
.tool-name {
|
|
786
|
-
font-family: var(--font-mono);
|
|
787
|
-
font-weight: 600;
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
.tool-arrow {
|
|
791
|
-
color: var(--body-text-color-subdued);
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
.tool-content {
|
|
795
|
-
padding: var(--size-3);
|
|
796
|
-
background: var(--background-fill-secondary);
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
.tool-description {
|
|
800
|
-
margin-bottom: var(--size-3);
|
|
801
|
-
color: var(--body-text-color);
|
|
802
|
-
}
|
|
803
|
-
.parameter {
|
|
804
|
-
margin-bottom: var(--size-2);
|
|
805
|
-
padding: var(--size-2);
|
|
806
|
-
background: var(--background-fill-primary);
|
|
807
|
-
border-radius: var(--radius-sm);
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
.parameter code {
|
|
811
|
-
font-weight: 600;
|
|
812
|
-
color: var(--color-accent);
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
.parameter-type {
|
|
816
|
-
color: var(--body-text-color-subdued);
|
|
817
|
-
margin-left: var(--size-1);
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
.parameter-description {
|
|
821
|
-
margin-top: var(--size-1);
|
|
822
|
-
color: var(--body-text-color);
|
|
823
|
-
}
|
|
824
606
|
</style>
|