Merge pull request #1 from modelcontextprotocol/chore/scaffolding
Initial project structure for MCP variants
This commit is contained in:
parent
4c989fd9f6
commit
4f98e0aab3
30 changed files with 855 additions and 3 deletions
90
.github/workflows/comment-trigger.yml
vendored
Normal file
90
.github/workflows/comment-trigger.yml
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
name: Comment Trigger
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
actions: write
|
||||
|
||||
jobs:
|
||||
trigger-checks:
|
||||
name: Trigger Checks from Comment
|
||||
if: |
|
||||
github.event.issue.pull_request &&
|
||||
(github.event.comment.body == '/test all' ||
|
||||
github.event.comment.body == '/test-all' ||
|
||||
github.event.comment.body == '/run-all-checks') &&
|
||||
(github.event.comment.author_association == 'OWNER' ||
|
||||
github.event.comment.author_association == 'MEMBER' ||
|
||||
github.event.comment.author_association == 'COLLABORATOR')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get PR branch
|
||||
uses: actions/github-script@v7
|
||||
id: get-pr
|
||||
with:
|
||||
script: |
|
||||
const pr = await github.rest.pulls.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: context.issue.number
|
||||
});
|
||||
return pr.data.head.ref;
|
||||
|
||||
- name: Add reaction to comment
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
await github.rest.reactions.createForIssueComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: context.payload.comment.id,
|
||||
content: 'rocket'
|
||||
});
|
||||
|
||||
- name: Trigger Python CI
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
await github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: 'python.yml',
|
||||
ref: '${{ fromJSON(steps.get-pr.outputs.result) }}'
|
||||
});
|
||||
|
||||
- name: Trigger Go CI
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
await github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: 'go.yml',
|
||||
ref: '${{ fromJSON(steps.get-pr.outputs.result) }}'
|
||||
});
|
||||
|
||||
- name: Trigger TypeScript CI
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
await github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: 'typescript.yml',
|
||||
ref: '${{ fromJSON(steps.get-pr.outputs.result) }}'
|
||||
});
|
||||
|
||||
- name: Comment on PR
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body: '🚀 All CI checks triggered! Check the Actions tab for progress.'
|
||||
});
|
||||
80
.github/workflows/go.yml
vendored
Normal file
80
.github/workflows/go.yml
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
name: Go CI
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'go/**'
|
||||
- '.github/workflows/go.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'go/**'
|
||||
- '.github/workflows/go.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
go-lint:
|
||||
name: "Linting"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||
with:
|
||||
go-version: "^1.25"
|
||||
- name: Check formatting
|
||||
run: |
|
||||
cd go/sdk
|
||||
unformatted=$(gofmt -l .)
|
||||
if [ -n "$unformatted" ]; then
|
||||
echo "The following files are not properly formatted:"
|
||||
echo "$unformatted"
|
||||
exit 1
|
||||
fi
|
||||
echo "All Go files are properly formatted"
|
||||
- name: Run Go vet
|
||||
run: |
|
||||
cd go/sdk
|
||||
go vet ./...
|
||||
- name: Run staticcheck
|
||||
uses: dominikh/staticcheck-action@288b4e28bae83c59f35f73651aeb5cab746a06fc # v1.4.0
|
||||
with:
|
||||
install-go: false
|
||||
version: "v0.6.1"
|
||||
working-directory: go/sdk
|
||||
|
||||
go-test:
|
||||
name: "Unit Tests"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go: ["1.23", "1.24", "1.25"]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
- name: Test
|
||||
run: |
|
||||
cd go/sdk
|
||||
go test -v ./...
|
||||
|
||||
go-race-test:
|
||||
name: "Race Detection"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||
with:
|
||||
go-version: "1.24"
|
||||
- name: Test with -race
|
||||
run: |
|
||||
cd go/sdk
|
||||
go test -v -race ./...
|
||||
67
.github/workflows/python.yml
vendored
Normal file
67
.github/workflows/python.yml
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
name: Python CI
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'python/**'
|
||||
- '.github/workflows/python.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'python/**'
|
||||
- '.github/workflows/python.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
python-lint:
|
||||
name: "Linting"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd python/sdk
|
||||
pip install -e .
|
||||
pip install ruff mypy
|
||||
- name: Run Ruff formatter check
|
||||
run: |
|
||||
cd python/sdk
|
||||
ruff format --check .
|
||||
- name: Run Ruff linter
|
||||
run: |
|
||||
cd python/sdk
|
||||
ruff check .
|
||||
- name: Run mypy
|
||||
run: |
|
||||
cd python/sdk
|
||||
mypy src/mcp_ext_variants --ignore-missing-imports
|
||||
|
||||
python-test:
|
||||
name: "Unit Tests"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.10", "3.11", "3.12"]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd python/sdk
|
||||
pip install -e .
|
||||
pip install pytest pytest-cov
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd python/sdk
|
||||
pytest -v --cov=src/mcp_ext_variants
|
||||
138
.github/workflows/status-check.yml
vendored
Normal file
138
.github/workflows/status-check.yml
vendored
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
name: Status Check
|
||||
|
||||
# This workflow enforces that all relevant CI checks pass based on which files changed.
|
||||
# It's the only required status check in branch protection settings.
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
workflow_run:
|
||||
workflows: ["Python CI", "Go CI", "TypeScript CI"]
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
statuses: write
|
||||
checks: write
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
verify-required-checks:
|
||||
name: Verify Required Checks
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request' || github.event.workflow_run.conclusion != 'cancelled'
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get PR number
|
||||
id: pr
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" == "workflow_run" ]; then
|
||||
PR_NUMBER=$(gh pr list --head "${{ github.event.workflow_run.head_branch }}" --json number --jq '.[0].number')
|
||||
echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: dorny/paths-filter@v3
|
||||
with:
|
||||
filters: |
|
||||
python:
|
||||
- 'python/**'
|
||||
- '.github/workflows/python.yml'
|
||||
go:
|
||||
- 'go/**'
|
||||
- '.github/workflows/go.yml'
|
||||
typescript:
|
||||
- 'typescript/**'
|
||||
- '.github/workflows/typescript.yml'
|
||||
|
||||
- name: Check required statuses
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const owner = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
const ref = context.payload.pull_request?.head.sha || context.payload.workflow_run?.head_sha;
|
||||
|
||||
// Define required checks per language
|
||||
const requiredChecks = {
|
||||
python: [
|
||||
'Python CI / Linting',
|
||||
'Python CI / Unit Tests (3.10)',
|
||||
'Python CI / Unit Tests (3.11)',
|
||||
'Python CI / Unit Tests (3.12)'
|
||||
],
|
||||
go: [
|
||||
'Go CI / Linting',
|
||||
'Go CI / Unit Tests (1.23)',
|
||||
'Go CI / Unit Tests (1.24)',
|
||||
'Go CI / Unit Tests (1.25)',
|
||||
'Go CI / Race Detection'
|
||||
],
|
||||
typescript: [
|
||||
'TypeScript CI / Linting',
|
||||
'TypeScript CI / Unit Tests (20)',
|
||||
'TypeScript CI / Unit Tests (22)'
|
||||
]
|
||||
};
|
||||
|
||||
// Get changed files from previous step
|
||||
const changedFiles = {
|
||||
python: ${{ steps.changed-files.outputs.python }} === 'true',
|
||||
go: ${{ steps.changed-files.outputs.go }} === 'true',
|
||||
typescript: ${{ steps.changed-files.outputs.typescript }} === 'true'
|
||||
};
|
||||
|
||||
// Collect all required checks based on changes
|
||||
let allRequiredChecks = [];
|
||||
for (const [lang, changed] of Object.entries(changedFiles)) {
|
||||
if (changed) {
|
||||
allRequiredChecks = allRequiredChecks.concat(requiredChecks[lang]);
|
||||
}
|
||||
}
|
||||
|
||||
if (allRequiredChecks.length === 0) {
|
||||
console.log('No language files changed, no checks required');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all check runs for this commit
|
||||
const { data: checkRuns } = await github.rest.checks.listForRef({
|
||||
owner,
|
||||
repo,
|
||||
ref
|
||||
});
|
||||
|
||||
// Verify all required checks have passed
|
||||
const checkStatuses = {};
|
||||
for (const check of checkRuns.check_runs) {
|
||||
checkStatuses[check.name] = check.conclusion;
|
||||
}
|
||||
|
||||
let allPassed = true;
|
||||
let failureMessage = '';
|
||||
|
||||
for (const requiredCheck of allRequiredChecks) {
|
||||
const status = checkStatuses[requiredCheck];
|
||||
if (!status) {
|
||||
allPassed = false;
|
||||
failureMessage += `❌ ${requiredCheck}: Not started\\n`;
|
||||
} else if (status !== 'success') {
|
||||
allPassed = false;
|
||||
failureMessage += `❌ ${requiredCheck}: ${status}\\n`;
|
||||
} else {
|
||||
failureMessage += `✅ ${requiredCheck}: ${status}\\n`;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allPassed) {
|
||||
core.setFailed(`Required checks have not passed:\\n${failureMessage}`);
|
||||
} else {
|
||||
console.log(`All required checks passed:\\n${failureMessage}`);
|
||||
}
|
||||
61
.github/workflows/typescript.yml
vendored
Normal file
61
.github/workflows/typescript.yml
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
name: TypeScript CI
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'typescript/**'
|
||||
- '.github/workflows/typescript.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'typescript/**'
|
||||
- '.github/workflows/typescript.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
typescript-lint:
|
||||
name: "Linting"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v6
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "20"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd typescript/sdk
|
||||
npm install
|
||||
- name: Run TypeScript compiler check
|
||||
run: |
|
||||
cd typescript/sdk
|
||||
npm run build
|
||||
- name: Run ESLint
|
||||
run: |
|
||||
cd typescript/sdk
|
||||
npm run lint
|
||||
|
||||
typescript-test:
|
||||
name: "Unit Tests"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: ["20", "22"]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v6
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd typescript/sdk
|
||||
npm install
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd typescript/sdk
|
||||
npm test
|
||||
44
.gitignore
vendored
44
.gitignore
vendored
|
|
@ -1,6 +1,3 @@
|
|||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
#
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
|
|
@ -30,3 +27,44 @@ go.work.sum
|
|||
# Editor/IDE
|
||||
# .idea/
|
||||
# .vscode/
|
||||
|
||||
# Node.js / TypeScript
|
||||
node_modules/
|
||||
dist/
|
||||
*.tsbuildinfo
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
.venv/
|
||||
venv/
|
||||
ENV/
|
||||
.pytest_cache/
|
||||
.mypy_cache/
|
||||
.ruff_cache/
|
||||
htmlcov/
|
||||
.coverage
|
||||
.coverage.*
|
||||
coverage.xml
|
||||
*.cover
|
||||
70
README.md
70
README.md
|
|
@ -3,3 +3,73 @@
|
|||
> #### **Status:** Experimental. This work is for prototyping and feedback only, and is not an accepted or official MCP extension.
|
||||
|
||||
This repository provides a multi-language reference implementation of the variants proposal for the Model Context Protocol (MCP), as described in [SEP-2053](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2053).
|
||||
|
||||
## Implementations
|
||||
|
||||
| Language | Directory | Package | Status |
|
||||
|----------|-----------|---------|--------|
|
||||
| Go | `go/sdk/` | `github.com/modelcontextprotocol/experimental-ext-variants/go/sdk` | Planned |
|
||||
| Python | `python/sdk/` | `mcp-ext-variants` | Planned |
|
||||
| TypeScript | `typescript/sdk/` | `@ext-modelcontextprotocol/variants` | Planned |
|
||||
|
||||
|
||||
## CI/CD
|
||||
|
||||
This monorepo uses **path-based CI workflows** to efficiently test only what changes:
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **Language-specific workflows** (`python.yml`, `go.yml`, `typescript.yml`)
|
||||
- Only trigger when their language directory or workflow file changes
|
||||
- Run all tests, linting, and checks for that language
|
||||
|
||||
2. **Status check workflow** (`status-check.yml`)
|
||||
- Runs on every PR to verify required checks passed
|
||||
- Determines what needs to pass based on which files changed
|
||||
- This is the only required check in branch protection
|
||||
|
||||
### Examples
|
||||
|
||||
- Change `python/sdk/file.py` → Only Python CI runs → PR requires Python checks to pass
|
||||
- Change both Go and TypeScript files → Both CIs run → PR requires both to pass
|
||||
- Change only `README.md` → No language CIs run → PR can merge immediately
|
||||
|
||||
### Forcing All Checks
|
||||
|
||||
To run all language checks regardless of changed files:
|
||||
- **In a PR**: Comment `/test all` (only works for repo owners/members/collaborators)
|
||||
- **Manually**: Use GitHub Actions UI or CLI to trigger individual workflows
|
||||
|
||||
### Adding New Required Checks
|
||||
|
||||
1. **Add your check** to the appropriate language workflow (e.g., `python.yml`):
|
||||
```yaml
|
||||
python-security-scan:
|
||||
name: "Security Scan"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Run security checks
|
||||
run: # your commands here
|
||||
```
|
||||
|
||||
2. **Update the status check** in `.github/workflows/status-check.yml`:
|
||||
```javascript
|
||||
const requiredChecks = {
|
||||
python: [
|
||||
'Python CI / Linting',
|
||||
'Python CI / Unit Tests (3.10)',
|
||||
// ... existing checks ...
|
||||
'Python CI / Security Scan' // ← Add your new check
|
||||
],
|
||||
```
|
||||
|
||||
3. **Submit PR** - Your new check is now required for all relevant changes!
|
||||
|
||||
## License
|
||||
|
||||
Apache License 2.0 - See LICENSE file for details
|
||||
|
||||
## Resources
|
||||
|
||||
- [Variants Proposal Specification (SEP-2053)](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2053) - Full specification and design details
|
||||
- [Model Context Protocol](https://modelcontextprotocol.io/specification)
|
||||
|
|
|
|||
0
conformance/.gitkeep
Normal file
0
conformance/.gitkeep
Normal file
3
go/sdk/README.md
Normal file
3
go/sdk/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# MCP Variants - Go Implementation
|
||||
|
||||
This will contain the Go implementation of the MCP Variants based on [SEP-2053](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2053).
|
||||
0
go/sdk/examples/.gitkeep
Normal file
0
go/sdk/examples/.gitkeep
Normal file
3
go/sdk/go.mod
Normal file
3
go/sdk/go.mod
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module github.com/modelcontextprotocol/experimental-ext-variants/go/sdk
|
||||
|
||||
go 1.23.0
|
||||
0
go/sdk/internal/.gitkeep
Normal file
0
go/sdk/internal/.gitkeep
Normal file
6
go/sdk/variants/variant.go
Normal file
6
go/sdk/variants/variant.go
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// Copyright 2025 The MCP Variants Authors. All rights reserved.
|
||||
// Use of this source code is governed by a Apache-2.0
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package variants implements MCP Variants for experimental extensions.
|
||||
package variants
|
||||
14
go/sdk/variants/variant_test.go
Normal file
14
go/sdk/variants/variant_test.go
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2025 The MCP Variants Authors. All rights reserved.
|
||||
// Use of this source code is governed by a Apache-2.0
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package variants
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestPlaceholder(t *testing.T) {
|
||||
// Placeholder test to ensure go test runs successfully
|
||||
if false {
|
||||
t.Error("This should not happen")
|
||||
}
|
||||
}
|
||||
31
python/sdk/README.md
Normal file
31
python/sdk/README.md
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# MCP Variants Python SDK
|
||||
|
||||
Python implementation of the Model Context Protocol (MCP) variants framework.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install mcp-ext-variants
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
from mcp_ext_variants import Variant
|
||||
|
||||
# Example usage will be added as the implementation progresses
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Install in development mode
|
||||
pip install -e .
|
||||
|
||||
# Run tests (when available)
|
||||
pytest
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Apache License 2.0 - See LICENSE file in the root directory for details.
|
||||
71
python/sdk/pyproject.toml
Normal file
71
python/sdk/pyproject.toml
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
[project]
|
||||
name = "mcp-ext-variants"
|
||||
version = "0.1.0"
|
||||
description = "Python SDK for Model Context Protocol variants"
|
||||
authors = [{name = "The MCP Variants Authors"}]
|
||||
readme = "README.md"
|
||||
license = {text = "Apache-2.0"}
|
||||
requires-python = ">=3.10"
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
]
|
||||
dependencies = [
|
||||
"mcp>=1.0.0",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
"Homepage" = "https://github.com/modelcontextprotocol/experimental-ext-variants"
|
||||
"Bug Reports" = "https://github.com/modelcontextprotocol/experimental-ext-variants/issues"
|
||||
"Source" = "https://github.com/modelcontextprotocol/experimental-ext-variants"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["src/mcp_ext_variants"]
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 120
|
||||
target-version = "py310"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"E", # pycodestyle
|
||||
"F", # pyflakes
|
||||
"I", # isort
|
||||
"UP", # pyupgrade
|
||||
"C4", # flake8-comprehensions
|
||||
"PERF", # Perflint
|
||||
]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"__init__.py" = ["F401"] # Allow unused imports in __init__.py
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "double"
|
||||
indent-style = "space"
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.10"
|
||||
warn_return_any = true
|
||||
warn_unused_configs = true
|
||||
disallow_untyped_defs = true
|
||||
ignore_missing_imports = true
|
||||
|
||||
[tool.pyright]
|
||||
typeCheckingMode = "basic"
|
||||
include = ["src/mcp_ext_variants", "tests"]
|
||||
venvPath = "."
|
||||
venv = ".venv"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
python_files = ["test_*.py", "*_test.py"]
|
||||
addopts = "--strict-markers --verbose"
|
||||
11
python/sdk/src/mcp_ext_variants/__init__.py
Normal file
11
python/sdk/src/mcp_ext_variants/__init__.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Copyright 2025 The MCP Variants Authors. All rights reserved.
|
||||
# Use of this source code is governed by a Apache-2.0
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
"""
|
||||
MCP Variants Python SDK
|
||||
|
||||
Implements experimental MCP Variants for extended functionality.
|
||||
"""
|
||||
|
||||
__all__: list[str] = [] # Export list will be populated as the SDK develops
|
||||
0
python/sdk/src/mcp_ext_variants/py.typed
Normal file
0
python/sdk/src/mcp_ext_variants/py.typed
Normal file
9
python/sdk/src/mcp_ext_variants/variant.py
Normal file
9
python/sdk/src/mcp_ext_variants/variant.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Copyright 2025 The MCP Variants Authors. All rights reserved.
|
||||
# Use of this source code is governed by a Apache-2.0
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
"""
|
||||
Package variants implements experimental MCP Variants for extended functionality.
|
||||
"""
|
||||
|
||||
__all__ = [] # Export list will be populated as the SDK develops
|
||||
1
python/sdk/tests/__init__.py
Normal file
1
python/sdk/tests/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Tests for mcp-ext-variants
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue