@runsnative/mcp-server 0.1.2 → 0.1.4

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.md CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  RunsNative MCP server — gives any MCP-capable agent access to RunsNative component docs, foundations, design exercises, and theme inference.
4
4
 
5
- Docs content is read from a local checkout of the [runsnative repo](https://github.com/KUKAMANGA-ENTERPRISES/runsnative) via `RUNSNATIVE_CONTENT_ROOT`. A cloud content API (no clone required, updates propagate without reinstalling) is in rollout; once live, the env var becomes optional and the server falls back to the cloud automatically.
5
+ Docs content comes from the RunsNative cloud content API by default no clone or configuration required, and content updates propagate without reinstalling. Developers working in the [runsnative repo](https://github.com/KUKAMANGA-ENTERPRISES/runsnative) can set `RUNSNATIVE_CONTENT_ROOT` to serve from a local checkout instead.
6
6
 
7
7
  ## Quick install
8
8
 
9
- Add one block to your MCP client config, pointing `RUNSNATIVE_CONTENT_ROOT` at the `content/` directory of a runsnative checkout.
9
+ Add one block to your MCP client config. No environment configuration is needed.
10
10
 
11
11
  ### Claude Desktop
12
12
 
@@ -18,10 +18,7 @@ Add one block to your MCP client config, pointing `RUNSNATIVE_CONTENT_ROOT` at t
18
18
  "mcpServers": {
19
19
  "runsnative": {
20
20
  "command": "npx",
21
- "args": ["-y", "@runsnative/mcp-server"],
22
- "env": {
23
- "RUNSNATIVE_CONTENT_ROOT": "/path/to/runsnative/content"
24
- }
21
+ "args": ["-y", "@runsnative/mcp-server"]
25
22
  }
26
23
  }
27
24
  }
@@ -36,15 +33,18 @@ Add `.mcp.json` to your project root:
36
33
  "mcpServers": {
37
34
  "runsnative": {
38
35
  "command": "npx",
39
- "args": ["-y", "@runsnative/mcp-server"],
40
- "env": {
41
- "RUNSNATIVE_CONTENT_ROOT": "/path/to/runsnative/content"
42
- }
36
+ "args": ["-y", "@runsnative/mcp-server"]
43
37
  }
44
38
  }
45
39
  }
46
40
  ```
47
41
 
42
+ To serve from a local checkout instead of the cloud API, add an `env` block:
43
+
44
+ ```json
45
+ "env": { "RUNSNATIVE_CONTENT_ROOT": "/path/to/runsnative/content" }
46
+ ```
47
+
48
48
  ## Authoring skill
49
49
 
50
50
  Once the MCP server is connected, load the RunsNative authoring skill to give your agent full component-authoring guidance. The skill is served at:
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ const provider = await createProvider();
21
21
  if (provider instanceof RemoteContentProvider) {
22
22
  await provider.initialize();
23
23
  }
24
- const server = new Server({ name: 'runsnative-mcp', version: '0.3.0' }, { capabilities: { tools: {} } });
24
+ const server = new Server({ name: 'runsnative-mcp', version: '0.1.4' }, { capabilities: { tools: {} } });
25
25
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
26
26
  tools: [
27
27
  GET_COMPONENT_TOOL,
@@ -1,4 +1,13 @@
1
- import sharp from 'sharp';
1
+ async function loadSharp() {
2
+ try {
3
+ // sharp is CJS: under ESM dynamic import the callable is mod.default.
4
+ const mod = (await import('sharp'));
5
+ return mod.default;
6
+ }
7
+ catch {
8
+ return null;
9
+ }
10
+ }
2
11
  const MAX_PIXELS = 10_000;
3
12
  const MAX_ITER = 20;
4
13
  function toHex(r, g, b) {
@@ -11,6 +20,10 @@ function sqDist(ar, ag, ab, br, bg, bb) {
11
20
  }
12
21
  export async function extractImageColors(buffer, sourceType, k = 5) {
13
22
  const extractedAt = new Date().toISOString();
23
+ const sharp = await loadSharp();
24
+ if (sharp === null) {
25
+ throw new Error('sharp is not installed — image color extraction requires it.');
26
+ }
14
27
  const { data, info } = await sharp(buffer)
15
28
  .flatten({ background: '#ffffff' })
16
29
  .removeAlpha()
@@ -1,4 +1,12 @@
1
- import { chromium } from 'playwright';
1
+ export async function loadChromium() {
2
+ try {
3
+ const playwright = await import('playwright');
4
+ return playwright.chromium;
5
+ }
6
+ catch {
7
+ return null;
8
+ }
9
+ }
2
10
  const VIEWPORT = { width: 1280, height: 800 };
3
11
  export async function fetchAndRender(url) {
4
12
  let parsed;
@@ -11,6 +19,17 @@ export async function fetchAndRender(url) {
11
19
  if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
12
20
  return { ok: false, error: { code: 'FETCH_ERROR', message: `Unsupported scheme: ${parsed.protocol}`, url } };
13
21
  }
22
+ const chromium = await loadChromium();
23
+ if (chromium === null) {
24
+ return {
25
+ ok: false,
26
+ error: {
27
+ code: 'FETCH_ERROR',
28
+ message: 'playwright is not installed — infer_brand_theme requires it. Install playwright, or use infer_theme for HTML-only analysis.',
29
+ url,
30
+ },
31
+ };
32
+ }
14
33
  const browser = await chromium.launch({ headless: true });
15
34
  try {
16
35
  const page = await browser.newPage();
@@ -1,8 +1,12 @@
1
- import { chromium } from 'playwright';
1
+ import { loadChromium } from './page-fetcher.js';
2
2
  const SAMPLE_SELECTORS = 'body,h1,h2,h3,h4,h5,h6,p,a,button,input,select,textarea,' +
3
3
  'div,span,header,footer,nav,main,section,article,aside,ul,ol,li';
4
4
  const MAX_ELEMENTS = 200;
5
5
  export async function extractStyles(snapshot) {
6
+ const chromium = await loadChromium();
7
+ if (chromium === null) {
8
+ throw new Error('playwright is not installed — style extraction requires it.');
9
+ }
6
10
  const browser = await chromium.launch({ headless: true });
7
11
  try {
8
12
  const page = await browser.newPage();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runsnative/mcp-server",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/"