@modelcontextprotocol/inspector 2.12.0 → 2.14.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.
Files changed (33) hide show
  1. package/README.md +4 -3
  2. package/clients/cli/build/index.js +17438 -23403
  3. package/clients/mcpdo/build/mcp-bin.js +2872 -3709
  4. package/clients/mcpdo/build/mcpdod.js +21 -31
  5. package/clients/mcpdo/build/server-Dv339Ejx.js +17118 -0
  6. package/clients/tui/build/index.js +22131 -26836
  7. package/clients/web/build/index.js +7025 -9086
  8. package/clients/web/dist/assets/fredoka-normal-hebrew-CjvktpUN.woff2 +0 -0
  9. package/clients/web/dist/assets/fredoka-normal-latin-DOQG_Jwn.woff2 +0 -0
  10. package/clients/web/dist/assets/fredoka-normal-latin-ext-tYNUQHO6.woff2 +0 -0
  11. package/clients/web/dist/assets/index-BCud2uMC.js +1594 -0
  12. package/clients/web/dist/assets/{index-dqp8Sd8W.css → index-Dval2a7I.css} +1 -1
  13. package/clients/web/dist/assets/{prism-light-DfUe_Xlh.js → prism-light-CoVRM9R2.js} +1 -1
  14. package/clients/web/dist/assets/roboto-mono-italic-cyrillic-C1E63de8.woff2 +0 -0
  15. package/clients/web/dist/assets/roboto-mono-italic-cyrillic-ext-DR9ovEqT.woff2 +0 -0
  16. package/clients/web/dist/assets/roboto-mono-italic-greek-Cs2u2nVh.woff2 +0 -0
  17. package/clients/web/dist/assets/roboto-mono-italic-latin-D_P-kX1t.woff2 +0 -0
  18. package/clients/web/dist/assets/roboto-mono-italic-latin-ext-CErTcBzw.woff2 +0 -0
  19. package/clients/web/dist/assets/roboto-mono-italic-vietnamese-D4UvzJMM.woff2 +0 -0
  20. package/clients/web/dist/assets/roboto-mono-normal-cyrillic-DfzWIUPd.woff2 +0 -0
  21. package/clients/web/dist/assets/roboto-mono-normal-cyrillic-ext-D8QBEkUe.woff2 +0 -0
  22. package/clients/web/dist/assets/roboto-mono-normal-greek-DlC4X1lQ.woff2 +0 -0
  23. package/clients/web/dist/assets/roboto-mono-normal-latin-BAKpfWyj.woff2 +0 -0
  24. package/clients/web/dist/assets/roboto-mono-normal-latin-ext-CSSVNFqV.woff2 +0 -0
  25. package/clients/web/dist/assets/roboto-mono-normal-vietnamese-DFkHeOHB.woff2 +0 -0
  26. package/clients/web/dist/fonts/Fredoka-OFL.txt +93 -0
  27. package/clients/web/dist/fonts/RobotoMono-OFL.txt +93 -0
  28. package/clients/web/dist/index.html +2 -5
  29. package/clients/web/static/sandbox_proxy.html +177 -6
  30. package/package.json +10 -9
  31. package/skills/mcpdo/SKILL.md +14 -0
  32. package/clients/mcpdo/build/chunk-LBQDT5VV.js +0 -22280
  33. package/clients/web/dist/assets/index-qtX15-Bz.js +0 -1587
@@ -1,4 +1,4 @@
1
- import{a as e,c as t,d as n,i as r,l as i,n as a,o,r as s,s as c,t as l,u}from"./index-qtX15-Bz.js";function d(e,n){if(e==null)return{};var r,i,a=t(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)r=o[i],n.indexOf(r)===-1&&{}.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}function f(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function p(e){if(Array.isArray(e))return f(e)}function m(e){if(typeof Symbol<`u`&&e[Symbol.iterator]!=null||e[`@@iterator`]!=null)return Array.from(e)}function h(e,t){if(e){if(typeof e==`string`)return f(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?f(e,t):void 0}}function g(){throw TypeError(`Invalid attempt to spread non-iterable instance.
1
+ import{a as e,c as t,d as n,i as r,l as i,n as a,o,r as s,s as c,t as l,u}from"./index-BCud2uMC.js";function d(e,n){if(e==null)return{};var r,i,a=t(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)r=o[i],n.indexOf(r)===-1&&{}.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}function f(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function p(e){if(Array.isArray(e))return f(e)}function m(e){if(typeof Symbol<`u`&&e[Symbol.iterator]!=null||e[`@@iterator`]!=null)return Array.from(e)}function h(e,t){if(e){if(typeof e==`string`)return f(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?f(e,t):void 0}}function g(){throw TypeError(`Invalid attempt to spread non-iterable instance.
2
2
  In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function _(e){return p(e)||m(e)||h(e)||g()}function v(e){"@babel/helpers - typeof";return v=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},v(e)}function y(e,t){if(v(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(v(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function b(e){var t=y(e,`string`);return v(t)==`symbol`?t:t+``}function x(e,t,n){return(t=b(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var S=n(u());function C(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function w(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?C(Object(n),!0).forEach(function(t){x(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):C(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function T(e){var t=e.length;if(t===0||t===1)return e;if(t===2)return[e[0],e[1],`${e[0]}.${e[1]}`,`${e[1]}.${e[0]}`];if(t===3)return[e[0],e[1],e[2],`${e[0]}.${e[1]}`,`${e[0]}.${e[2]}`,`${e[1]}.${e[0]}`,`${e[1]}.${e[2]}`,`${e[2]}.${e[0]}`,`${e[2]}.${e[1]}`,`${e[0]}.${e[1]}.${e[2]}`,`${e[0]}.${e[2]}.${e[1]}`,`${e[1]}.${e[0]}.${e[2]}`,`${e[1]}.${e[2]}.${e[0]}`,`${e[2]}.${e[0]}.${e[1]}`,`${e[2]}.${e[1]}.${e[0]}`];if(t>=4)return[e[0],e[1],e[2],e[3],`${e[0]}.${e[1]}`,`${e[0]}.${e[2]}`,`${e[0]}.${e[3]}`,`${e[1]}.${e[0]}`,`${e[1]}.${e[2]}`,`${e[1]}.${e[3]}`,`${e[2]}.${e[0]}`,`${e[2]}.${e[1]}`,`${e[2]}.${e[3]}`,`${e[3]}.${e[0]}`,`${e[3]}.${e[1]}`,`${e[3]}.${e[2]}`,`${e[0]}.${e[1]}.${e[2]}`,`${e[0]}.${e[1]}.${e[3]}`,`${e[0]}.${e[2]}.${e[1]}`,`${e[0]}.${e[2]}.${e[3]}`,`${e[0]}.${e[3]}.${e[1]}`,`${e[0]}.${e[3]}.${e[2]}`,`${e[1]}.${e[0]}.${e[2]}`,`${e[1]}.${e[0]}.${e[3]}`,`${e[1]}.${e[2]}.${e[0]}`,`${e[1]}.${e[2]}.${e[3]}`,`${e[1]}.${e[3]}.${e[0]}`,`${e[1]}.${e[3]}.${e[2]}`,`${e[2]}.${e[0]}.${e[1]}`,`${e[2]}.${e[0]}.${e[3]}`,`${e[2]}.${e[1]}.${e[0]}`,`${e[2]}.${e[1]}.${e[3]}`,`${e[2]}.${e[3]}.${e[0]}`,`${e[2]}.${e[3]}.${e[1]}`,`${e[3]}.${e[0]}.${e[1]}`,`${e[3]}.${e[0]}.${e[2]}`,`${e[3]}.${e[1]}.${e[0]}`,`${e[3]}.${e[1]}.${e[2]}`,`${e[3]}.${e[2]}.${e[0]}`,`${e[3]}.${e[2]}.${e[1]}`,`${e[0]}.${e[1]}.${e[2]}.${e[3]}`,`${e[0]}.${e[1]}.${e[3]}.${e[2]}`,`${e[0]}.${e[2]}.${e[1]}.${e[3]}`,`${e[0]}.${e[2]}.${e[3]}.${e[1]}`,`${e[0]}.${e[3]}.${e[1]}.${e[2]}`,`${e[0]}.${e[3]}.${e[2]}.${e[1]}`,`${e[1]}.${e[0]}.${e[2]}.${e[3]}`,`${e[1]}.${e[0]}.${e[3]}.${e[2]}`,`${e[1]}.${e[2]}.${e[0]}.${e[3]}`,`${e[1]}.${e[2]}.${e[3]}.${e[0]}`,`${e[1]}.${e[3]}.${e[0]}.${e[2]}`,`${e[1]}.${e[3]}.${e[2]}.${e[0]}`,`${e[2]}.${e[0]}.${e[1]}.${e[3]}`,`${e[2]}.${e[0]}.${e[3]}.${e[1]}`,`${e[2]}.${e[1]}.${e[0]}.${e[3]}`,`${e[2]}.${e[1]}.${e[3]}.${e[0]}`,`${e[2]}.${e[3]}.${e[0]}.${e[1]}`,`${e[2]}.${e[3]}.${e[1]}.${e[0]}`,`${e[3]}.${e[0]}.${e[1]}.${e[2]}`,`${e[3]}.${e[0]}.${e[2]}.${e[1]}`,`${e[3]}.${e[1]}.${e[0]}.${e[2]}`,`${e[3]}.${e[1]}.${e[2]}.${e[0]}`,`${e[3]}.${e[2]}.${e[0]}.${e[1]}`,`${e[3]}.${e[2]}.${e[1]}.${e[0]}`]}var E={};function D(e){if(e.length===0||e.length===1)return e;var t=e.join(`.`);return E[t]||(E[t]=T(e)),E[t]}function O(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return D(e.filter(function(e){return e!==`token`})).reduce(function(e,t){return w(w({},e),n[t])},t)}function k(e){return e.join(` `)}function A(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return j({node:r,stylesheet:e,useInlineStyles:t,key:`code-segment-${n}-${i}`})})}}function j(e){var t=e.node,n=e.stylesheet,r=e.style,a=r===void 0?{}:r,o=e.useInlineStyles,s=e.key,c=t.properties,l=t.type,u=t.tagName,d=t.value;if(l===`text`)return d;if(u){var f=A(n,o),p;if(!o)p=w(w({},c),{},{className:k(c.className)});else{var m=Object.keys(n).reduce(function(e,t){return t.split(`.`).forEach(function(t){e.includes(t)||e.push(t)}),e},[]),h=c.className&&c.className.includes(`token`)?[`token`]:[],g=c.className&&h.concat(c.className.filter(function(e){return!m.includes(e)}));p=w(w({},c),{},{className:k(g)||void 0,style:O(c.className,Object.assign({},c.style,a),n)})}var _=f(t.children);return S.createElement(u,i({key:s},p),_)}}var M=(function(e,t){return e.listLanguages().indexOf(t)!==-1}),ee=[`language`,`children`,`style`,`customStyle`,`codeTagProps`,`useInlineStyles`,`showLineNumbers`,`showInlineLineNumbers`,`startingLineNumber`,`lineNumberContainerStyle`,`lineNumberStyle`,`wrapLines`,`wrapLongLines`,`lineProps`,`renderer`,`PreTag`,`CodeTag`,`code`,`astGenerator`];function N(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function P(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?N(Object(n),!0).forEach(function(t){x(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):N(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}var F=/\n/g;function I(e){return e.match(F)}function L(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return S.createElement(`span`,{key:`line-${t}`,className:`react-syntax-highlighter-line-number`,style:typeof r==`function`?r(i):r},`${i}
3
3
  `)})}function te(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=r===void 0?{float:`left`,paddingRight:`10px`}:r,a=e.numberStyle,o=a===void 0?{}:a,s=e.startingLineNumber;return S.createElement(`code`,{style:Object.assign({},n,i)},L({lines:t.replace(/\n$/,``).split(`
4
4
  `),style:o,startingLineNumber:s}))}function R(e){return`${e.toString().length}.25em`}function z(e,t){return{type:`element`,tagName:`span`,properties:{key:`line-number--${e}`,className:[`comment`,`linenumber`,`react-syntax-highlighter-line-number`],style:t},children:[{type:`text`,value:e}]}}function B(e,t,n){var r={display:`inline-block`,minWidth:R(n),paddingRight:`1em`,textAlign:`right`,userSelect:`none`},i=typeof e==`function`?e(t):e;return P(P({},r),i)}function V(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=o===void 0?{}:o,c=e.className,l=c===void 0?[]:c,u=e.showLineNumbers,d=e.wrapLongLines,f=e.wrapLines,p=f!==void 0&&f?P({},typeof s==`function`?s(n):s):{};if(p.className=p.className?[].concat(_(p.className.trim().split(/\s+/)),_(l)):l,n&&a){var m=B(r,n,i);t.unshift(z(n,m))}return d&u&&(p.style=P({display:`flex`},p.style)),{type:`element`,tagName:`span`,properties:p,children:t}}function H(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[],n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:[];e.length===void 0&&(e=[e]);for(var r=0;r<e.length;r++){var i=e[r];if(i.type===`text`)n.push(V({children:[i],className:_(new Set(t))}));else if(i.children){var a=t.concat(i.properties?.className||[]);H(i.children,a).forEach(function(e){return n.push(e)})}}return n}function ne(e,t,n,r,i,a,o,s,c){var l,u=H(e.value),d=[],f=-1,p=0;function m(e,a){return V({children:e,lineNumber:a,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:arguments.length>2&&arguments[2]!==void 0?arguments[2]:[],showLineNumbers:r,wrapLongLines:c,wrapLines:t})}function h(e,t){if(r&&t&&i){var n=B(s,t,o);e.unshift(z(t,n))}return e}function g(e,n){var r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:[];return t||r.length>0?m(e,n,r):h(e,n)}for(var _=function(){var e=u[p],t=e.children[0].value;if(I(t)){var n=t.split(`
@@ -0,0 +1,93 @@
1
+ Copyright 2016 The Fredoka Project Authors (https://github.com/hafontia/Fredoka-One)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,93 @@
1
+ Copyright 2015 The Roboto Mono Project Authors (https://github.com/googlefonts/robotomono)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ https://openfontlicense.org
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -4,12 +4,9 @@
4
4
  <meta charset="UTF-8" />
5
5
  <link rel="icon" type="image/svg+xml" href="/assets/MCP-CWGQJYyH.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <link rel="preconnect" href="https://fonts.googleapis.com" />
8
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
- <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@300..700&family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap" rel="stylesheet" />
10
7
  <title>MCP Inspector</title>
11
- <script type="module" crossorigin src="/assets/index-qtX15-Bz.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-dqp8Sd8W.css">
8
+ <script type="module" crossorigin src="/assets/index-BCud2uMC.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-Dval2a7I.css">
13
10
  </head>
14
11
  <body>
15
12
  <div id="root"></div>
@@ -33,7 +33,31 @@
33
33
  src/utils/sandbox-csp.ts). The proxy assigns that pre-wrapped document
34
34
  to `srcdoc` verbatim — it never parses or injects into the untrusted
35
35
  bytes — so the CSP `<meta>` is guaranteed to be the first `<head>`
36
- child of the inner document. -->
36
+ child of the inner document.
37
+
38
+ Self-navigation: a sandboxed frame may always navigate ITSELF —
39
+ `allow-top-navigation` governs other frames, not its own — and the
40
+ sandbox flags follow it, so a page the app navigates to is still
41
+ opaque ("null") and still `inner.contentWindow`. Nothing in the app's
42
+ own CSP can stop that (CSP has no shipped navigation directive), so
43
+ two controls here do instead:
44
+ 1. A `frame-src` / `child-src` policy on THIS document, installed
45
+ per render before the inner frame is loaded (see
46
+ `installFramePolicy`). A parent's `frame-src` governs every
47
+ navigation of its child frame, including one the child starts,
48
+ so the inner frame can load only the srcdoc (not a fetch, so not
49
+ subject to it), the dedicated app origin, or the app's approved
50
+ `frameDomains`. It is a <meta> rather than a header because the
51
+ sources are only known once the resource-ready message arrives.
52
+ 2. Navigation detection (see `closeNavigatedFrame` and its
53
+ callers): a navigation 1. refuses raises a policy violation on
54
+ this document, and on the srcdoc path the frame leaving its
55
+ document anyway (a navigation 1. allowed, such as to a declared
56
+ frame domain) is reported by the host wrapper's departure
57
+ script, and also shows as a second `load`. Any of them closes
58
+ the relay, removes the frame and tells the host. This half is
59
+ defense in depth, not the boundary: a navigated page's scripts
60
+ can run before either signal arrives. -->
37
61
  <title>MCP-UI Proxy</title>
38
62
  <style>
39
63
  html,
@@ -76,6 +100,38 @@
76
100
  return allowList.join("; ");
77
101
  }
78
102
 
103
+ // The approved `frameDomains` from the resource-ready message's `csp`
104
+ // (the host has already filtered them; see approveCspSources in
105
+ // src/utils/sandbox-csp.ts). Re-screened here because they become CSP
106
+ // source expressions on THIS document: anything carrying whitespace, a
107
+ // directive or list separator, or a quote (a keyword such as 'self',
108
+ // which would name this proxy's own origin) is dropped.
109
+ function approvedFrameSources(csp) {
110
+ const list = csp && Array.isArray(csp.frameDomains) ? csp.frameDomains : [];
111
+ return list.filter(
112
+ (s) => typeof s === "string" && s !== "" && !/[\s;,'"]/.test(s),
113
+ );
114
+ }
115
+
116
+ // Restrict what the inner frame may be navigated to, by installing a
117
+ // `frame-src` / `child-src` policy on this document (see the head
118
+ // comment for why a parent's policy is the control that works). Must run
119
+ // BEFORE the inner frame starts its navigation. Policies only ever
120
+ // intersect, so a second call can narrow but never widen what an
121
+ // earlier one allowed — a re-render in the same proxy document fails
122
+ // closed. `child-src` is set alongside so the restriction holds even in
123
+ // a browser that falls back to it for frames; the srcdoc document
124
+ // inherits this policy too, which is harmless because its own policy
125
+ // already limits frames to the same `frameDomains` and workers to
126
+ // 'none'.
127
+ function installFramePolicy(sources) {
128
+ const list = sources.length > 0 ? sources.join(" ") : "'none'";
129
+ const meta = document.createElement("meta");
130
+ meta.httpEquiv = "Content-Security-Policy";
131
+ meta.content = `frame-src ${list}; child-src ${list}`;
132
+ document.head.appendChild(meta);
133
+ }
134
+
79
135
  // The exact embedder origins this proxy accepts, injected by the sandbox
80
136
  // controller when it serves this page (see `embedderOriginsLiteral` in
81
137
  // server/sandbox-controller.ts). It is the same list the served
@@ -166,6 +222,95 @@
166
222
  // based on the permissions requested by the app
167
223
  document.body.appendChild(inner);
168
224
 
225
+ // Set once the inner frame is seen leaving the document the host loaded.
226
+ // From then on the relay is closed in both directions and every message
227
+ // is dropped: whatever the frame holds is no longer the app, even though
228
+ // it still satisfies `event.source === inner.contentWindow` and still
229
+ // serialises its origin as "null".
230
+ let navigatedAway = false;
231
+
232
+ // Fail closed on a frame that tried to leave its document: stop
233
+ // relaying, remove the frame (which destroys whatever document it
234
+ // holds), and tell the host through the app's own logging channel,
235
+ // which it already surfaces. Idempotent, because one attempt can be
236
+ // seen twice (a blocked navigation is both a policy violation and, in
237
+ // Chromium, a second `load` onto an error page).
238
+ function closeNavigatedFrame(what) {
239
+ if (navigatedAway) return;
240
+ navigatedAway = true;
241
+ inner.remove();
242
+ console.error(
243
+ `[Sandbox] the app ${what}; the frame was removed and the relay closed.`,
244
+ );
245
+ window.parent.postMessage(
246
+ {
247
+ jsonrpc: "2.0",
248
+ method: "notifications/message",
249
+ params: {
250
+ level: "error",
251
+ logger: "mcp-inspector-sandbox",
252
+ data: `The MCP App ${what}. The Inspector removed the frame and stopped relaying messages; reload the app to try again.`,
253
+ },
254
+ },
255
+ EXPECTED_HOST_ORIGIN,
256
+ );
257
+ }
258
+
259
+ // A navigation the frame policy (installFramePolicy) refuses is
260
+ // reported HERE, on the policy's own document. Engines differ in what
261
+ // follows: Chromium commits an error page (a second `load`), while
262
+ // Firefox leaves the original document in place and fires nothing
263
+ // further. The violation is the one signal both give, so it is what
264
+ // makes the attempt visible to the host everywhere. The app's own
265
+ // nested-frame violations are reported to the app's document, not
266
+ // this one, so they do not reach this listener.
267
+ document.addEventListener("securitypolicyviolation", (e) => {
268
+ if (
269
+ e.effectiveDirective === "frame-src" ||
270
+ e.effectiveDirective === "child-src"
271
+ ) {
272
+ closeNavigatedFrame(
273
+ "tried to navigate its frame to an origin it did not declare",
274
+ );
275
+ }
276
+ });
277
+
278
+ // Watch a srcdoc load for the frame navigating itself elsewhere. The
279
+ // srcdoc document fires at most one `load`, so any later one is a
280
+ // different document — another page (one the frame policy allowed,
281
+ // such as a declared frame domain), a blocked navigation's error page,
282
+ // or a reload. All of them close the frame. A navigation started while
283
+ // the srcdoc is still loading aborts it before its `load`, so the next
284
+ // document's `load` is the FIRST one; that case is caught by the
285
+ // departure message instead (see DEPARTURE_MESSAGE_KEY).
286
+ //
287
+ // The frame is detached while it is configured and re-attached after
288
+ // the listener is on, so the only `load` it can fire first is the
289
+ // srcdoc's: inserting a frame that already carries `srcdoc` skips the
290
+ // initial about:blank `load` that a bare frame would fire, which is what
291
+ // makes "the second load" unambiguous across engines.
292
+ function loadSrcdocWatchingForNavigation(html) {
293
+ inner.remove();
294
+ inner.srcdoc = html;
295
+ let loads = 0;
296
+ inner.addEventListener("load", function onLoad() {
297
+ loads += 1;
298
+ if (loads === 1) return;
299
+ inner.removeEventListener("load", onLoad);
300
+ closeNavigatedFrame(
301
+ "navigated its frame away from the document the host loaded",
302
+ );
303
+ });
304
+ document.body.appendChild(inner);
305
+ }
306
+
307
+ // The host wrapper (wrapSandboxedHtml in src/utils/sandbox-csp.ts)
308
+ // runs a script ahead of the app's code that posts
309
+ // `{ mcpInspectorSandbox: "departing" }` when the srcdoc document starts
310
+ // to leave (`beforeunload` / `pagehide`), whether or not it ever
311
+ // finished loading. It is consumed here and never relayed.
312
+ const DEPARTURE_MESSAGE_KEY = "mcpInspectorSandbox";
313
+
169
314
  const RESOURCE_READY_NOTIFICATION =
170
315
  "ui/notifications/sandbox-resource-ready";
171
316
  const PROXY_READY_NOTIFICATION = "ui/notifications/sandbox-proxy-ready";
@@ -190,6 +335,9 @@
190
335
  // never parses or injects into the untrusted bytes.
191
336
 
192
337
  window.addEventListener("message", async (event) => {
338
+ // Closed for good once the frame navigated away (see
339
+ // loadSrcdocWatchingForNavigation): nothing is relayed either way.
340
+ if (navigatedAway) return;
193
341
  if (event.source === window.parent) {
194
342
  // Validate that messages from parent come from the expected host origin.
195
343
  // This prevents malicious pages from sending messages to this sandbox.
@@ -204,7 +352,7 @@
204
352
  }
205
353
 
206
354
  if (event.data && event.data.method === RESOURCE_READY_NOTIFICATION) {
207
- const { html, sandbox, permissions, src } = event.data.params;
355
+ const { html, sandbox, permissions, src, csp } = event.data.params;
208
356
  // The host asked for the dedicated-origin path: it published the
209
357
  // wrapped document to its own app-origin listener and is handing
210
358
  // us the URL. Only an absolute http(s) URL is honored — anything
@@ -299,6 +447,10 @@
299
447
  // an app silently rendering the wrong bytes.
300
448
  inner.removeAttribute("srcdoc");
301
449
  innerOrigin = srcUrl.origin;
450
+ // The frame may hold only the app-origin document. That
451
+ // document's own nested frames are governed by its own header
452
+ // (it is not srcdoc, so it does not inherit this policy).
453
+ installFramePolicy([srcUrl.origin]);
302
454
  inner.src = srcUrl.href;
303
455
  } else if (typeof html === "string") {
304
456
  // The host has already wrapped the app's HTML in a fixed shell
@@ -323,16 +475,25 @@
323
475
  .filter((t) => t && t.toLowerCase() !== "allow-same-origin");
324
476
  inner.setAttribute("sandbox", fallbackTokens.join(" "));
325
477
  innerOrigin = "null";
326
- inner.srcdoc = html;
478
+ // The srcdoc load itself is not a fetch, so `frame-src` does not
479
+ // apply to it; what it does stop is the frame being navigated to
480
+ // anything but the app's approved `frameDomains` afterwards.
481
+ installFramePolicy(approvedFrameSources(csp));
482
+ loadSrcdocWatchingForNavigation(html);
327
483
  }
328
484
  } else {
329
485
  if (inner && inner.contentWindow) {
330
486
  // Target the inner frame's real origin on the dedicated-origin
331
487
  // path, so a frame that navigated itself elsewhere stops
332
488
  // receiving host messages. The opaque default has no targetable
333
- // origin ("null" is not a valid targetOrigin), so it keeps "*" —
334
- // safe there because the frame is `srcdoc` and cannot navigate
335
- // to another origin's document without allow-top-navigation.
489
+ // origin ("null" is not a valid targetOrigin), so it has to use
490
+ // "*" — which on its own would deliver to WHATEVER document the
491
+ // frame holds: a sandboxed frame can navigate itself to another
492
+ // origin without allow-top-navigation, and the new page keeps the
493
+ // opaque origin and the same contentWindow. What keeps "*" from
494
+ // reaching such a page is the frame policy (installFramePolicy),
495
+ // which blocks the navigation, and the navigation watch, which
496
+ // closes this relay if the frame leaves its document anyway.
336
497
  inner.contentWindow.postMessage(
337
498
  event.data,
338
499
  innerOrigin === "null" ? "*" : innerOrigin,
@@ -354,6 +515,16 @@
354
515
  );
355
516
  return;
356
517
  }
518
+ if (event.data && event.data[DEPARTURE_MESSAGE_KEY] === "departing") {
519
+ // Only the opaque srcdoc path watches for departure: a
520
+ // dedicated-origin app is targeted by its real origin instead.
521
+ if (innerOrigin === "null") {
522
+ closeNavigatedFrame(
523
+ "navigated its frame away from the document the host loaded",
524
+ );
525
+ }
526
+ return;
527
+ }
357
528
  // Relay messages from inner frame to parent window.
358
529
  // Use specific origin instead of "*" to prevent message interception.
359
530
  window.parent.postMessage(event.data, EXPECTED_HOST_ORIGIN);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelcontextprotocol/inspector",
3
- "version": "2.12.0",
3
+ "version": "2.14.0",
4
4
  "description": "The Model Context Protocol Inspector",
5
5
  "keywords": [
6
6
  "MCP",
@@ -111,6 +111,7 @@
111
111
  "smoke:web:browser": "node scripts/install-smoke-browser.mjs && node scripts/smoke-web-browser.mjs",
112
112
  "smoke:web:app": "node scripts/install-smoke-browser.mjs && node scripts/smoke-web-app.mjs",
113
113
  "smoke:web:elicit": "node scripts/install-smoke-browser.mjs && node scripts/smoke-web-elicitation.mjs",
114
+ "smoke:web:sandbox": "node scripts/install-smoke-browser.mjs && node scripts/smoke-web-sandbox-navigation.mjs",
114
115
  "smoke:web:tabs": "node scripts/install-smoke-browser.mjs chromium && node scripts/smoke-web-tabs.mjs chromium",
115
116
  "smoke:web:engine": "node scripts/run-engine-smokes.mjs",
116
117
  "smoke:web:chromium": "node scripts/run-engine-smokes.mjs chromium",
@@ -125,11 +126,11 @@
125
126
  },
126
127
  "dependencies": {
127
128
  "@hono/node-server": "^2.0.12",
128
- "@modelcontextprotocol/client": "2.3.1",
129
- "@modelcontextprotocol/core": "2.3.1",
129
+ "@modelcontextprotocol/client": "2.4.0",
130
+ "@modelcontextprotocol/core": "2.4.0",
130
131
  "@modelcontextprotocol/ext-apps": "^2.0.0",
131
132
  "@modelcontextprotocol/ext-tasks": "^0.2.2",
132
- "@modelcontextprotocol/server": "2.3.1",
133
+ "@modelcontextprotocol/server": "2.4.0",
133
134
  "@napi-rs/keyring": "^2.1.1",
134
135
  "@vitejs/plugin-react": "^6.0.0",
135
136
  "ajv": "^8.17.1",
@@ -142,23 +143,23 @@
142
143
  "pino": "^9.14.0",
143
144
  "proper-lockfile": "^4.1.2",
144
145
  "react": "^19.0.0",
145
- "undici": "^8.11.2",
146
+ "undici": "^8.12.3",
146
147
  "vite": "^8.1.5",
147
148
  "yaml": "^2.9.0",
148
149
  "zod": "^4.4.3"
149
150
  },
150
151
  "engines": {
151
- "node": ">=22.19.0"
152
+ "node": "^22.23.4 || ^24.22.1 || >=26.12.1"
152
153
  },
153
154
  "allowScripts": {
154
155
  "fsevents": false
155
156
  },
156
157
  "devDependencies": {
157
158
  "@eslint/js": "^10.0.1",
158
- "@modelcontextprotocol/server-legacy": "2.3.1",
159
+ "@modelcontextprotocol/server-legacy": "2.4.0",
159
160
  "@types/node": "^24.12.4",
160
161
  "@types/proper-lockfile": "^4.1.4",
161
- "@vitest/coverage-v8": "4.1.11",
162
+ "@vitest/coverage-v8": "4.1.12",
162
163
  "eslint": "^10.8.0",
163
164
  "eslint-plugin-react-hooks": "^7.1.1",
164
165
  "express": "^5.2.1",
@@ -167,6 +168,6 @@
167
168
  "semver": "^7.8.5",
168
169
  "typescript": "~5.9.3",
169
170
  "typescript-eslint": "^8.65.0",
170
- "vitest": "4.1.11"
171
+ "vitest": "4.1.12"
171
172
  }
172
173
  }
@@ -163,3 +163,17 @@ more).
163
163
  - Parked calls expire after 10 minutes; one parked call per connection. Pass
164
164
  `--elicit off` on `connect` to have well-behaved servers fall back to their
165
165
  own defaults instead of asking.
166
+
167
+ ## Load runs (`tools/call --load`)
168
+
169
+ - The summary's `latencyMs` and `okThroughput` cover **successful** calls
170
+ only; failures are timed in `errorLatencyMs`, and `isError` results' text
171
+ is tallied in `toolErrorMessages` (thrown ones in `errorMessages`). Judge a
172
+ run on these, not on `throughput`, which counts failures too.
173
+ - With `--load-rate`, compare `achievedRate` to `rate` and read
174
+ `droppedSlots`: slots nobody was free to take are dropped, so a server too
175
+ slow for the target can still report healthy latency. A shortfall under 90%
176
+ also prints a warning on stderr.
177
+ - `stoppedEarly` (`reason` + `detail`) means the run ended before its bounds:
178
+ `consecutive_errors` (the server stopped answering), `connection_lost`, or
179
+ `interrupted`. The counts cover only what completed.