Skip to content
Merged
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
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pnpm run build

This command runs `build-all.mts`, producing versioned `.html`, `.js`, and `.css` files inside `assets/`. Each widget is wrapped with the CSS it needs so you can host the bundles directly or ship them with your own server.

To iterate locally, you can also launch the Vite dev server:
To iterate on your components locally, you can also launch the Vite dev server:

```bash
pnpm run dev
Expand Down Expand Up @@ -130,12 +130,23 @@ You can add your app to the conversation context by selecting it in the "More" o

You can then invoke tools by asking something related. For example, for the Pizzaz app, you can ask "What are the best pizzas in town?".


## Next steps

- Customize the widget data: edit the handlers in `pizzaz_server_node/src`, `pizzaz_server_python/main.py`, or the solar system server to fetch data from your systems.
- Create your own components and add them to the gallery: drop new entries into `src/` and they will be picked up automatically by the build script.

### Deploy your MCP server

You can use the cloud environment of your choice to deploy your MCP server.

Include this in the environment variables:

```
BASE_URL=https://your-server.com
```

This will be used to generate the HTML for the widgets so that they can serve static assets from this hosted url.

## Contributing

You are welcome to open issues or submit PRs to improve this app, however, please note that we may not review all suggestions.
Expand Down
52 changes: 23 additions & 29 deletions build-all.mts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const targets: string[] = [
"pizzaz-carousel",
"pizzaz-list",
"pizzaz-albums",
"pizzaz-video",
];
const builtNames: string[] = [];

Expand Down Expand Up @@ -143,8 +142,6 @@ const outputs = fs
.map((f) => path.join("assets", f))
.filter((p) => fs.existsSync(p));

const renamed = [];

const h = crypto
.createHash("sha256")
.update(pkg.version, "utf8")
Expand All @@ -159,38 +156,35 @@ for (const out of outputs) {
const newName = path.join(dir, `${base}-${h}${ext}`);

fs.renameSync(out, newName);
renamed.push({ old: out, neu: newName });
console.log(`${out} -> ${newName}`);
}
console.groupEnd();

console.log("new hash: ", h);

const defaultBaseUrl = "http://localhost:4444";
const baseUrlCandidate = process.env.BASE_URL?.trim() ?? "";
const baseUrlRaw = baseUrlCandidate.length > 0 ? baseUrlCandidate : defaultBaseUrl;
const normalizedBaseUrl = baseUrlRaw.replace(/\/+$/, "") || defaultBaseUrl;
console.log(`Using BASE_URL ${normalizedBaseUrl} for generated HTML`);

for (const name of builtNames) {
const dir = outDir;
const htmlPath = path.join(dir, `${name}-${h}.html`);
const cssPath = path.join(dir, `${name}-${h}.css`);
const jsPath = path.join(dir, `${name}-${h}.js`);

const css = fs.existsSync(cssPath)
? fs.readFileSync(cssPath, { encoding: "utf8" })
: "";
const js = fs.existsSync(jsPath)
? fs.readFileSync(jsPath, { encoding: "utf8" })
: "";

const cssBlock = css ? `\n <style>\n${css}\n </style>\n` : "";
const jsBlock = js ? `\n <script type="module">\n${js}\n </script>` : "";

const html = [
"<!doctype html>",
"<html>",
`<head>${cssBlock}</head>`,
"<body>",
` <div id="${name}-root"></div>${jsBlock}`,
"</body>",
"</html>",
].join("\n");
fs.writeFileSync(htmlPath, html, { encoding: "utf8" });
console.log(`${htmlPath} (generated)`);
const hashedHtmlPath = path.join(dir, `${name}-${h}.html`);
const liveHtmlPath = path.join(dir, `${name}.html`);
const html = `<!doctype html>
<html>
<head>
<script type="module" src="${normalizedBaseUrl}/${name}.js"></script>
<link rel="stylesheet" href="${normalizedBaseUrl}/${name}.css">
</head>
<body>
<div id="${name}-root"></div>
</body>
</html>
`;
fs.writeFileSync(hashedHtmlPath, html, { encoding: "utf8" });
fs.writeFileSync(liveHtmlPath, html, { encoding: "utf8" });
console.log(`${hashedHtmlPath} (generated live HTML)`);
console.log(`${liveHtmlPath} (generated live HTML)`);
}
Loading