@mcp-b/global 1.0.1 → 1.0.2
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/README +167 -0
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +2 -9
- package/dist/index.js.map +1 -1
- package/dist/index.umd +11 -0
- package/package.json +11 -5
package/README
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# @mcp-b/global
|
|
2
|
+
|
|
3
|
+
Global bundle for MCP-B (Model Context Protocol - Browser) that provides a polyfill exposing `window.mcp` for easy script tag or CDN usage in browser environments.
|
|
4
|
+
|
|
5
|
+
This package creates a global MCP server instance, allowing seamless integration of Model Context Protocol capabilities directly in the browser. It's designed for scenarios where you want a drop-in polyfill without module bundlers, while also supporting modern ESM/CJS imports.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Auto-initializes on script load in browsers.
|
|
10
|
+
- Exposes `window.mcp` as an instance of `McpServer` from `@modelcontextprotocol/sdk`.
|
|
11
|
+
- Registers a default tool: `get_current_website_title` to retrieve the document title.
|
|
12
|
+
- Supports cleanup for testing or dynamic reloading.
|
|
13
|
+
- Built with security in mind (e.g., configurable allowed origins for transport).
|
|
14
|
+
- Lightweight and treeshaken for browser efficiency.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
### Via NPM (for module-based projects)
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @mcp-b/global
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
or
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
yarn add @mcp-b/global
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
or
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add @mcp-b/global
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Via CDN (for script tag usage)
|
|
37
|
+
|
|
38
|
+
Use a CDN like unpkg or jsDelivr for direct browser inclusion:
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<script src="https://unpkg.com/@mcp-b/global@1.0.1/dist/index.umd.js"></script>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This will auto-initialize `window.mcp` upon loading.
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
### Script Tag (Polyfill Mode)
|
|
49
|
+
|
|
50
|
+
Simply include the script in your HTML. The library will auto-initialize and expose `window.mcp`.
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<!DOCTYPE html>
|
|
54
|
+
<html lang="en">
|
|
55
|
+
<head>
|
|
56
|
+
<meta charset="UTF-8" />
|
|
57
|
+
<title>MCP-B Global Example</title>
|
|
58
|
+
<script src="https://unpkg.com/@mcp-b/global@1.0.1/dist/index.umd.js"></script>
|
|
59
|
+
</head>
|
|
60
|
+
<body>
|
|
61
|
+
<script>
|
|
62
|
+
// Wait for DOMContentLoaded if needed, but auto-init handles it
|
|
63
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
64
|
+
console.log(window.mcp); // McpServer instance
|
|
65
|
+
// Use window.mcp.registerTool(...) or other methods
|
|
66
|
+
});
|
|
67
|
+
</script>
|
|
68
|
+
</body>
|
|
69
|
+
</html>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Module Import (ESM/CJS)
|
|
73
|
+
|
|
74
|
+
For modern JavaScript projects:
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
// ESM
|
|
78
|
+
import { initializeGlobalMCP } from "@mcp-b/global";
|
|
79
|
+
|
|
80
|
+
// or CJS
|
|
81
|
+
const { initializeGlobalMCP } = require("@mcp-b/global");
|
|
82
|
+
|
|
83
|
+
// Initialize manually
|
|
84
|
+
initializeGlobalMCP();
|
|
85
|
+
|
|
86
|
+
// Now window.mcp is available
|
|
87
|
+
console.log(window.mcp);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### Cleanup
|
|
91
|
+
|
|
92
|
+
If you need to reset the instance (e.g., in tests or hot module replacement):
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
import { cleanupGlobalMCP } from "@mcp-b/global";
|
|
96
|
+
|
|
97
|
+
cleanupGlobalMCP(); // Closes the server and removes window.mcp
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## API
|
|
101
|
+
|
|
102
|
+
### `initializeGlobalMCP(): void`
|
|
103
|
+
|
|
104
|
+
- Initializes the global MCP server if not already done.
|
|
105
|
+
- Safe to call multiple times (idempotent).
|
|
106
|
+
- Throws an error if initialization fails.
|
|
107
|
+
- In browser environments only; skips in non-browser contexts.
|
|
108
|
+
|
|
109
|
+
### `cleanupGlobalMCP(): void`
|
|
110
|
+
|
|
111
|
+
- Closes the MCP server connection.
|
|
112
|
+
- Removes `window.mcp`.
|
|
113
|
+
- Resets internal state for re-initialization.
|
|
114
|
+
|
|
115
|
+
### Global Exposure
|
|
116
|
+
|
|
117
|
+
After initialization:
|
|
118
|
+
|
|
119
|
+
- `window.mcp`: An instance of `McpServer` with:
|
|
120
|
+
- Server info: `{ name: hostname, version: '1.0.0' }`
|
|
121
|
+
- Capabilities: Supports tool list changes and debounced notifications.
|
|
122
|
+
- Default tool: `get_current_website_title` – Returns the current document title as `{ content: [{ type: 'text', text: title }] }`.
|
|
123
|
+
|
|
124
|
+
You can extend it by calling `window.mcp.registerTool(...)` or other MCP SDK methods.
|
|
125
|
+
|
|
126
|
+
## Configuration and Best Practices
|
|
127
|
+
|
|
128
|
+
- **Security**: The transport uses `allowedOrigins: ['*']` by default for broad compatibility. In production, restrict this to trusted origins (e.g., your domain) to prevent cross-origin issues. Modify the source or fork if needed.
|
|
129
|
+
- **Error Handling**: Tools and initialization include try-catch blocks for robustness.
|
|
130
|
+
- **Browser Compatibility**: Targets ES2018; works in modern browsers (Chrome 61+, Firefox 55+, Safari 11+, Edge 16+).
|
|
131
|
+
- **TypeScript**: Includes full type declarations for `window.mcp`.
|
|
132
|
+
|
|
133
|
+
## Dependencies
|
|
134
|
+
|
|
135
|
+
- `@mcp-b/transports`: For browser transport handling.
|
|
136
|
+
- `@modelcontextprotocol/sdk`: Core MCP SDK.
|
|
137
|
+
- `zod`: For schema validation (if used internally).
|
|
138
|
+
|
|
139
|
+
## Development
|
|
140
|
+
|
|
141
|
+
### Building
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pnpm install
|
|
145
|
+
pnpm build
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Scripts
|
|
149
|
+
|
|
150
|
+
- `build`: Builds the library using tsup (ESM, CJS, UMD formats).
|
|
151
|
+
- `typecheck`: Runs TypeScript checks.
|
|
152
|
+
- `lint` / `format` / `check`: Uses Biome for code quality.
|
|
153
|
+
- `clean`: Removes build artifacts.
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
158
|
+
|
|
159
|
+
## Contributing
|
|
160
|
+
|
|
161
|
+
Contributions welcome! Fork the repo, create a branch, and submit a PR. Report issues at [GitHub Issues](https://github.com/MiguelsPizza/WebMCP/issues).
|
|
162
|
+
|
|
163
|
+
## Links
|
|
164
|
+
|
|
165
|
+
- [Repository](https://github.com/MiguelsPizza/WebMCP/tree/main/packages/global)
|
|
166
|
+
- [NPM Package](https://www.npmjs.com/package/@mcp-b/global)
|
|
167
|
+
- [Homepage](https://github.com/MiguelsPizza/WebMCP#readme)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var transports=require('@mcp-b/transports'),mcp_js=require('@modelcontextprotocol/sdk/server/mcp.js');// @mcp-b/global - MIT License
|
|
2
|
+
var t=null,i=false;function c(){if(!t)try{let e=window.location.hostname||"localhost";t=new mcp_js.McpServer({name:e,version:"1.0.0"},{capabilities:{tools:{listChanged:!0},debouncedNotificationMethods:["notifications/tools/list_changed"]}}),t.registerTool("get_current_website_title",{description:"Get the title of the current website"},async()=>{try{return {content:[{type:"text",text:document.title||"Untitled"}]}}catch(n){return console.error("Error in get_current_website_title tool:",n),{content:[{type:"text",text:`Error getting website title ${n instanceof Error?n.message:String(n)}`}],isError:!0}}});let o=new transports.TabServerTransport({allowedOrigins:["*"]});t.connect(o);}catch(e){t=null;let o=e instanceof Error?e.message:"Unknown error";throw new Error(`Failed to initialize MCP server: ${o}`)}}function r(){if(typeof window=="undefined"){console.warn("initializeGlobalMCP called in non-browser environment; skipping.");return}if(!(i&&window.mcp&&t))try{c(),t&&(window.mcp=t,i=!0);}catch(e){throw console.error("Failed to initialize global MCP:",e),e}}function s(){if(t)try{t.close();}catch(e){console.warn("Error closing MCP server:",e);}finally{t=null;}typeof window!="undefined"&&"mcp"in window&&delete window.mcp,i=false;}if(typeof window!="undefined"&&typeof document!="undefined"){let e=()=>{try{r();}catch(o){console.error("Auto-initialization of global MCP failed:",o);}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e();}var p=r;exports.cleanupGlobalMCP=s;exports.default=p;exports.initializeGlobalMCP=r;//# sourceMappingURL=index.cjs.map
|
|
3
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/global.ts","../src/index.ts"],"names":["serverInstance","isInitialized","initializeMCP","hostname","McpServer","error","transport","TabServerTransport","errorMessage","initializeGlobalMCP","cleanupGlobalMCP","autoInitialize","index_default"],"mappings":"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","file":"index.cjs","sourcesContent":["// global.ts\n\nimport { TabServerTransport } from '@mcp-b/transports';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nlet serverInstance: McpServer | null = null;\nlet isInitialized = false;\n\n/**\n * Internal initialization function that creates and configures the MCP server.\n * This function is idempotent and handles errors gracefully.\n * @throws {Error} If initialization fails\n */\nfunction initializeMCP(): void {\n if (serverInstance) {\n return;\n }\n\n try {\n const hostname = window.location.hostname || 'localhost';\n\n serverInstance = new McpServer(\n {\n name: hostname,\n version: '1.0.0',\n },\n {\n capabilities: {\n tools: {\n listChanged: true,\n },\n debouncedNotificationMethods: [\n 'notifications/tools/list_changed',\n ],\n },\n }\n );\n\n // Register default tool with proper error handling in the callback\n serverInstance.registerTool(\n 'get_current_website_title',\n {\n description: 'Get the title of the current website',\n },\n async () => {\n try {\n const title = document.title || 'Untitled';\n return { content: [{ type: 'text', text: title }] };\n } catch (error) {\n console.error('Error in get_current_website_title tool:', error);\n return { content: [{ type: 'text', text: `Error getting website title ${error instanceof Error ? error.message : String(error)}` }], isError: true };\n }\n }\n );\n\n // Configure transport with restricted origins if possible; '*' is insecure, consider environment-specific origins\n // For best security practices, replace '*' with specific allowed origins in production\n const transport = new TabServerTransport({\n allowedOrigins: ['*'],\n });\n\n serverInstance.connect(transport);\n } catch (error) {\n serverInstance = null;\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to initialize MCP server: ${errorMessage}`);\n }\n}\n\n/**\n * Initializes the global MCP server and exposes it on window.mcp.\n * This function is safe to call multiple times - it will only initialize once.\n * It performs environment checks and handles browser-only execution.\n */\nexport function initializeGlobalMCP(): void {\n if (typeof window === 'undefined') {\n console.warn('initializeGlobalMCP called in non-browser environment; skipping.');\n return;\n }\n\n if (isInitialized && window.mcp && serverInstance) {\n return;\n }\n\n try {\n initializeMCP();\n if (serverInstance) {\n window.mcp = serverInstance;\n isInitialized = true;\n }\n } catch (error) {\n console.error('Failed to initialize global MCP:', error);\n throw error;\n }\n}\n\n/**\n * Cleanup function to properly dispose of the MCP server and remove global reference.\n * This is useful for testing, hot module replacement, or resetting the state.\n * It handles errors during cleanup gracefully.\n */\nexport function cleanupGlobalMCP(): void {\n if (serverInstance) {\n try {\n serverInstance.close();\n } catch (error) {\n console.warn('Error closing MCP server:', error);\n } finally {\n serverInstance = null;\n }\n }\n\n if (typeof window !== 'undefined' && 'mcp' in window) {\n delete (window as unknown as { mcp?: unknown }).mcp;\n }\n\n isInitialized = false;\n}","// index.ts\n\nimport { initializeGlobalMCP } from './global.js';\n\nexport * from './types.js';\nexport { initializeGlobalMCP, cleanupGlobalMCP } from './global.js';\n\n// Auto-initialize when script loads in browser environments\n// Using DOMContentLoaded for better timing instead of setTimeout(0), ensuring DOM is ready\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n const autoInitialize = () => {\n try {\n initializeGlobalMCP();\n } catch (error) {\n console.error('Auto-initialization of global MCP failed:', error);\n }\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', autoInitialize);\n } else {\n autoInitialize();\n }\n}\n\n// For manual initialization (when using as ES module)\nexport default initializeGlobalMCP;"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Initializes the global MCP server and exposes it on window.mcp.
|
|
5
|
+
* This function is safe to call multiple times - it will only initialize once.
|
|
6
|
+
* It performs environment checks and handles browser-only execution.
|
|
7
|
+
*/
|
|
8
|
+
declare function initializeGlobalMCP(): void;
|
|
9
|
+
/**
|
|
10
|
+
* Cleanup function to properly dispose of the MCP server and remove global reference.
|
|
11
|
+
* This is useful for testing, hot module replacement, or resetting the state.
|
|
12
|
+
* It handles errors during cleanup gracefully.
|
|
13
|
+
*/
|
|
14
|
+
declare function cleanupGlobalMCP(): void;
|
|
15
|
+
|
|
16
|
+
declare global {
|
|
17
|
+
interface Window {
|
|
18
|
+
mcp: McpServer;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { cleanupGlobalMCP, initializeGlobalMCP as default, initializeGlobalMCP };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Initializes the global MCP server and exposes it on window.mcp.
|
|
5
|
+
* This function is safe to call multiple times - it will only initialize once.
|
|
6
|
+
* It performs environment checks and handles browser-only execution.
|
|
7
|
+
*/
|
|
8
|
+
declare function initializeGlobalMCP(): void;
|
|
9
|
+
/**
|
|
10
|
+
* Cleanup function to properly dispose of the MCP server and remove global reference.
|
|
11
|
+
* This is useful for testing, hot module replacement, or resetting the state.
|
|
12
|
+
* It handles errors during cleanup gracefully.
|
|
13
|
+
*/
|
|
14
|
+
declare function cleanupGlobalMCP(): void;
|
|
15
|
+
|
|
16
|
+
declare global {
|
|
17
|
+
interface Window {
|
|
18
|
+
mcp: McpServer;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { cleanupGlobalMCP, initializeGlobalMCP as default, initializeGlobalMCP };
|