npm.io
0.3.0 • Published 2d agoCLI

typegpu-runtime-inspector-mcp

Licence
MIT
Version
0.3.0
Deps
12
Size
241 kB
Vulns
0
Weekly
8

TypeGPU Runtime Inspector MCP

Local stdio MCP server for validating TypeGPU code in Chromium with WebGPU.

It loads TypeGPU inspection modules through Vite, creates a browser GPUDevice, and reports generated WGSL, shader compilation messages, WebGPU validation errors, bind group layout stats, console/page errors, and recorded GPU calls.

Quick Setup

Use npx from the client you want to configure:

npx typegpu-runtime-inspector-mcp@latest setup codex
npx typegpu-runtime-inspector-mcp@latest setup claude
npx typegpu-runtime-inspector-mcp@latest setup opencode

Configure every supported client found on PATH:

npx typegpu-runtime-inspector-mcp@latest setup all

The setup command registers a local MCP server named typegpu_inspector and pins it to the package version that performed setup, for example:

npx typegpu-runtime-inspector-mcp@0.2.1

Existing typegpu_inspector entries are left unchanged unless --upgrade or --force is provided.

Upgrade From v0.1

If you installed the first release with setup, your MCP client is pinned to that exact package version. Re-run setup with --upgrade to update an existing typegpu_inspector entry that already points at this npm package:

npx typegpu-runtime-inspector-mcp@latest setup codex --upgrade
npx typegpu-runtime-inspector-mcp@latest setup claude --upgrade
npx typegpu-runtime-inspector-mcp@latest setup opencode --upgrade

Or update every supported client found on PATH:

npx typegpu-runtime-inspector-mcp@latest setup all --upgrade

Then restart the MCP client so it launches the new server process. You can check the local environment with:

npx typegpu-runtime-inspector-mcp@latest doctor

--upgrade only replaces entries that already reference this npm package. If a client has a custom typegpu_inspector command, use --force to replace it intentionally.

Run a local environment check:

npx typegpu-runtime-inspector-mcp@latest doctor

Requirements:

  • Node.js 20 or newer
  • Local filesystem access to the inspected project
  • Playwright Chromium with WebGPU support

playwright-chromium is a runtime dependency of this package. If lifecycle scripts were skipped during install, enable them and reinstall, then run doctor again.

Manual Client Config

Codex (~/.codex/config.toml):

[mcp_servers.typegpu_inspector]
command = "npx"
args = ["typegpu-runtime-inspector-mcp@<version>"]

Codex CLI:

codex mcp add typegpu_inspector -- npx typegpu-runtime-inspector-mcp@<version>

Claude Code:

claude mcp add --transport stdio --scope user typegpu_inspector -- npx typegpu-runtime-inspector-mcp@<version>

OpenCode:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "typegpu_inspector": {
      "type": "local",
      "command": ["npx", "typegpu-runtime-inspector-mcp@<version>"],
      "enabled": true
    }
  }
}

MCP Tools

Default discovery exposes three agent-facing tools:

  • inspect_typegpu: run a browser/WebGPU inspection from a probe, inspection module, or exported symbols.
  • list_typegpu_exports: scan one module and suggest symbol targets for inspect_typegpu.
  • resolve_typegpu_context: explain inferred roots, dependency sources, warnings, and next actions without launching a browser.
inspect_typegpu

Preferred tool for agents. Accepted target variants:

  • probe: function body for quick inline probes.
  • module: path to an inspection module that exports inspect.
  • symbols: exported symbols from an existing module, usually after list_typegpu_exports.

The MCP infers project/package/workspace roots, local TypeGPU dependencies, and Vite config. Add project.root, project.dependencyAliases, target.virtualPath, or environment fields only when warnings or diagnostics ask for them.

In TypeGPU monorepos, package resolution can still fall back to the MCP package when the current package does not expose a node_modules/typegpu workspace link. Check dependencySummary.hasBundledTypegpuFallback and warnings. Retry with project.root anchored to the workspace root and a package-root alias through project.dependencyAliases instead of aliasing individual subpaths:

{
  "project": {
    "root": ".",
    "dependencyAliases": {
      "typegpu": "packages/typegpu/src"
    }
  }
}

That one alias covers typegpu, typegpu/data, typegpu/std, and typegpu/common. For inline probes that import project files, set target.virtualPath inside the inspected package so relative imports resolve from the same location as the source being tested.

Quick probe:

{
  "target": {
    "kind": "probe",
    "body": "const main = tgpu.computeFn({ workgroupSize: [1] })(() => { 'use gpu'; }); return { label: 'main', kind: 'compute-pipeline', value: main };"
  }
}

Existing exported symbols:

{
  "target": {
    "kind": "symbols",
    "modulePath": "src/shaders.ts",
    "targets": [{ "kind": "compute-pipeline", "compute": "mainCompute" }]
  }
}

Inspection modules export inspect by default:

export async function inspect({ root, device, tgpu, d, std, common }) {
  const main = tgpu.computeFn({ workgroupSize: [1] })(() => {
    'use gpu';
  });

  return {
    label: 'main',
    kind: 'compute-pipeline',
    value: main,
  };
}

Use target.kind: "module" for these files:

{
  "target": {
    "kind": "module",
    "path": "src/inspect-particle-step.ts"
  }
}

The context contains:

  • root: TypeGPU root backed by the inspector browser device.
  • device: recorded GPUDevice proxy.
  • tgpu, d, std, common: TypeGPU imports resolved for the inspected project.

Return a target or an array of targets:

{
  label?: string;
  kind?: 'compute-pipeline' | 'render-pipeline' | 'resolvable';
  value?: unknown;
  create?: () => unknown;
  unwrap?: boolean;
}

Plain returned values are treated as { value }. Compute pipeline targets may return a TypeGPU compute entrypoint; the inspector creates the pipeline. Use create when construction should happen during target attribution, especially for render pipelines and descriptor-heavy probes.

return {
  label: 'render',
  kind: 'render-pipeline',
  create: () =>
    root.createRenderPipeline({
      vertex: common.fullScreenTriangle,
      fragment,
      targets: { format: 'bgra8unorm' },
    }),
};

If kind is omitted on a create target, the inspector infers it from the created TypeGPU pipeline when possible.

list_typegpu_exports

Statically scans a module and returns:

  • exports: all exported symbols found.
  • likelyTypegpuExports: exports that look like TypeGPU symbols.
  • suggestedSymbolTargets: ready-to-copy inspect_typegpu.target.targets entries when possible.
{
  "modulePath": "src/shaders.ts"
}
resolve_typegpu_context

Returns sanitized resolvedContext, dependencySummary, warnings, and nextActions for a target path. Agent-facing outputs replace local absolute paths with labels such as <projectRoot>, <packageRoot>, <workspaceRoot>, and <mcpPackage>.

{
  "targetPath": "apps/demo/src/shaders.ts"
}

Agent Examples

Quick probe:

{
  "target": {
    "kind": "probe",
    "body": "const fragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f })(({ uv }) => { 'use gpu'; return d.vec4f(uv, 0, 1); }); return { label: 'render', kind: 'render-pipeline', create: () => root.createRenderPipeline({ vertex: common.fullScreenTriangle, fragment, targets: { format: 'bgra8unorm' } }) };"
  }
}

Inspection file:

{
  "project": { "root": "/path/to/project" },
  "target": {
    "kind": "module",
    "path": "src/inspect-particle-step.ts"
  }
}

Probe with relative imports:

{
  "project": { "root": "/path/to/project" },
  "target": {
    "kind": "probe",
    "virtualPath": "src/typegpu-mcp-probe.ts",
    "body": "const { helper } = await import('./helper'); return { label: 'helper', kind: 'resolvable', value: helper };"
  }
}

Browser Setup And Assets

Use these fields when the inspected module expects DOM nodes, globals, static assets, or non-standard import paths:

{
  "target": {
    "kind": "module",
    "path": "src/examples/image-processing/blur/index.ts"
  },
  "environment": {
    "documentHtml": "<canvas width=\"512\" height=\"512\"></canvas>",
    "browserSetup": "window.__TEST_MODE__ = true;",
    "staticAssetRoutes": [
      { "urlPrefix": "/TypeGPU", "directory": "public" },
      { "urlPrefix": "/", "directory": "public" }
    ]
  }
}

Fields:

  • documentHtml: assigned to document.body.innerHTML before import.
  • browserSetup: browser JavaScript executed before import with root, device, tgpu, d, std, and common parameters.
  • staticAssetRoutes: serves files from local directories through the inspector Vite server.
  • features: WebGPU features to request from the adapter.
  • strictNames: deterministic TypeGPU generated names. Defaults to true.
  • viteConfigPath: optional project Vite config. Low-level calls resolve it relative to cwd; agent-facing project hints resolve relative paths from the target package first, then project/workspace roots.

Output

inspect_typegpu mirrors the most useful result fields at the top level:

  • summary: compact target, pipeline, console, and compilation counts.
  • targets: per-target status, diagnostics, pipeline creation, and optional WGSL.
  • dependencySummary: core TypeGPU source routing and bundled fallback flags.
  • warnings: sanitized context/dependency warnings.
  • nextActions: concrete retry hints.
  • inspection: the formatted report kept for compatibility.

Agent-facing outputs sanitize local absolute paths into labels such as <projectRoot>, <packageRoot>, <workspaceRoot>, and <mcpPackage>.

Default output is compact. Controls:

  • verbosity: "summary" (default), "normal", or "full".
  • includeWgsl: include WGSL in targets and shader-module descriptors. Defaults to true only for "full".
  • includeCalls: include recorded GPU calls. Defaults to true only for "full".
  • maxWgslBytes: truncate each included WGSL string to this many UTF-8 bytes.
  • diagnosticsOnly: return diagnostics, target status, console messages, and page errors.

inspectBody, inlineCode, setupBody, and browserSetup are JavaScript or TypeScript source snippets. Pass actual newline characters in these fields when you need multiple lines; double-escaped text such as \\nconst x = 1 is parsed as literal source and will fail.

{
  "target": {
    "kind": "probe",
    "body": "return { label: 'main', kind: 'resolvable', value: helper };"
  },
  "output": {
    "verbosity": "normal",
    "includeWgsl": true,
    "maxWgslBytes": 4000
  }
}

Common diagnostic codes:

  • plain-object-not-inspectable
  • wrapper-required
  • slot-binding-required
  • pipeline-resource-shape
  • pipeline-validated-without-recorded-creation
  • raw-webgpu-pipeline-unsupported
  • typegpu-fragment-function-not-resolvable
  • module-import-failed
  • canvas-dom-setup-required
  • direct-symbol-inspection
  • typegpu-random-resolution-failed

Local Development

pnpm install
pnpm start

Checks:

pnpm typecheck
pnpm test
pnpm test:browser

Browser tests require Playwright Chromium with WebGPU support. If Chromium is missing, run:

pnpm exec playwright install chromium

Keywords