Skip to content
Draft
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
11 changes: 11 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "nitro-viewer",
"runtimeExecutable": "node",
"runtimeArgs": ["-e", "setTimeout(()=>{},999999999)"],
"port": 3742
}
]
}
9 changes: 9 additions & 0 deletions node-version/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ tasks:
- task: bundle
- npx @anthropic-ai/mcpb pack . ../build/nitro-pdf-services-node-{{.VERSION}}.mcpb

deploy-viewer:
desc: Copy viewer-app/index.html into the installed Claude Desktop extension (hot-reload without reinstalling mcpb)
vars:
EXT_DIR: "{{.HOME}}/Library/Application Support/Claude/Claude Extensions/local.mcpb.nitro-software-inc..nitro-mcp"
cmds:
- cp viewer-app/index.html "{{.EXT_DIR}}/viewer-app/index.html"
- cp viewer-app/index.html "{{.EXT_DIR}}/dist/viewer-app/index.html"
- echo "✓ viewer deployed"

clean:
desc: Clean build artifacts
cmds:
Expand Down
30 changes: 30 additions & 0 deletions node-version/build.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { build } from 'esbuild';
import { createRequire } from 'module';
import fs from 'node:fs';
import path from 'node:path';

const require = createRequire(import.meta.url);
const { version } = require('./manifest.json');
Expand All @@ -11,6 +13,34 @@ await build({
format: 'cjs',
outfile: 'dist/bundle.cjs',
define: {
// Replace import.meta.url (ESM-only) with a CJS equivalent so that
// fileURLToPath(import.meta.url) resolves correctly in the bundle.
// __filename is injected by esbuild for CJS output.
'import.meta.url': '__importMetaUrl',
'process.env.MCP_SERVER_VERSION': JSON.stringify(version),
},
banner: {
js: "const __importMetaUrl = require('url').pathToFileURL(__filename).href;",
},
});

// Copy legacy viewer-app/ into dist/viewer-app/ (used by the Express server fallback).
const srcDir = path.resolve('viewer-app');
const destDir = path.resolve('dist', 'viewer-app');
fs.mkdirSync(destDir, { recursive: true });
for (const file of fs.readdirSync(srcDir)) {
fs.copyFileSync(path.join(srcDir, file), path.join(destDir, file));
}
console.log(`Copied viewer-app/ → dist/viewer-app/`);

// Copy the built MCP App HTML (React inline viewer) into dist/mcp-viewer-app/
// so the ui:// resource handler can read it from a stable path in the bundle.
const mcpAppSrc = path.resolve('mcp-viewer-app', 'dist', 'mcp-app.html');
const mcpAppDestDir = path.resolve('dist', 'mcp-viewer-app');
fs.mkdirSync(mcpAppDestDir, { recursive: true });
if (fs.existsSync(mcpAppSrc)) {
fs.copyFileSync(mcpAppSrc, path.join(mcpAppDestDir, 'mcp-app.html'));
console.log(`Copied mcp-viewer-app/dist/mcp-app.html → dist/mcp-viewer-app/`);
} else {
console.warn(`⚠ mcp-viewer-app not built — run: cd mcp-viewer-app && npm run build`);
}
12 changes: 12 additions & 0 deletions node-version/mcp-viewer-app/mcp-app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Nitro PDF Viewer</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/mcp-app.tsx"></script>
</body>
</html>
Loading