Server-side D3 with ease
Tested on Nodejs v16 & up

Create a SVG
import { D3Node } from 'd3-node' // const D3Node = require('d3-node')
const d3n = new D3Node() // initializes D3 with container element
d3n.createSVG(10,20).append('g') // create SVG w/ 'g' tag and width/height
d3n.svgString() // output: <svg width="10" height="20" xmlns="http://www.w3.org/2000/svg"><g></g></svg>
Setting container & insertion point via selector
const options = { selector: '#chart', container: '
' }
const d3n = new D3Node(options) // initializes D3 with container element
const d3 = d3n.d3
d3.select(d3n.document.querySelector('#chart')).append('span') // insert span tag into #chart
d3n.html() // output: <html><head></head><body>
<span></span>
</body></html>
d3n.chartHTML() // output:
<span></span>
Inline SVG styles
const d3n = new D3Node({styles:'.test {fill:#000;}'})
d3n.createSVG().append('g')
d3n.svgString()
Output
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<style type="text/css"><![CDATA[ .test{fill:#000;} ]]></style>
</defs>
<g></g>
</svg>
Create a canvas (for generating a png)
const canvasModule = require('canvas'); // supports node-canvas v1 & v2.x
const d3n = new D3Node({ canvasModule }); // pass it node-canvas
const canvas = d3n.createCanvas(960, 500);
const context = canvas.getContext('2d');
// draw on your canvas, then output canvas to png
canvas.pngStream().pipe(fs.createWriteStream('output.png'));
$ npm test
$ claude mcp add d3-node \
-- python -m otcore.mcp_server <graph>