Add MCP client configuration examples to CONTRIBUTING.md (#508)

* docs: restore full MCP client JSON configs to CONTRIBUTING.md

Reinstate the copy-pasteable JSON configurations for running all examples
with MCP clients (npx-based and local development), which were removed
from README.md in 2af02ba. Placed in CONTRIBUTING.md as a better home
for contributor-facing setup instructions.

https://claude.ai/code/session_014pjt7bE4ckHns5QFPkdWQp

* Use start:stdio in local dev config, add missing scripts to 9 examples

Update the local development JSON config in CONTRIBUTING.md to use
`npm --silent run start:stdio` instead of manual bash commands.

Add `serve:stdio` and `start:stdio` scripts to the 9 examples that
were missing them (basic-server-*, sheet-music, transcript,
video-resource, debug) to match the pattern already in place for the
other 11 showcase examples.

https://claude.ai/code/session_014pjt7bE4ckHns5QFPkdWQp

* style: auto-fix prettier formatting

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Olivier Chafik 2026-03-06 13:16:42 +00:00 • committed by GitHub
commit 134c71c29c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 479 additions and 0 deletions

View file

@ -40,6 +40,465 @@ Or build and run examples:
npm run examples:start
```
### With MCP Clients
To use these examples with MCP clients that support the stdio transport (such as Claude Desktop or VS Code), add this MCP server configuration to your client's settings:
<details>
<summary>MCP client configuration for all examples (using stdio)</summary>
```json
{
"mcpServers": {
"basic-react": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-basic-react",
"--stdio"
]
},
"basic-vanillajs": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-basic-vanillajs",
"--stdio"
]
},
"basic-vue": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-basic-vue",
"--stdio"
]
},
"basic-svelte": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-basic-svelte",
"--stdio"
]
},
"basic-preact": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-basic-preact",
"--stdio"
]
},
"basic-solid": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-basic-solid",
"--stdio"
]
},
"budget-allocator": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-budget-allocator",
"--stdio"
]
},
"cohort-heatmap": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-cohort-heatmap",
"--stdio"
]
},
"customer-segmentation": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-customer-segmentation",
"--stdio"
]
},
"map": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-map",
"--stdio"
]
},
"pdf": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-pdf",
"--stdio"
]
},
"scenario-modeler": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-scenario-modeler",
"--stdio"
]
},
"shadertoy": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-shadertoy",
"--stdio"
]
},
"sheet-music": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-sheet-music",
"--stdio"
]
},
"system-monitor": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-system-monitor",
"--stdio"
]
},
"threejs": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-threejs",
"--stdio"
]
},
"transcript": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-transcript",
"--stdio"
]
},
"video-resource": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-video-resource",
"--stdio"
]
},
"wiki-explorer": {
"command": "npx",
"args": [
"-y",
"--silent",
"--registry=https://registry.npmjs.org/",
"@modelcontextprotocol/server-wiki-explorer",
"--stdio"
]
},
"qr": {
"command": "uv",
"args": [
"run",
"/path/to/ext-apps/examples/qr-server/server.py",
"--stdio"
]
},
"say": {
"command": "uv",
"args": [
"run",
"--default-index",
"https://pypi.org/simple",
"https://raw.githubusercontent.com/modelcontextprotocol/ext-apps/refs/heads/main/examples/say-server/server.py",
"--stdio"
]
}
}
}
```
</details>
> [!NOTE]
> The `qr` server requires cloning the repository first. See [qr-server README](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/qr-server) for details.
### Local Development
To test local modifications with MCP clients, first clone and install the repository:
```bash
git clone https://github.com/modelcontextprotocol/ext-apps.git
cd ext-apps
npm install
```
Then configure your MCP client to build and run the local server. Replace `~/code/ext-apps` with your actual clone path.
Most example servers have a `start:stdio` script that builds and launches in stdio mode. Use `npm --silent run start:stdio` for these:
<details>
<summary>MCP client configuration for local development (all examples)</summary>
```json
{
"mcpServers": {
"basic-react": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/basic-server-react",
"run",
"start:stdio"
]
},
"basic-vanillajs": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/basic-server-vanillajs",
"run",
"start:stdio"
]
},
"basic-vue": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/basic-server-vue",
"run",
"start:stdio"
]
},
"basic-svelte": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/basic-server-svelte",
"run",
"start:stdio"
]
},
"basic-preact": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/basic-server-preact",
"run",
"start:stdio"
]
},
"basic-solid": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/basic-server-solid",
"run",
"start:stdio"
]
},
"budget-allocator": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/budget-allocator-server",
"run",
"start:stdio"
]
},
"cohort-heatmap": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/cohort-heatmap-server",
"run",
"start:stdio"
]
},
"customer-segmentation": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/customer-segmentation-server",
"run",
"start:stdio"
]
},
"map": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/map-server",
"run",
"start:stdio"
]
},
"pdf": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/pdf-server",
"run",
"start:stdio"
]
},
"scenario-modeler": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/scenario-modeler-server",
"run",
"start:stdio"
]
},
"shadertoy": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/shadertoy-server",
"run",
"start:stdio"
]
},
"sheet-music": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/sheet-music-server",
"run",
"start:stdio"
]
},
"system-monitor": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/system-monitor-server",
"run",
"start:stdio"
]
},
"threejs": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/threejs-server",
"run",
"start:stdio"
]
},
"transcript": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/transcript-server",
"run",
"start:stdio"
]
},
"video-resource": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/video-resource-server",
"run",
"start:stdio"
]
},
"wiki-explorer": {
"command": "npm",
"args": [
"--silent",
"--prefix",
"~/code/ext-apps/examples/wiki-explorer-server",
"run",
"start:stdio"
]
},
"qr": {
"command": "bash",
"args": [
"-c",
"uv run ~/code/ext-apps/examples/qr-server/server.py --stdio"
]
},
"say": {
"command": "bash",
"args": [
"-c",
"uv run --index https://pypi.org/simple ~/code/ext-apps/examples/say-server/server.py --stdio"
]
}
}
}
```
</details>
This configuration rebuilds each server on launch, ensuring your local changes are picked up.
## Testing
### Unit Tests

View file

@ -17,7 +17,9 @@
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"",
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
"serve": "bun --watch main.ts",
"serve:stdio": "bun main.ts --stdio",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"start:stdio": "cross-env NODE_ENV=development npm run build 1>&2 && npm run serve:stdio",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"",
"prepublishOnly": "npm run build"
},

View file

@ -27,7 +27,9 @@
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"",
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
"serve": "bun --watch main.ts",
"serve:stdio": "bun main.ts --stdio",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"start:stdio": "cross-env NODE_ENV=development npm run build 1>&2 && npm run serve:stdio",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"",
"prepublishOnly": "npm run build"
},

View file

@ -17,7 +17,9 @@
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"",
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
"serve": "bun --watch main.ts",
"serve:stdio": "bun main.ts --stdio",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"start:stdio": "cross-env NODE_ENV=development npm run build 1>&2 && npm run serve:stdio",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"",
"prepublishOnly": "npm run build"
},

View file

@ -17,7 +17,9 @@
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"",
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
"serve": "bun --watch main.ts",
"serve:stdio": "bun main.ts --stdio",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"start:stdio": "cross-env NODE_ENV=development npm run build 1>&2 && npm run serve:stdio",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"",
"prepublishOnly": "npm run build"
},

View file

@ -17,7 +17,9 @@
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"",
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
"serve": "bun --watch main.ts",
"serve:stdio": "bun main.ts --stdio",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"start:stdio": "cross-env NODE_ENV=development npm run build 1>&2 && npm run serve:stdio",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"",
"prepublishOnly": "npm run build"
},

View file

@ -17,7 +17,9 @@
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"",
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
"serve": "bun --watch main.ts",
"serve:stdio": "bun main.ts --stdio",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"start:stdio": "cross-env NODE_ENV=development npm run build 1>&2 && npm run serve:stdio",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"",
"prepublishOnly": "npm run build"
},

View file

@ -27,7 +27,9 @@
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"",
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
"serve": "bun --watch main.ts",
"serve:stdio": "bun main.ts --stdio",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"start:stdio": "cross-env NODE_ENV=development npm run build 1>&2 && npm run serve:stdio",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"",
"prepublishOnly": "npm run build"
},

View file

@ -17,7 +17,9 @@
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"",
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
"serve": "bun --watch main.ts",
"serve:stdio": "bun main.ts --stdio",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"start:stdio": "cross-env NODE_ENV=development npm run build 1>&2 && npm run serve:stdio",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"",
"prepublishOnly": "npm run build"
},

View file

@ -17,7 +17,9 @@
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"",
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
"serve": "bun --watch main.ts",
"serve:stdio": "bun main.ts --stdio",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"start:stdio": "cross-env NODE_ENV=development npm run build 1>&2 && npm run serve:stdio",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"",
"prepublishOnly": "npm run build"
},

View file

@ -17,7 +17,9 @@
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"",
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
"serve": "bun --watch main.ts",
"serve:stdio": "bun main.ts --stdio",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"start:stdio": "cross-env NODE_ENV=development npm run build 1>&2 && npm run serve:stdio",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"",
"prepublishOnly": "npm run build"
},