* 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>
16 KiB
Contributing to MCP Apps SDK
We welcome contributions to the MCP Apps SDK! This document outlines the process for contributing to the project.
Getting Started
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR-USERNAME/ext-apps.git - Install dependencies:
npm install - Build the project:
npm run build - Run tests:
npm test
Development Process
- Create a new branch for your changes
- Make your changes
- Run
npm run prettierto ensure code style compliance - Run
npm testto verify all tests pass - Submit a pull request
Pull Request Guidelines
- Follow the existing code style
- Include tests for new functionality
- Update documentation as needed
- Keep changes focused and atomic
- Provide a clear description of changes
Running Examples
Start the development environment with hot reloading:
npm run examples:dev
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:
MCP client configuration for all examples (using stdio)
{
"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"
]
}
}
}
Note
The
qrserver requires cloning the repository first. See qr-server README for details.
Local Development
To test local modifications with MCP clients, first clone and install the repository:
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:
MCP client configuration for local development (all examples)
{
"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"
]
}
}
}
This configuration rebuilds each server on launch, ensuring your local changes are picked up.
Testing
Unit Tests
Run unit tests with Bun:
npm test
E2E Tests
E2E tests use Playwright to verify all example servers work correctly with screenshot comparisons.
# Run all E2E tests
npm run test:e2e
# Run a specific server's tests
npm run test:e2e -- --grep "Budget Allocator"
# Run tests in interactive UI mode
npm run test:e2e:ui
Updating Golden Screenshots
When UI changes are intentional, update the golden screenshots:
# Update all screenshots
npm run test:e2e:update
# Update screenshots for a specific server
npm run test:e2e:update -- --grep "Three.js"
Note: Golden screenshots are platform-agnostic. Tests use canvas masking and tolerance thresholds to handle minor cross-platform rendering differences.
Updating Snapshots in CI
If E2E tests fail in CI due to screenshot mismatches, you can update snapshots directly from your PR:
- Comment
/update-snapshotson the PR - The workflow will update snapshots and push to your branch
- A comment will confirm when complete
Alternatively, use the workflow dispatch to manually trigger updates for any branch.
Code of Conduct
This project follows our Code of Conduct. Please review it before contributing.
Reporting Issues
- Use the GitHub issue tracker
- Search existing issues before creating a new one
- Provide clear reproduction steps
Security Issues
Please review our Security Policy for reporting security vulnerabilities.
For Maintainers
Repository Setup
This repository uses npm trusted publishing with OIDC - no secrets required.
Before publishing releases, ensure the following are configured:
-
Trusted publisher on npm: Configure the package to trust this GitHub repository
- Go to https://www.npmjs.com/package/@modelcontextprotocol/ext-apps/access
- Under "Trusted Publishers", click "Add trusted publisher"
- Select "GitHub Actions"
- Repository:
modelcontextprotocol/ext-apps - Workflow filename:
npm-publish.yml - Environment:
Release(optional, for additional protection)
-
Releaseenvironment (optional): Create a protected environment for additional safeguards- Go to Settings > Environments > New environment
- Name it
Release - Add required reviewers or other protection rules as needed
Publishing a Release
Releases are published automatically via GitHub Actions when a GitHub Release is created.
Steps to publish:
-
Update the version in
package.json:# For a regular release npm version patch # or minor, or major # For a beta release npm version prerelease --preid=beta -
Commit the version bump (if not done by
npm version):git add package.json git commit -m "Bump version to X.Y.Z" git push origin main -
Create a GitHub Release:
- Go to Releases
- Click "Draft a new release"
- Create a new tag matching the version (e.g.,
v0.1.0) - Set the target branch (usually
main) - Write release notes describing the changes
- Click "Publish release"
-
Monitor the workflow:
- The npm-publish workflow will trigger automatically
- It runs build and test jobs before publishing
- On success, the package is published to npm with provenance
npm Tags
The workflow automatically determines the npm dist-tag:
| Version Pattern | npm Tag | Install Command |
|---|---|---|
X.Y.Z (from main) |
latest |
npm install @modelcontextprotocol/ext-apps |
X.Y.Z-beta.N |
beta |
npm install @modelcontextprotocol/ext-apps@beta |
X.Y.Z (from release branch) |
release-X.Y |
npm install @modelcontextprotocol/ext-apps@release-X.Y |
Maintenance Releases
To release a patch for an older version:
- Create a release branch from the tag:
git checkout -b release-0.1 v0.1.0 - Cherry-pick or apply fixes
- Bump the patch version
- Create a GitHub Release targeting the release branch
- The package will be published with tag
release-0.1
Testing Pre-releases
Every commit and PR automatically publishes a preview package via pkg-pr-new. Check the PR comments or workflow logs for the install command.
License
By contributing, you agree that your contributions will be licensed under the MIT License.