Skip to content

Commit e106194

Browse files
authored
Merge branch 'main' into completion-support-default
2 parents 4e6c7f9 + 4ab7794 commit e106194

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+5383
-929
lines changed

.dockerignore

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Version control
2+
.git
3+
.gitignore
4+
5+
# Node.js
6+
node_modules
7+
npm-debug.log
8+
9+
# Build artifacts
10+
client/dist
11+
client/build
12+
server/dist
13+
server/build
14+
15+
# Environment variables
16+
.env
17+
.env.local
18+
.env.development
19+
.env.test
20+
.env.production
21+
22+
# Editor files
23+
.vscode
24+
.idea
25+
26+
# Logs
27+
logs
28+
*.log
29+
30+
# Testing
31+
coverage
32+
33+
# Docker
34+
Dockerfile
35+
.dockerignore

.git-blame-ignore-revs

Whitespace-only changes.

.github/workflows/e2e_tests.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: Playwright Tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
# Installing Playright dependencies can take quite awhile, and also depends on GitHub CI load.
12+
timeout-minutes: 15
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Install dependencies
17+
run: |
18+
sudo apt-get update
19+
sudo apt-get install -y libwoff1
20+
21+
- uses: actions/checkout@v4
22+
23+
- uses: actions/setup-node@v4
24+
id: setup_node
25+
with:
26+
node-version-file: package.json
27+
cache: npm
28+
29+
# Cache Playwright browsers
30+
- name: Cache Playwright browsers
31+
id: cache-playwright
32+
uses: actions/cache@v4
33+
with:
34+
path: ~/.cache/ms-playwright # The default Playwright cache path
35+
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }} # Cache key based on OS and package-lock.json
36+
restore-keys: |
37+
${{ runner.os }}-playwright-
38+
39+
- name: Install dependencies
40+
run: npm ci
41+
42+
- name: Install Playwright dependencies
43+
run: npx playwright install-deps
44+
45+
- name: Install Playwright and browsers unless cached
46+
run: npx playwright install --with-deps
47+
if: steps.cache-playwright.outputs.cache-hit != 'true'
48+
49+
- name: Run Playwright tests
50+
id: playwright-tests
51+
run: npm run test:e2e
52+
53+
- name: Upload Playwright Report and Screenshots
54+
uses: actions/upload-artifact@v4
55+
if: steps.playwright-tests.conclusion != 'skipped'
56+
with:
57+
name: playwright-report
58+
path: |
59+
client/playwright-report/
60+
client/test-results/
61+
client/results.json
62+
retention-days: 2
63+
64+
- name: Publish Playwright Test Summary
65+
uses: daun/playwright-report-summary@v3
66+
if: steps.playwright-tests.conclusion != 'skipped'
67+
with:
68+
create-comment: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
69+
report-file: client/results.json
70+
comment-title: "🎭 Playwright E2E Test Results"
71+
job-summary: true
72+
icon-style: "emojis"
73+
custom-info: |
74+
**Test Environment:** Ubuntu Latest, Node.js ${{ steps.setup_node.outputs.node-version }}
75+
**Browsers:** Chromium, Firefox
76+
77+
📊 [View Detailed HTML Report](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) (download artifacts)
78+
test-command: "npm run test:e2e"

.github/workflows/main.yml

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ jobs:
1919

2020
- uses: actions/setup-node@v4
2121
with:
22-
node-version: 18
22+
node-version-file: package.json
2323
cache: npm
2424

2525
# Working around https://github.com/npm/cli/issues/4828
2626
# - run: npm ci
2727
- run: npm install --no-package-lock
2828

29+
- name: Check version consistency
30+
run: npm run check-version
31+
2932
- name: Check linting
3033
working-directory: ./client
3134
run: npm run lint
@@ -50,7 +53,7 @@ jobs:
5053
- uses: actions/checkout@v4
5154
- uses: actions/setup-node@v4
5255
with:
53-
node-version: 18
56+
node-version-file: package.json
5457
cache: npm
5558
registry-url: "https://registry.npmjs.org"
5659

@@ -62,3 +65,52 @@ jobs:
6265
- run: npm run publish-all
6366
env:
6467
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
68+
69+
publish-github-container-registry:
70+
runs-on: ubuntu-latest
71+
if: github.event_name == 'release'
72+
environment: release
73+
needs: build
74+
permissions:
75+
contents: read
76+
packages: write
77+
attestations: write
78+
id-token: write
79+
steps:
80+
- uses: actions/checkout@v4
81+
82+
- name: Log in to the Container registry
83+
uses: docker/login-action@v3
84+
with:
85+
registry: ghcr.io
86+
username: ${{ github.actor }}
87+
password: ${{ secrets.GITHUB_TOKEN }}
88+
89+
- name: Extract metadata (tags, labels) for Docker
90+
id: meta
91+
uses: docker/metadata-action@v5
92+
with:
93+
images: ghcr.io/${{ github.repository }}
94+
95+
- name: Set up QEMU
96+
uses: docker/setup-qemu-action@v3
97+
98+
- name: Set up Docker Buildx
99+
uses: docker/setup-buildx-action@v3
100+
101+
- name: Build and push Docker image
102+
id: push
103+
uses: docker/build-push-action@v6
104+
with:
105+
context: .
106+
push: true
107+
platforms: linux/amd64,linux/arm64
108+
tags: ${{ steps.meta.outputs.tags }}
109+
labels: ${{ steps.meta.outputs.labels }}
110+
111+
- name: Generate artifact attestation
112+
uses: actions/attest-build-provenance@v2
113+
with:
114+
subject-name: ghcr.io/${{ github.repository }}
115+
subject-digest: ${{ steps.push.outputs.digest }}
116+
push-to-registry: true

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ client/tsconfig.app.tsbuildinfo
99
client/tsconfig.node.tsbuildinfo
1010
cli/build
1111
test-output
12+
client/playwright-report/
13+
client/results.json
14+
client/test-results/
15+

.node-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
22.x.x

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ The project is organized as a monorepo with workspaces:
3030

3131
- `client/`: React frontend with Vite, TypeScript and Tailwind
3232
- `server/`: Express backend with TypeScript
33-
- `bin/`: CLI scripts
33+
- `cli/`: Command-line interface for testing and invoking MCP server methods directly

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ Thanks for your interest in contributing! This guide explains how to get involve
77
1. Fork the repository and clone it locally
88
2. Install dependencies with `npm install`
99
3. Run `npm run dev` to start both client and server in development mode
10-
4. Use the web UI at http://127.0.0.1:6274 to interact with the inspector
10+
4. Use the web UI at http://localhost:6274 to interact with the inspector
1111

1212
## Development Process & Pull Requests
1313

1414
1. Create a new branch for your changes
1515
2. Make your changes following existing code style and conventions. You can run `npm run prettier-check` and `npm run prettier-fix` as applicable.
16-
3. Test changes locally by running `npm test`
16+
3. Test changes locally by running `npm test` and `npm run test:e2e`
1717
4. Update documentation as needed
1818
5. Use clear commit messages explaining your changes
1919
6. Verify all changes work as expected

Dockerfile

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Build stage
2+
FROM node:24-slim AS builder
3+
4+
# Set working directory
5+
WORKDIR /app
6+
7+
# Copy package files for installation
8+
COPY package*.json ./
9+
COPY .npmrc ./
10+
COPY client/package*.json ./client/
11+
COPY server/package*.json ./server/
12+
COPY cli/package*.json ./cli/
13+
14+
# Install dependencies
15+
RUN npm ci --ignore-scripts
16+
17+
# Copy source files
18+
COPY . .
19+
20+
# Build the application
21+
RUN npm run build
22+
23+
# Production stage
24+
FROM node:24-slim
25+
26+
WORKDIR /app
27+
28+
# Copy package files for production
29+
COPY package*.json ./
30+
COPY .npmrc ./
31+
COPY client/package*.json ./client/
32+
COPY server/package*.json ./server/
33+
COPY cli/package*.json ./cli/
34+
35+
# Install only production dependencies
36+
RUN npm ci --omit=dev --ignore-scripts
37+
38+
# Copy built files from builder stage
39+
COPY --from=builder /app/client/dist ./client/dist
40+
COPY --from=builder /app/client/bin ./client/bin
41+
COPY --from=builder /app/server/build ./server/build
42+
COPY --from=builder /app/cli/build ./cli/build
43+
44+
# Set default port values as environment variables
45+
ENV CLIENT_PORT=6274
46+
ENV SERVER_PORT=6277
47+
48+
# Document which ports the application uses internally
49+
EXPOSE ${CLIENT_PORT} ${SERVER_PORT}
50+
51+
# Use ENTRYPOINT with CMD for arguments
52+
ENTRYPOINT ["npm", "start"]

README.md

Lines changed: 77 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,31 @@ The MCP inspector is a developer tool for testing and debugging MCP servers.
44

55
![MCP Inspector Screenshot](https://raw.githubusercontent.com/modelcontextprotocol/inspector/main/mcp-inspector.png)
66

7+
## Architecture Overview
8+
9+
The MCP Inspector consists of two main components that work together:
10+
11+
- **MCP Inspector Client (MCPI)**: A React-based web UI that provides an interactive interface for testing and debugging MCP servers
12+
- **MCP Proxy (MCPP)**: A Node.js server that acts as a protocol bridge, connecting the web UI to MCP servers via various transport methods (stdio, SSE, streamable-http)
13+
14+
Note that the proxy is not a network proxy for intercepting traffic. Instead, it functions as both an MCP client (connecting to your MCP server) and an HTTP server (serving the web UI), enabling browser-based interaction with MCP servers that use different transport protocols.
15+
716
## Running the Inspector
817

918
### Requirements
1019

1120
- Node.js: ^22.7.5
1221

22+
### Quick Start (UI mode)
23+
24+
To get up and running right away with the UI, just execute the following:
25+
26+
```bash
27+
npx @modelcontextprotocol/inspector
28+
```
29+
30+
The server will start up and the UI will be accessible at `http://localhost:6274`.
31+
1332
### From an MCP server repository
1433

1534
To inspect an MCP server implementation, there's no need to clone this repo. Instead, use `npx`. For example, if your server is built at `build/index.js`:
@@ -118,17 +137,64 @@ The inspector supports bearer token authentication for SSE connections. Enter yo
118137

119138
The MCP Inspector includes a proxy server that can run and communicate with local MCP processes. The proxy server should not be exposed to untrusted networks as it has permissions to spawn local processes and can connect to any specified MCP server.
120139

140+
#### Authentication
141+
142+
The MCP Inspector proxy server requires authentication by default. When starting the server, a random session token is generated and printed to the console:
143+
144+
```
145+
🔑 Session token: 3a1c267fad21f7150b7d624c160b7f09b0b8c4f623c7107bbf13378f051538d4
146+
147+
🔗 Open inspector with token pre-filled:
148+
http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=3a1c267fad21f7150b7d624c160b7f09b0b8c4f623c7107bbf13378f051538d4
149+
```
150+
151+
This token must be included as a Bearer token in the Authorization header for all requests to the server. The inspector will automatically open your browser with the token pre-filled in the URL.
152+
153+
**Automatic browser opening** - The inspector now automatically opens your browser with the token pre-filled in the URL when authentication is enabled.
154+
155+
**Alternative: Manual configuration** - If you already have the inspector open:
156+
157+
1. Click the "Configuration" button in the sidebar
158+
2. Find "Proxy Session Token" and enter the token displayed in the proxy console
159+
3. Click "Save" to apply the configuration
160+
161+
The token will be saved in your browser's local storage for future use.
162+
163+
If you need to disable authentication (NOT RECOMMENDED), you can set the `DANGEROUSLY_OMIT_AUTH` environment variable:
164+
165+
```bash
166+
DANGEROUSLY_OMIT_AUTH=true npm start
167+
```
168+
169+
#### Local-only Binding
170+
171+
By default, both the MCP Inspector proxy server and client bind only to `localhost` to prevent network access. This ensures they are not accessible from other devices on the network. If you need to bind to all interfaces for development purposes, you can override this with the `HOST` environment variable:
172+
173+
```bash
174+
HOST=0.0.0.0 npm start
175+
```
176+
177+
**Warning:** Only bind to all interfaces in trusted network environments, as this exposes the proxy server's ability to execute local processes and both services to network access.
178+
179+
#### DNS Rebinding Protection
180+
181+
To prevent DNS rebinding attacks, the MCP Inspector validates the `Origin` header on incoming requests. By default, only requests from the client origin are allowed (respects `CLIENT_PORT` if set, defaulting to port 6274). You can configure additional allowed origins by setting the `ALLOWED_ORIGINS` environment variable (comma-separated list):
182+
183+
```bash
184+
ALLOWED_ORIGINS=http://localhost:6274,http://localhost:8000 npm start
185+
```
186+
121187
### Configuration
122188

123189
The MCP Inspector supports the following configuration settings. To change them, click on the `Configuration` button in the MCP Inspector UI:
124190

125-
| Setting | Description | Default |
126-
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------- |
127-
| `MCP_SERVER_REQUEST_TIMEOUT` | Timeout for requests to the MCP server (ms) | 10000 |
128-
| `MCP_REQUEST_TIMEOUT_RESET_ON_PROGRESS` | Reset timeout on progress notifications | true |
129-
| `MCP_REQUEST_MAX_TOTAL_TIMEOUT` | Maximum total timeout for requests sent to the MCP server (ms) (Use with progress notifications) | 60000 |
130-
| `MCP_PROXY_FULL_ADDRESS` | Set this if you are running the MCP Inspector Proxy on a non-default address. Example: http://10.1.1.22:5577 | "" |
131-
| `MCP_AUTO_OPEN_ENABLED` | Enable automatic browser opening when inspector starts. Only as environment var, not configurable in browser. | true |
191+
| Setting | Description | Default |
192+
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
193+
| `MCP_SERVER_REQUEST_TIMEOUT` | Timeout for requests to the MCP server (ms) | 10000 |
194+
| `MCP_REQUEST_TIMEOUT_RESET_ON_PROGRESS` | Reset timeout on progress notifications | true |
195+
| `MCP_REQUEST_MAX_TOTAL_TIMEOUT` | Maximum total timeout for requests sent to the MCP server (ms) (Use with progress notifications) | 60000 |
196+
| `MCP_PROXY_FULL_ADDRESS` | Set this if you are running the MCP Inspector Proxy on a non-default address. Example: http://10.1.1.22:5577 | "" |
197+
| `MCP_AUTO_OPEN_ENABLED` | Enable automatic browser opening when inspector starts (works with authentication enabled). Only as environment var, not configurable in browser. | true |
132198

133199
These settings can be adjusted in real-time through the UI and will persist across sessions.
134200

@@ -233,9 +299,12 @@ npx @modelcontextprotocol/inspector --cli node build/index.js --method resources
233299
# List available prompts
234300
npx @modelcontextprotocol/inspector --cli node build/index.js --method prompts/list
235301

236-
# Connect to a remote MCP server
302+
# Connect to a remote MCP server (default is SSE transport)
237303
npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com
238304

305+
# Connect to a remote MCP server (with Streamable HTTP transport)
306+
npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com --transport http
307+
239308
# Call a tool on a remote server
240309
npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com --method tools/call --tool-name remotetool --tool-arg param=value
241310

0 commit comments

Comments
 (0)