Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
eca81ec
Add .NET CLI implementation
asklar Sep 20, 2025
48b577c
Configure .NET tool for NuGet publishing
asklar Sep 20, 2025
b05feac
update readme
asklar Sep 20, 2025
eb0b94b
Optimize NuGet package size and bump version to 0.1.1
asklar Sep 20, 2025
41f2284
feat: Enhance Pack and Validate commands with dynamic tool discovery …
asklar Oct 5, 2025
ec6b503
fix: Refactor code for improved readability and consistency across mu…
asklar Oct 5, 2025
ef6e52b
0.2.0
asklar Oct 5, 2025
1280f4b
feat: Update validate command to support optional manifest argument a…
asklar Oct 5, 2025
880e8fe
Initial plan
Copilot Oct 12, 2025
ebd5a7c
Add _meta property and Windows static_responses support to .NET tool
Copilot Oct 12, 2025
91d8485
Fix static_responses serialization to use clean JSON structure
Copilot Oct 12, 2025
28ee865
Remove accidentally committed build artifacts from examples
Copilot Oct 12, 2025
23bd699
Use typed responses for initialize and tools/list static responses
Copilot Oct 12, 2025
8ff4d1b
Remove accidentally committed build artifacts
Copilot Oct 12, 2025
d59cd21
Use strongly typed models for static responses and get protocol versi…
Copilot Oct 12, 2025
6d175d6
Remove accidentally committed package-lock.json
Copilot Oct 12, 2025
095b351
Add YAML pipeline to test .NET tool with examples
Copilot Oct 12, 2025
8d374c6
Update .github/workflows/test-dotnet.yml
asklar Oct 12, 2025
7e04790
Fix Windows PowerShell syntax error and add user/asklar/dotnet branch…
Copilot Oct 12, 2025
9dc590c
Fix init command hanging by using --yes flag for non-interactive mode
Copilot Oct 13, 2025
cd2d423
Add CI test verifying inputSchema capture with hello-world example an…
Copilot Oct 13, 2025
8ebe23d
Remove accidentally committed example artifacts
Copilot Oct 13, 2025
8d3365b
Add real CI test for file-system-node with schema discovery using mod…
Copilot Oct 13, 2025
8873c36
Remove accidentally committed example artifacts
Copilot Oct 13, 2025
3b0ab56
Remove package-lock.json from examples
Copilot Oct 13, 2025
0cda640
Improve CI test to print full manifest and use JSON parsing for valid…
Copilot Oct 13, 2025
bfed1a1
Remove accidentally committed artifacts
Copilot Oct 13, 2025
66ddac4
Remove package-lock.json from examples
Copilot Oct 13, 2025
83ed03e
Fix null field serialization in static_responses by filtering at assi…
Copilot Oct 13, 2025
bfac6c3
Remove accidentally committed package-lock.json
Copilot Oct 13, 2025
a311216
Revert example manifest.json files to original state - CI should gene…
Copilot Oct 13, 2025
d0d0902
Revert yarn.lock for hello-world-node example to original state
Copilot Oct 13, 2025
7e51b72
Properly revert yarn.lock to original state before any PR changes
Copilot Oct 13, 2025
7f823f7
Update version to 0.3.0 in mcpb.csproj
asklar Oct 13, 2025
b5ff589
Merge pull request #2 from asklar/user/asklar/dotnet
asklar Oct 15, 2025
ccc2117
Bump version to 0.3.1 in mcpb.csproj
asklar Oct 15, 2025
81132ef
Refactor manifest handling and improve JSON serialization for Windows…
asklar Oct 15, 2025
cfee5ed
Add documentation for Windows _meta updates in README.md
asklar Oct 15, 2025
adfe057
Merge branch 'anthropics:main' into dotnet
asklar Oct 24, 2025
bd4371e
Initial plan
Copilot Oct 30, 2025
19e89ad
Add localization and icons support to .NET MCPB CLI (manifest 0.3)
Copilot Oct 30, 2025
ed170ca
Make localization fields optional with defaults (resources: mcpb-reso…
Copilot Oct 30, 2025
8e2bc36
Change icon 'sizes' to 'size' and add localization completeness valid…
Copilot Oct 30, 2025
c1f1a9a
Remove license from localizable properties list
Copilot Oct 30, 2025
4423180
Use strongly-typed model for localization resource files with System.…
Copilot Oct 31, 2025
81e719b
Update test-dotnet.yml
asklar Oct 31, 2025
a34ca60
Add 'dotnet' branch to workflow triggers
asklar Oct 31, 2025
8a2f07b
Bump version to 0.3.3
Copilot Nov 1, 2025
bbee7c4
Merge pull request #4 from asklar/copilot/update-mcpb-cli-localizatio…
asklar Nov 1, 2025
d0e2871
Initial plan
Copilot Nov 1, 2025
aa774ba
Create publishing workflow for .NET tool using trusted publishing
Copilot Nov 1, 2025
80c1cf3
Add documentation for trusted publishing setup
Copilot Nov 1, 2025
0a8a103
Fix trusted publishing configuration and improve workflow
Copilot Nov 1, 2025
71397e1
Update workflow to trigger on dotnet branch instead of main
Copilot Nov 1, 2025
f33d8d1
Merge pull request #5 from asklar/copilot/create-publishing-pipeline
asklar Nov 1, 2025
30b0584
Add GitHub Actions workflow for .NET tool publishing
asklar Nov 1, 2025
8316a0b
Remove API key from NuGet publish command
asklar Nov 1, 2025
e51eef4
Remove API key from NuGet push command
asklar Nov 1, 2025
fdbf997
Update NuGet source management in workflow
asklar Nov 1, 2025
043e1b7
Update NuGet source management in workflow
asklar Nov 1, 2025
3a05be7
Update NuGet publish workflow to use OIDC login
asklar Nov 2, 2025
1a34ce1
feat: Enhance ValidateCommand with discovery and verbose options
asklar Nov 9, 2025
0a17553
Merge branch 'modelcontextprotocol:main' into dotnet
asklar Dec 3, 2025
76ee3bb
Bump version and update dependencies in package.json
asklar Dec 3, 2025
96a5e43
Merge branch 'main' into dotnet
asklar Dec 4, 2025
c80dc47
run in dotnet branch
asklar Dec 4, 2025
a1049f8
Merge branch 'modelcontextprotocol:main' into dotnet
asklar Dec 4, 2025
ae84963
Add the ability to pass user_config to discovery
asklar Dec 5, 2025
37cc371
Merge pull request #6 from asklar/user/asklar/user_config
asklar Dec 5, 2025
6cedc6f
app exec alias support
asklar Dec 6, 2025
433d06c
fix: update link for App Execution Aliases documentation
asklar Dec 6, 2025
b69dcab
Merge pull request #7 from asklar/temp-stash
asklar Dec 6, 2025
fb0e98f
Merge branch 'modelcontextprotocol:main' into dotnet
asklar Dec 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/workflows/publish-dotnet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Publish .NET Tool

# This workflow publishes the .NET tool to NuGet using Trusted Publishing (OIDC).
#
# Setup required on NuGet.org:
# 1. Navigate to your package page at https://www.nuget.org/packages/Mcpb.Cli/
# 2. Go to "Manage Package" and select "Publishing" or "Trusted publishers"
# 3. Click "Add" to configure a new trusted publisher
# 4. Configure the GitHub Actions OIDC settings:
# - Subject Repository: asklar/mcpb
# - Subject Workflow: .github/workflows/publish-dotnet.yml
# - Subject Environment: nuget (optional but recommended)
# 5. Save the trusted publisher configuration
#
# Setup required in GitHub:
# 1. Create an environment named "nuget" in repository settings
# 2. Add protection rules if desired (e.g., required reviewers)
#
# The workflow will run automatically when the version in dotnet/mcpb/mcpb.csproj is changed
# and pushed to the dotnet branch, or it can be triggered manually.

on:
workflow_dispatch:
push:
branches:
- dotnet
paths:
- 'dotnet/mcpb/mcpb.csproj'

permissions:
contents: read
id-token: write

jobs:
publish:
name: Publish to NuGet
runs-on: ubuntu-latest
environment: nuget

steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup .NET
uses: actions/setup-dotnet@3e891b0cb619bf60e2c25674b222b8940e2c1c25 # v4.1.0
with:
dotnet-version: '8.0.x'

- name: Restore dependencies
run: |
cd dotnet
dotnet restore

- name: Build
run: |
cd dotnet
dotnet build -c Release --no-restore

- name: Test
run: |
cd dotnet
dotnet test -c Release --no-build --verbosity normal

- name: Pack
run: |
cd dotnet/mcpb
dotnet pack -c Release --no-build --output ./artifacts
- name: Remove old v2 NuGet source if exists
run: dotnet nuget remove source nuget.org || true

# Get a short-lived NuGet API key
- name: NuGet login (OIDC → temp API key)
uses: NuGet/login@v1
id: login
with:
user: ${{ secrets.NUGET_USER }} # Recommended: use a secret like ${{ secrets.NUGET_USER }} for your nuget.org username (profile name), NOT your email address

# Push the package
- name: NuGet push
run: |
cd dotnet/mcpb
dotnet nuget push ./artifacts/*.nupkg --api-key ${{steps.login.outputs.NUGET_API_KEY}} --source https://api.nuget.org/v3/index.json --skip-duplicate

292 changes: 292 additions & 0 deletions .github/workflows/test-dotnet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
name: Test .NET Tool

on:
pull_request:
branches:
- main
- user/asklar/dotnet
- dotnet
paths:
- 'dotnet/**'
- 'examples/**'
- '.github/workflows/test-dotnet.yml'
push:
branches:
- main
- dotnet
- user/asklar/dotnet
paths:
- 'dotnet/**'
- 'examples/**'
- '.github/workflows/test-dotnet.yml'

permissions:
contents: read

jobs:
test-dotnet:
name: Test .NET Tool
strategy:
matrix:
os:
- ubuntu-latest
- windows-latest
- macos-latest
runs-on: ${{ matrix.os }}

steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup .NET
uses: actions/setup-dotnet@3e891b0cb619bf60e2c25674b222b8940e2c1c25 # v4.1.0
with:
dotnet-version: '8.0.x'

- name: Setup Node.js (for examples)
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '20.x'

# Step a) Run .NET tests
- name: Run .NET Tests
shell: bash
run: |
cd dotnet
dotnet restore
dotnet build -c Release
dotnet test -c Release --no-build --verbosity normal

# Step b) Validate basic CLI functionality
- name: Test CLI - Help Command
shell: bash
run: |
cd dotnet
dotnet run --project mcpb/mcpb.csproj -- --help

- name: Test CLI - Version Command
shell: bash
run: |
cd dotnet
dotnet run --project mcpb/mcpb.csproj -- --version

# Step c) Test with examples - hello-world-node
- name: Setup hello-world-node Example
shell: bash
run: |
cd examples/hello-world-node
npm install

- name: Test CLI - Validate hello-world-node Manifest
shell: bash
run: |
cd dotnet
dotnet run --project mcpb/mcpb.csproj -- validate ../examples/hello-world-node/manifest.json

- name: Test CLI - Pack hello-world-node (with update and output)
shell: bash
run: |
cd examples/hello-world-node
echo "=== Original Manifest ==="
cat manifest.json
echo ""
echo "=== Running mcpb pack --update ==="
dotnet run --project ../../dotnet/mcpb/mcpb.csproj -- pack . hello-world-test.mcpb --update
echo ""
echo "=== Updated Manifest with _meta ==="
cat manifest.json
echo ""
echo "=== Verifying _meta field was added ==="
if grep -q '"_meta"' manifest.json; then
echo "✓ _meta field found in manifest"
else
echo "✗ _meta field NOT found in manifest"
exit 1
fi
echo ""
echo "=== Verifying static_responses ==="
if grep -q '"static_responses"' manifest.json; then
echo "✓ static_responses found in manifest"
else
echo "✗ static_responses NOT found in manifest"
exit 1
fi
echo ""
echo "=== Verifying inputSchema is present in tools/list ==="
if grep -q '"inputSchema"' manifest.json; then
echo "✓ inputSchema found in manifest"
echo ""
echo "=== Extracting tool schema from _meta ==="
cat manifest.json | grep -A 50 '"tools/list"' | head -50
else
echo "✗ inputSchema NOT found in manifest"
exit 1
fi
echo ""
echo "=== Verifying initialize response with protocolVersion ==="
if grep -q '"protocolVersion"' manifest.json; then
echo "✓ protocolVersion found"
echo ""
echo "=== Initialize response ==="
cat manifest.json | grep -A 20 '"initialize"' | head -20
else
echo "✗ protocolVersion NOT found"
exit 1
fi

# Test with file-system-node example
- name: Setup file-system-node Example
shell: bash
run: |
cd examples/file-system-node
npm install

- name: Test CLI - Validate file-system-node Manifest
shell: bash
run: |
cd dotnet
dotnet run --project mcpb/mcpb.csproj -- validate ../examples/file-system-node/manifest.json

- name: Test CLI - Pack file-system-node (no update)
shell: bash
run: |
cd examples/file-system-node
echo "=== Testing pack without --update ==="
dotnet run --project ../../dotnet/mcpb/mcpb.csproj -- pack . file-system-test.mcpb --force || true
echo ""
echo "=== Manifest (should be unchanged) ==="
cat manifest.json

- name: Test CLI - Update file-system-node with schema discovery
shell: bash
run: |
cd examples/file-system-node
echo "=== File-system-node example requires allowed_directories argument ==="
echo "=== Temporarily modifying manifest to include test directory ==="
cp manifest.json manifest.json.backup
TEST_DIR="$(cd .. && pwd)"
echo "Using test directory: $TEST_DIR"
jq --arg dir "$TEST_DIR" '.server.mcp_config.args = ["${__dirname}/server/index.js", $dir]' manifest.json > manifest.json.tmp && mv manifest.json.tmp manifest.json
echo ""
echo "=== Running mcpb pack --update to discover schemas ==="
dotnet run --project ../../dotnet/mcpb/mcpb.csproj -- pack . /tmp/fs-test.mcpb --update || echo "Pack may have warnings"
echo ""
echo "=== FULL UPDATED MANIFEST ==="
cat manifest.json | jq .
echo ""
echo "=== Verifying _meta field exists ==="
if [ "$(cat manifest.json | jq -r '._meta | type')" = "object" ]; then
echo "✓ _meta field is present and is an object"
else
echo "✗ _meta field NOT found or not an object"
mv manifest.json.backup manifest.json
exit 1
fi
echo ""
echo "=== Verifying com.microsoft.windows in _meta ==="
if [ "$(cat manifest.json | jq -r '._meta["com.microsoft.windows"] | type')" = "object" ]; then
echo "✓ com.microsoft.windows field is present"
else
echo "✗ com.microsoft.windows field NOT found"
mv manifest.json.backup manifest.json
exit 1
fi
echo ""
echo "=== Verifying static_responses in com.microsoft.windows ==="
if [ "$(cat manifest.json | jq -r '._meta["com.microsoft.windows"].static_responses | type')" = "object" ]; then
echo "✓ static_responses field is present"
else
echo "✗ static_responses field NOT found"
mv manifest.json.backup manifest.json
exit 1
fi
echo ""
echo "=== Verifying protocolVersion in initialize response ==="
PROTOCOL_VERSION=$(cat manifest.json | jq -r '._meta["com.microsoft.windows"].static_responses.initialize.protocolVersion')
if [ "$PROTOCOL_VERSION" != "null" ] && [ -n "$PROTOCOL_VERSION" ]; then
echo "✓ protocolVersion found: $PROTOCOL_VERSION"
else
echo "✗ protocolVersion NOT found"
mv manifest.json.backup manifest.json
exit 1
fi
echo ""
echo "=== Verifying tools/list has tools array ==="
TOOLS_COUNT=$(cat manifest.json | jq -r '._meta["com.microsoft.windows"].static_responses["tools/list"].tools | length')
if [ "$TOOLS_COUNT" -gt 0 ]; then
echo "✓ tools/list contains $TOOLS_COUNT tools"
else
echo "✗ tools/list does not contain any tools"
mv manifest.json.backup manifest.json
exit 1
fi
echo ""
echo "=== Verifying inputSchema for read_file tool ==="
READ_FILE_SCHEMA=$(cat manifest.json | jq '._meta["com.microsoft.windows"].static_responses["tools/list"].tools[] | select(.name == "read_file") | .inputSchema')
if [ "$READ_FILE_SCHEMA" != "null" ] && [ -n "$READ_FILE_SCHEMA" ]; then
echo "✓ inputSchema found for read_file"
echo "$READ_FILE_SCHEMA" | jq .
else
echo "✗ inputSchema NOT found for read_file"
mv manifest.json.backup manifest.json
exit 1
fi
echo ""
echo "=== Verifying inputSchema has required 'path' property for read_file ==="
HAS_PATH=$(cat manifest.json | jq -r '._meta["com.microsoft.windows"].static_responses["tools/list"].tools[] | select(.name == "read_file") | .inputSchema.properties.path | type')
if [ "$HAS_PATH" = "object" ]; then
echo "✓ read_file inputSchema has 'path' property"
else
echo "✗ read_file inputSchema missing 'path' property"
mv manifest.json.backup manifest.json
exit 1
fi
echo ""
echo "=== Verifying inputSchema for write_file tool ==="
WRITE_FILE_SCHEMA=$(cat manifest.json | jq '._meta["com.microsoft.windows"].static_responses["tools/list"].tools[] | select(.name == "write_file") | .inputSchema')
if [ "$WRITE_FILE_SCHEMA" != "null" ] && [ -n "$WRITE_FILE_SCHEMA" ]; then
echo "✓ inputSchema found for write_file"
echo "$WRITE_FILE_SCHEMA" | jq .
else
echo "✗ inputSchema NOT found for write_file"
mv manifest.json.backup manifest.json
exit 1
fi
echo ""
echo "=== Restoring original manifest ==="
mv manifest.json.backup manifest.json

# Test init command
- name: Test CLI - Init Command
shell: bash
run: |
cd dotnet
mkdir -p ../test-init
cd ../test-init
echo "=== Testing mcpb init ==="
dotnet run --project ../dotnet/mcpb/mcpb.csproj -- init --yes --server-type node --entry-point server/index.js
echo ""
echo "=== Generated Manifest ==="
cat manifest.json
echo ""
echo "=== Verifying manifest was created ==="
if [ -f manifest.json ]; then
echo "✓ manifest.json created"
else
echo "✗ manifest.json NOT created"
exit 1
fi

# Clean up test artifacts
- name: Cleanup
if: always()
shell: bash
run: |
cd examples/hello-world-node
git checkout manifest.json || true
rm -f hello-world-test.mcpb || true
cd ../file-system-node
git checkout manifest.json || true
rm -f file-system-test.mcpb file-system-schema-test.mcpb || true
cd ../../
rm -rf test-init || true
Loading