mcpcat 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcpcat-0.1.0/.claude/settings.local.json +16 -0
- mcpcat-0.1.0/.github/workflows/mcp-compatibility.yml +119 -0
- mcpcat-0.1.0/.gitignore +147 -0
- mcpcat-0.1.0/CLAUDE.md +1 -0
- mcpcat-0.1.0/PKG-INFO +145 -0
- mcpcat-0.1.0/PythonSDKSupport.md +425 -0
- mcpcat-0.1.0/README.md +121 -0
- mcpcat-0.1.0/examples/basic_usage.py +40 -0
- mcpcat-0.1.0/pyproject.toml +87 -0
- mcpcat-0.1.0/src/mcpcat/__init__.py +106 -0
- mcpcat-0.1.0/src/mcpcat/modules/__init__.py +38 -0
- mcpcat-0.1.0/src/mcpcat/modules/compatibility.py +63 -0
- mcpcat-0.1.0/src/mcpcat/modules/context_parameters.py +52 -0
- mcpcat-0.1.0/src/mcpcat/modules/internal.py +40 -0
- mcpcat-0.1.0/src/mcpcat/modules/logging.py +128 -0
- mcpcat-0.1.0/src/mcpcat/modules/overrides/fastmcp.py +31 -0
- mcpcat-0.1.0/src/mcpcat/modules/overrides/mcp_server.py +160 -0
- mcpcat-0.1.0/src/mcpcat/modules/redaction.py +42 -0
- mcpcat-0.1.0/src/mcpcat/modules/session.py +85 -0
- mcpcat-0.1.0/src/mcpcat/modules/tools.py +39 -0
- mcpcat-0.1.0/src/mcpcat/modules/tracing.py +101 -0
- mcpcat-0.1.0/src/mcpcat/modules/version_detection.py +47 -0
- mcpcat-0.1.0/src/mcpcat/types.py +66 -0
- mcpcat-0.1.0/tests/__init__.py +1 -0
- mcpcat-0.1.0/tests/test_context_parameter_integration.py +71 -0
- mcpcat-0.1.0/tests/test_error_tracking.py +219 -0
- mcpcat-0.1.0/tests/test_functionality.py +89 -0
- mcpcat-0.1.0/tests/test_get_unknown_or_stdio_session.py +185 -0
- mcpcat-0.1.0/tests/test_identify_function.py +225 -0
- mcpcat-0.1.0/tests/test_mcp_version_compatibility.py +19 -0
- mcpcat-0.1.0/tests/test_options_handling.py +40 -0
- mcpcat-0.1.0/tests/test_preserve_existing_tools.py +137 -0
- mcpcat-0.1.0/tests/test_redact_sensitive_information.py +162 -0
- mcpcat-0.1.0/tests/test_tool_call_context.py +90 -0
- mcpcat-0.1.0/tests/test_tool_call_context_logging.py +112 -0
- mcpcat-0.1.0/tests/test_trace_collection.py +33 -0
- mcpcat-0.1.0/tests/test_track.py +37 -0
- mcpcat-0.1.0/tests/test_utils/__init__.py +26 -0
- mcpcat-0.1.0/tests/test_utils/client.py +45 -0
- mcpcat-0.1.0/tests/test_utils/todo_server.py +71 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(mkdir:*)",
|
|
5
|
+
"Bash(find:*)",
|
|
6
|
+
"Bash(grep:*)",
|
|
7
|
+
"Bash(uv run pytest tests/test_get_unknown_or_stdio_session.py -v)",
|
|
8
|
+
"Bash(uv run:*)",
|
|
9
|
+
"Bash(rg:*)",
|
|
10
|
+
"Bash(/Users/naseemalnaji/.nvm/versions/node/v23.5.0/lib/node_modules/@anthropic-ai/claude-code/vendor/ripgrep/arm64-darwin/rg \"CallToolResult\" --type py -A 3 -B 3)",
|
|
11
|
+
"Bash(/Users/naseemalnaji/.nvm/versions/node/v23.5.0/lib/node_modules/@anthropic-ai/claude-code/vendor/ripgrep/arm64-darwin/rg \"from mcp.types import.*CallToolResult\" --type py)",
|
|
12
|
+
"Bash(pip show:*)"
|
|
13
|
+
],
|
|
14
|
+
"deny": []
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
name: MCP Version Compatibility Testing
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
schedule:
|
|
9
|
+
# Run weekly to catch new MCP versions
|
|
10
|
+
- cron: '0 0 * * 0'
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
discover-versions:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
outputs:
|
|
17
|
+
mcp-versions: ${{ steps.get-versions.outputs.versions }}
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Get available MCP versions
|
|
21
|
+
id: get-versions
|
|
22
|
+
run: |
|
|
23
|
+
# Get all available versions from PyPI
|
|
24
|
+
versions=$(pip index versions mcp 2>/dev/null | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | sort -V)
|
|
25
|
+
|
|
26
|
+
# Filter to versions >= 1.2.0 and get only latest patch version for each minor
|
|
27
|
+
declare -A latest_minor
|
|
28
|
+
for version in $versions; do
|
|
29
|
+
major=$(echo $version | cut -d. -f1)
|
|
30
|
+
minor=$(echo $version | cut -d. -f2)
|
|
31
|
+
patch=$(echo $version | cut -d. -f3)
|
|
32
|
+
|
|
33
|
+
# Include if version >= 1.2.0
|
|
34
|
+
if [ "$major" -gt 1 ] || ([ "$major" -eq 1 ] && [ "$minor" -ge 2 ]); then
|
|
35
|
+
minor_key="$major.$minor"
|
|
36
|
+
latest_minor[$minor_key]="$version"
|
|
37
|
+
fi
|
|
38
|
+
done
|
|
39
|
+
|
|
40
|
+
# Create JSON array from latest versions
|
|
41
|
+
filtered_versions=()
|
|
42
|
+
for version in "${latest_minor[@]}"; do
|
|
43
|
+
filtered_versions+=("\"$version\"")
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
json_array="[$(IFS=,; echo "${filtered_versions[*]}")]"
|
|
47
|
+
echo "Found MCP versions: $json_array"
|
|
48
|
+
echo "versions=$json_array" >> $GITHUB_OUTPUT
|
|
49
|
+
|
|
50
|
+
test-compatibility:
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
needs: discover-versions
|
|
53
|
+
strategy:
|
|
54
|
+
matrix:
|
|
55
|
+
mcp-version: ${{ fromJson(needs.discover-versions.outputs.mcp-versions) }}
|
|
56
|
+
fail-fast: false
|
|
57
|
+
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
|
|
61
|
+
- name: Install uv
|
|
62
|
+
uses: astral-sh/setup-uv@v4
|
|
63
|
+
with:
|
|
64
|
+
version: "latest"
|
|
65
|
+
|
|
66
|
+
- name: Set up Python 3.12
|
|
67
|
+
uses: actions/setup-python@v5
|
|
68
|
+
with:
|
|
69
|
+
python-version: '3.12'
|
|
70
|
+
|
|
71
|
+
- name: Update pyproject.toml with MCP ${{ matrix.mcp-version }}
|
|
72
|
+
run: |
|
|
73
|
+
# Replace the whole quoted string, preserving the trailing comma
|
|
74
|
+
sed -i -E 's/"mcp==[^"]+"/"mcp==${{ matrix.mcp-version }}"/' pyproject.toml
|
|
75
|
+
|
|
76
|
+
- name: Install dependencies with MCP ${{ matrix.mcp-version }}
|
|
77
|
+
run: |
|
|
78
|
+
uv sync --extra dev
|
|
79
|
+
|
|
80
|
+
- name: Run full test suite with MCP ${{ matrix.mcp-version }}
|
|
81
|
+
run: |
|
|
82
|
+
echo "Running full test suite with MCP version ${{ matrix.mcp-version }}"
|
|
83
|
+
uv run pytest tests/ -v
|
|
84
|
+
|
|
85
|
+
report-compatibility:
|
|
86
|
+
runs-on: ubuntu-latest
|
|
87
|
+
needs: [discover-versions, test-compatibility]
|
|
88
|
+
if: always()
|
|
89
|
+
|
|
90
|
+
steps:
|
|
91
|
+
- uses: actions/checkout@v4
|
|
92
|
+
|
|
93
|
+
- name: Print compatibility report
|
|
94
|
+
run: |
|
|
95
|
+
echo "=========================================="
|
|
96
|
+
echo " MCP VERSION COMPATIBILITY REPORT "
|
|
97
|
+
echo "=========================================="
|
|
98
|
+
echo ""
|
|
99
|
+
echo "This report shows the compatibility status of MCPCat with different MCP versions."
|
|
100
|
+
echo ""
|
|
101
|
+
echo "Generated on: $(date)"
|
|
102
|
+
echo ""
|
|
103
|
+
echo "📋 TESTED VERSIONS"
|
|
104
|
+
echo "─────────────────────────────────────────"
|
|
105
|
+
echo "MCP versions tested: ${{ needs.discover-versions.outputs.mcp-versions }}"
|
|
106
|
+
echo "Python version: 3.12"
|
|
107
|
+
echo ""
|
|
108
|
+
echo "🧪 TEST COVERAGE"
|
|
109
|
+
echo "─────────────────────────────────────────"
|
|
110
|
+
echo "✓ FastMCP server compatibility"
|
|
111
|
+
echo "✓ Low-level Server compatibility"
|
|
112
|
+
echo "✓ Both implementations tested with is_compatible_server function"
|
|
113
|
+
echo ""
|
|
114
|
+
echo "📊 RESULTS"
|
|
115
|
+
echo "─────────────────────────────────────────"
|
|
116
|
+
echo "Check the individual test job results above for detailed compatibility status."
|
|
117
|
+
echo "Each MCP version was tested in a separate matrix job."
|
|
118
|
+
echo ""
|
|
119
|
+
echo "=========================================="
|
mcpcat-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
*.manifest
|
|
31
|
+
*.spec
|
|
32
|
+
|
|
33
|
+
# Installer logs
|
|
34
|
+
pip-log.txt
|
|
35
|
+
pip-delete-this-directory.txt
|
|
36
|
+
|
|
37
|
+
# Unit test / coverage reports
|
|
38
|
+
htmlcov/
|
|
39
|
+
.tox/
|
|
40
|
+
.nox/
|
|
41
|
+
.coverage
|
|
42
|
+
.coverage.*
|
|
43
|
+
.cache
|
|
44
|
+
nosetests.xml
|
|
45
|
+
coverage.xml
|
|
46
|
+
*.cover
|
|
47
|
+
*.py,cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
.pytest_cache/
|
|
50
|
+
cover/
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
*.pot
|
|
55
|
+
|
|
56
|
+
# Django stuff:
|
|
57
|
+
*.log
|
|
58
|
+
local_settings.py
|
|
59
|
+
db.sqlite3
|
|
60
|
+
db.sqlite3-journal
|
|
61
|
+
|
|
62
|
+
# Flask stuff:
|
|
63
|
+
instance/
|
|
64
|
+
.webassets-cache
|
|
65
|
+
|
|
66
|
+
# Scrapy stuff:
|
|
67
|
+
.scrapy
|
|
68
|
+
|
|
69
|
+
# Sphinx documentation
|
|
70
|
+
docs/_build/
|
|
71
|
+
|
|
72
|
+
# PyBuilder
|
|
73
|
+
.pybuilder/
|
|
74
|
+
target/
|
|
75
|
+
|
|
76
|
+
# Jupyter Notebook
|
|
77
|
+
.ipynb_checkpoints
|
|
78
|
+
|
|
79
|
+
# IPython
|
|
80
|
+
profile_default/
|
|
81
|
+
ipython_config.py
|
|
82
|
+
|
|
83
|
+
# pyenv
|
|
84
|
+
.python-version
|
|
85
|
+
|
|
86
|
+
# pipenv
|
|
87
|
+
Pipfile.lock
|
|
88
|
+
|
|
89
|
+
# pdm
|
|
90
|
+
.pdm.toml
|
|
91
|
+
.pdm-python
|
|
92
|
+
|
|
93
|
+
# PEP 582
|
|
94
|
+
__pypackages__/
|
|
95
|
+
|
|
96
|
+
# Celery stuff
|
|
97
|
+
celerybeat-schedule
|
|
98
|
+
celerybeat.pid
|
|
99
|
+
|
|
100
|
+
# SageMath parsed files
|
|
101
|
+
*.sage.py
|
|
102
|
+
|
|
103
|
+
# Environments
|
|
104
|
+
.env
|
|
105
|
+
.venv
|
|
106
|
+
env/
|
|
107
|
+
venv/
|
|
108
|
+
ENV/
|
|
109
|
+
env.bak/
|
|
110
|
+
venv.bak/
|
|
111
|
+
|
|
112
|
+
# Spyder project settings
|
|
113
|
+
.spyderproject
|
|
114
|
+
.spyproject
|
|
115
|
+
|
|
116
|
+
# Rope project settings
|
|
117
|
+
.ropeproject
|
|
118
|
+
|
|
119
|
+
# mkdocs documentation
|
|
120
|
+
/site
|
|
121
|
+
|
|
122
|
+
# mypy
|
|
123
|
+
.mypy_cache/
|
|
124
|
+
.dmypy.json
|
|
125
|
+
dmypy.json
|
|
126
|
+
|
|
127
|
+
# Pyre type checker
|
|
128
|
+
.pyre/
|
|
129
|
+
|
|
130
|
+
# pytype static type analyzer
|
|
131
|
+
.pytype/
|
|
132
|
+
|
|
133
|
+
# Cython debug symbols
|
|
134
|
+
cython_debug/
|
|
135
|
+
|
|
136
|
+
# PyCharm
|
|
137
|
+
.idea/
|
|
138
|
+
|
|
139
|
+
# VSCode
|
|
140
|
+
.vscode/
|
|
141
|
+
|
|
142
|
+
# macOS
|
|
143
|
+
.DS_Store
|
|
144
|
+
|
|
145
|
+
# uv
|
|
146
|
+
.uv/
|
|
147
|
+
uv.lock
|
mcpcat-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
- Always run with `uv`
|
mcpcat-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcpcat
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Analytics Tool for MCP Servers - provides insights into MCP tool usage patterns
|
|
5
|
+
Author-email: Your Name <your.email@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Requires-Dist: datafog>=4.1.1
|
|
16
|
+
Requires-Dist: mcp>=1.0.0
|
|
17
|
+
Requires-Dist: pydantic>=2.0.0
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
22
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# MCPCat Python SDK
|
|
26
|
+
|
|
27
|
+
Analytics tool for MCP (Model Context Protocol) servers that provides insights into tool usage patterns.
|
|
28
|
+
|
|
29
|
+
## Features
|
|
30
|
+
|
|
31
|
+
- **Tool Usage Analytics**: Tracks which tools are called and how frequently
|
|
32
|
+
- **Context Injection**: Adds context parameters to tools to understand user intent
|
|
33
|
+
- **Session Tracking**: Identifies and tracks user sessions
|
|
34
|
+
- **Report Missing Tools**: Allows clients to report when needed tools are missing
|
|
35
|
+
- **PII Redaction**: Automatically redacts sensitive information from logs
|
|
36
|
+
- **Non-invasive Integration**: Simple one-line integration with existing MCP servers
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install mcpcat
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from fastmcp import FastMCP
|
|
48
|
+
from mcpcat import track
|
|
49
|
+
|
|
50
|
+
# Create your MCP server
|
|
51
|
+
mcp = FastMCP("my-server")
|
|
52
|
+
|
|
53
|
+
# Add your tools
|
|
54
|
+
@mcp.tool()
|
|
55
|
+
def my_tool(arg: str) -> str:
|
|
56
|
+
return f"Result: {arg}"
|
|
57
|
+
|
|
58
|
+
# Enable MCPCat tracking
|
|
59
|
+
track(mcp)
|
|
60
|
+
|
|
61
|
+
# Run the server
|
|
62
|
+
mcp.run()
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
MCPCat can be configured with various options:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from mcpcat import track, MCPCatOptions
|
|
71
|
+
|
|
72
|
+
options = MCPCatOptions(
|
|
73
|
+
enableToolCallContext=True, # Add context parameters to tools
|
|
74
|
+
enableTracing=True, # Trace tool calls
|
|
75
|
+
enableReportMissing=True, # Add report_missing tool
|
|
76
|
+
identify=my_identify_func # Custom session identification
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
track(mcp, options)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## How It Works
|
|
83
|
+
|
|
84
|
+
1. MCPCat intercepts the MCP server's tool listing and calling mechanisms
|
|
85
|
+
2. It injects a `context` parameter into each tool's schema
|
|
86
|
+
3. When tools are called, it captures analytics data including timing, arguments, and results
|
|
87
|
+
4. The `report_missing` tool allows LLMs to report when they need functionality that isn't available
|
|
88
|
+
|
|
89
|
+
## Custom Session Identification
|
|
90
|
+
|
|
91
|
+
You can provide a custom function to identify users:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
def identify_user(request_context):
|
|
95
|
+
# Your logic to identify the user
|
|
96
|
+
return {
|
|
97
|
+
"sessionId": "session-123",
|
|
98
|
+
"userId": "user-456"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
options = MCPCatOptions(identify=identify_user)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Log Format
|
|
105
|
+
|
|
106
|
+
MCPCat logs are written in JSON format with the following structure:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"timestamp": "2024-01-20T10:30:00Z",
|
|
111
|
+
"event": "tool_call",
|
|
112
|
+
"tool_name": "my_tool",
|
|
113
|
+
"session_id": "session-123",
|
|
114
|
+
"user_id": "user-456",
|
|
115
|
+
"duration": 0.123,
|
|
116
|
+
"result": "success",
|
|
117
|
+
"context_provided": true
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Development
|
|
122
|
+
|
|
123
|
+
To set up for development:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Clone the repository
|
|
127
|
+
git clone https://github.com/yourusername/mcpcat-python-sdk.git
|
|
128
|
+
cd mcpcat-python-sdk
|
|
129
|
+
|
|
130
|
+
# Install dependencies
|
|
131
|
+
pip install -e ".[dev]"
|
|
132
|
+
|
|
133
|
+
# Run tests
|
|
134
|
+
pytest
|
|
135
|
+
|
|
136
|
+
# Run type checking
|
|
137
|
+
mypy src
|
|
138
|
+
|
|
139
|
+
# Run linting
|
|
140
|
+
ruff check src
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT
|