aixtools 0.1.0__tar.gz → 0.1.1__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.
Potentially problematic release.
This version of aixtools might be problematic. Click here for more details.
- aixtools-0.1.1/.env_template +42 -0
- aixtools-0.1.1/.github/workflows/build_and_publish_docker.yml +34 -0
- aixtools-0.1.1/.github/workflows/lint.yml +37 -0
- aixtools-0.1.1/.github/workflows/release.yml +37 -0
- aixtools-0.1.1/.gitignore +188 -0
- aixtools-0.1.1/.python-version +1 -0
- aixtools-0.1.1/.roo/rules/rules-mcp.md +170 -0
- aixtools-0.1.1/.roo/rules/rules.md +76 -0
- aixtools-0.1.1/.vscode/settings.json +8 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/PKG-INFO +1 -1
- aixtools-0.1.1/aixtools/.chainlit/config.toml +113 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/bn.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/en-US.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/gu.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/he-IL.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/hi.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/ja.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/kn.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/ml.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/mr.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/nl.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/ta.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/te.json +214 -0
- aixtools-0.1.1/aixtools/.chainlit/translations/zh-CN.json +214 -0
- aixtools-0.1.1/aixtools/__init__.py +11 -0
- aixtools-0.1.1/aixtools/_version.py +34 -0
- aixtools-0.1.1/aixtools/chainlit.md +14 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools.egg-info/PKG-INFO +1 -1
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools.egg-info/SOURCES.txt +38 -1
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools.egg-info/top_level.txt +0 -1
- aixtools-0.1.1/docker/mcp-base/Dockerfile +36 -0
- aixtools-0.1.1/notebooks/example_faulty_mcp_server.ipynb +74 -0
- aixtools-0.1.1/notebooks/example_mcp_server_stdio.ipynb +76 -0
- aixtools-0.1.1/notebooks/example_raw_mcp_client.ipynb +84 -0
- aixtools-0.1.1/notebooks/example_tool_doctor.ipynb +65 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/pyproject.toml +10 -8
- aixtools-0.1.1/scripts/config.sh +28 -0
- aixtools-0.1.1/scripts/lint.sh +32 -0
- aixtools-0.1.1/scripts/log_view.sh +18 -0
- aixtools-0.1.1/scripts/run_example_mcp_server.sh +14 -0
- aixtools-0.1.1/scripts/run_faulty_mcp_server.sh +13 -0
- aixtools-0.1.1/scripts/run_server.sh +29 -0
- aixtools-0.1.1/uv.lock +5163 -0
- aixtools-0.1.0/aixtools/__init__.py +0 -5
- {aixtools-0.1.0 → aixtools-0.1.1}/README.md +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/a2a/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/a2a/app.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/a2a/utils.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/agents/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/agents/agent.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/agents/agent_batch.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/app.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/context.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/db/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/db/database.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/db/vector_db.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/log_view/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/log_view/app.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/log_view/display.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/log_view/export.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/log_view/filters.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/log_view/log_utils.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/log_view/node_summary.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/logfilters/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/logfilters/context_filter.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/logging/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/logging/log_objects.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/logging/logging_config.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/logging/mcp_log_models.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/logging/mcp_logger.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/logging/model_patch_logging.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/logging/open_telemetry.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/mcp/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/mcp/example_client.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/mcp/example_server.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/mcp/fast_mcp_log.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/mcp/faulty_mcp.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/model_patch/model_patch.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/server/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/server/app_mounter.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/server/path.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/server/utils.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/testing/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/testing/aix_test_model.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/testing/mock_tool.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/testing/model_patch_cache.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/tools/doctor/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/tools/doctor/tool_doctor.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/tools/doctor/tool_recommendation.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/utils/__init__.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/utils/chainlit/cl_agent_show.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/utils/chainlit/cl_utils.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/utils/config.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/utils/config_util.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/utils/enum_with_description.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/utils/persisted_dict.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools/utils/utils.py +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools.egg-info/dependency_links.txt +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools.egg-info/entry_points.txt +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/aixtools.egg-info/requires.txt +0 -0
- {aixtools-0.1.0 → aixtools-0.1.1}/setup.cfg +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#-----------------------------------------------------------------------------
|
|
2
|
+
#
|
|
3
|
+
# Template for .env file
|
|
4
|
+
#
|
|
5
|
+
#-----------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
MODEL_FAMILY=azure
|
|
9
|
+
VDB_EMBEDDINGS_MODEL_FAMILY=azure
|
|
10
|
+
|
|
11
|
+
MODEL_TIMEOUT=120
|
|
12
|
+
|
|
13
|
+
# Azure OpenAI
|
|
14
|
+
AZURE_OPENAI_ENDPOINT=https://your_endpoint.openai.azure.com
|
|
15
|
+
AZURE_OPENAI_API_VERSION=2024-06-01
|
|
16
|
+
AZURE_OPENAI_API_KEY=your_secret_key
|
|
17
|
+
AZURE_MODEL_NAME=gpt-4o
|
|
18
|
+
AZURE_OPENAI_PROVIDER_ID=azure
|
|
19
|
+
AZURE_VDB_EMBEDDINGS_MODEL_NAME=text-embedding-3-small
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Open AI
|
|
23
|
+
OPENAI_MODEL_NAME=gpt-4.5-preview
|
|
24
|
+
OPENAI_API_KEY=openai_api_key
|
|
25
|
+
OPENAI_VDB_EMBEDDINGS_MODEL_NAME=text-embedding-3-small
|
|
26
|
+
|
|
27
|
+
# Ollama models
|
|
28
|
+
OLLAMA_MODEL_NAME=llama3.2:3b-instruct-fp16
|
|
29
|
+
OLLAMA_LOCAL_URL=http://localhost:11434/v1
|
|
30
|
+
OLLAMA_VDB_EMBEDDINGS_MODEL_NAME=snowflake-arctic-embed2:latest
|
|
31
|
+
|
|
32
|
+
# Docker and CI/CD Configuration (optional)
|
|
33
|
+
# These variables are used for Docker builds and GitHub workflows
|
|
34
|
+
DOCKER_WORKFLOW_REPO=your-org/your-reusable-workflows
|
|
35
|
+
DOCKER_REPO_NAME=your-docker-repo
|
|
36
|
+
DOCKER_REPO_PATH=your-path
|
|
37
|
+
DOCKER_REGISTRY=your-registry.com:443
|
|
38
|
+
DOCKER_ARTIFACTORY_USERNAME=your_username
|
|
39
|
+
# DOCKER_ARTIFACTORY_API_KEY should be set as a GitHub secret
|
|
40
|
+
|
|
41
|
+
# Custom certificate for Docker builds (optional)
|
|
42
|
+
# CUSTOM_CERT_FILE=/path/to/your/certificate.crt
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Build and Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build-and-publish-docker-images:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- name: build and publish
|
|
12
|
+
uses: ${{ vars.DOCKER_WORKFLOW_REPO }}/.github/workflows/publish_docker_artifactory.yml@main
|
|
13
|
+
with:
|
|
14
|
+
REPO_NAME: ${{ vars.DOCKER_REPO_NAME }}
|
|
15
|
+
REPO_PATH: ${{ vars.DOCKER_REPO_PATH }}
|
|
16
|
+
IMAGE_NAME: mcp-base
|
|
17
|
+
DOCKER_TAG: ${{ github.sha }}
|
|
18
|
+
CONTEXT: docker/mcp-base
|
|
19
|
+
# secrets:
|
|
20
|
+
DOS_ARTIFACTORY_USERNAME: ${{ vars.DOCKER_ARTIFACTORY_USERNAME }}
|
|
21
|
+
DOS_ARTIFACTORY_API_KEY: ${{ secrets.DOCKER_ARTIFACTORY_API_KEY }}
|
|
22
|
+
- name: test docker interaction
|
|
23
|
+
run: |
|
|
24
|
+
echo "Testing Docker interaction..."
|
|
25
|
+
docker --version
|
|
26
|
+
docker images
|
|
27
|
+
docker rm ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_REPO_PATH }}/mcp-base:${{ github.sha }} || true
|
|
28
|
+
docker images
|
|
29
|
+
docker pull ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_REPO_PATH }}/mcp-base:${{ github.sha }} || true
|
|
30
|
+
docker images
|
|
31
|
+
echo "Docker interaction test completed."
|
|
32
|
+
env:
|
|
33
|
+
DOCKER_BUILDKIT: 1
|
|
34
|
+
DOCKER_CLI_EXPERIMENTAL: enabled
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Lint and Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint-and-test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout code
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up Python 3.12
|
|
18
|
+
uses: actions/setup-python@v4
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
|
|
22
|
+
- name: Install uv
|
|
23
|
+
run: |
|
|
24
|
+
pip install uv
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: |
|
|
28
|
+
uv sync
|
|
29
|
+
uv pip install -e ".[feature]"
|
|
30
|
+
|
|
31
|
+
- name: Set up environment
|
|
32
|
+
run: |
|
|
33
|
+
touch .env
|
|
34
|
+
|
|
35
|
+
- name: Run linting
|
|
36
|
+
run: |
|
|
37
|
+
./scripts/lint.sh
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch: # Temporarily allow manual triggering
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build-and-publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: release
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout code
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0 # Fetch full history for setuptools_scm
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v4
|
|
21
|
+
|
|
22
|
+
- name: Install build dependencies
|
|
23
|
+
run: uv sync --group dev
|
|
24
|
+
|
|
25
|
+
- name: Build package
|
|
26
|
+
run: uv run python -m build
|
|
27
|
+
|
|
28
|
+
- name: Check package contents
|
|
29
|
+
run: |
|
|
30
|
+
ls -la dist/
|
|
31
|
+
uv run python -m twine check dist/*
|
|
32
|
+
|
|
33
|
+
- name: Publish to PyPI
|
|
34
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
35
|
+
with:
|
|
36
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
37
|
+
skip-existing: true
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
.DS_Store
|
|
6
|
+
agents/.DS_Store
|
|
7
|
+
|
|
8
|
+
# C extensions
|
|
9
|
+
*.so
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
.Python
|
|
13
|
+
build/
|
|
14
|
+
develop-eggs/
|
|
15
|
+
dist/
|
|
16
|
+
downloads/
|
|
17
|
+
eggs/
|
|
18
|
+
.eggs/
|
|
19
|
+
lib/
|
|
20
|
+
lib64/
|
|
21
|
+
parts/
|
|
22
|
+
sdist/
|
|
23
|
+
var/
|
|
24
|
+
wheels/
|
|
25
|
+
share/python-wheels/
|
|
26
|
+
*.egg-info/
|
|
27
|
+
.installed.cfg
|
|
28
|
+
*.egg
|
|
29
|
+
MANIFEST
|
|
30
|
+
|
|
31
|
+
# PyInstaller
|
|
32
|
+
# Usually these files are written by a python script from a template
|
|
33
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
34
|
+
*.manifest
|
|
35
|
+
*.spec
|
|
36
|
+
|
|
37
|
+
# Installer logs
|
|
38
|
+
pip-log.txt
|
|
39
|
+
pip-delete-this-directory.txt
|
|
40
|
+
|
|
41
|
+
# Unit test / coverage reports
|
|
42
|
+
htmlcov/
|
|
43
|
+
.tox/
|
|
44
|
+
.nox/
|
|
45
|
+
.coverage
|
|
46
|
+
.coverage.*
|
|
47
|
+
.cache
|
|
48
|
+
nosetests.xml
|
|
49
|
+
coverage.xml
|
|
50
|
+
*.cover
|
|
51
|
+
*.py,cover
|
|
52
|
+
.hypothesis/
|
|
53
|
+
.pytest_cache/
|
|
54
|
+
cover/
|
|
55
|
+
|
|
56
|
+
# Translations
|
|
57
|
+
*.mo
|
|
58
|
+
*.pot
|
|
59
|
+
|
|
60
|
+
# Django stuff:
|
|
61
|
+
*.log
|
|
62
|
+
local_settings.py
|
|
63
|
+
db.sqlite3
|
|
64
|
+
db.sqlite3-journal
|
|
65
|
+
|
|
66
|
+
# Flask stuff:
|
|
67
|
+
instance/
|
|
68
|
+
.webassets-cache
|
|
69
|
+
|
|
70
|
+
# Scrapy stuff:
|
|
71
|
+
.scrapy
|
|
72
|
+
|
|
73
|
+
# Sphinx documentation
|
|
74
|
+
docs/_build/
|
|
75
|
+
|
|
76
|
+
# PyBuilder
|
|
77
|
+
.pybuilder/
|
|
78
|
+
target/
|
|
79
|
+
|
|
80
|
+
# Jupyter Notebook
|
|
81
|
+
.ipynb_checkpoints
|
|
82
|
+
|
|
83
|
+
# IPython
|
|
84
|
+
profile_default/
|
|
85
|
+
ipython_config.py
|
|
86
|
+
|
|
87
|
+
# pyenv
|
|
88
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
89
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
90
|
+
# .python-version
|
|
91
|
+
|
|
92
|
+
# pipenv
|
|
93
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
94
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
95
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
96
|
+
# install all needed dependencies.
|
|
97
|
+
#Pipfile.lock
|
|
98
|
+
|
|
99
|
+
# UV
|
|
100
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
101
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
102
|
+
# commonly ignored for libraries.
|
|
103
|
+
#uv.lock
|
|
104
|
+
|
|
105
|
+
# poetry
|
|
106
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
107
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
108
|
+
# commonly ignored for libraries.
|
|
109
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
110
|
+
#poetry.lock
|
|
111
|
+
|
|
112
|
+
# pdm
|
|
113
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
114
|
+
#pdm.lock
|
|
115
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
116
|
+
# in version control.
|
|
117
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
118
|
+
.pdm.toml
|
|
119
|
+
.pdm-python
|
|
120
|
+
.pdm-build/
|
|
121
|
+
|
|
122
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
123
|
+
__pypackages__/
|
|
124
|
+
|
|
125
|
+
# Celery stuff
|
|
126
|
+
celerybeat-schedule
|
|
127
|
+
celerybeat.pid
|
|
128
|
+
|
|
129
|
+
# SageMath parsed files
|
|
130
|
+
*.sage.py
|
|
131
|
+
|
|
132
|
+
# Environments
|
|
133
|
+
.env
|
|
134
|
+
.venv
|
|
135
|
+
env/
|
|
136
|
+
venv/
|
|
137
|
+
ENV/
|
|
138
|
+
env.bak/
|
|
139
|
+
venv.bak/
|
|
140
|
+
|
|
141
|
+
# Spyder project settings
|
|
142
|
+
.spyderproject
|
|
143
|
+
.spyproject
|
|
144
|
+
|
|
145
|
+
# Rope project settings
|
|
146
|
+
.ropeproject
|
|
147
|
+
|
|
148
|
+
# mkdocs documentation
|
|
149
|
+
/site
|
|
150
|
+
|
|
151
|
+
# mypy
|
|
152
|
+
.mypy_cache/
|
|
153
|
+
.dmypy.json
|
|
154
|
+
dmypy.json
|
|
155
|
+
|
|
156
|
+
# Pyre type checker
|
|
157
|
+
.pyre/
|
|
158
|
+
|
|
159
|
+
# pytype static type analyzer
|
|
160
|
+
.pytype/
|
|
161
|
+
|
|
162
|
+
# Cython debug symbols
|
|
163
|
+
cython_debug/
|
|
164
|
+
|
|
165
|
+
# PyCharm
|
|
166
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
167
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
168
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
169
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
170
|
+
#.idea/
|
|
171
|
+
|
|
172
|
+
#IDEs
|
|
173
|
+
.idea/
|
|
174
|
+
|
|
175
|
+
# Ruff stuff:
|
|
176
|
+
.ruff_cache/
|
|
177
|
+
|
|
178
|
+
# PyPI configuration file
|
|
179
|
+
.pypirc
|
|
180
|
+
|
|
181
|
+
# Chainlit stuff
|
|
182
|
+
.files/
|
|
183
|
+
|
|
184
|
+
# Data directories
|
|
185
|
+
data/
|
|
186
|
+
aixtools/data/
|
|
187
|
+
logs/
|
|
188
|
+
aixtools/_version.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12.2
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# FastMCP Server Guidelines
|
|
2
|
+
|
|
3
|
+
These are the core conventions and patterns you should follow when building Python MCP servers with FastMCP.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Server Initialization
|
|
8
|
+
|
|
9
|
+
References: [FastMCP Servers docs](https://gofastmcp.com/servers/fastmcp#initialization), [GitHub examples](https://github.com/jlowin/fastmcp/blob/main/examples/readme-quickstart.py)
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from fastmcp import FastMCP
|
|
13
|
+
|
|
14
|
+
mcp = FastMCP(
|
|
15
|
+
name="MyServer", # Optional (recommended): human-readable identifier
|
|
16
|
+
instructions="Describe usage...", # Optional (recommended): high‑level guidance for clients
|
|
17
|
+
lifespan=startup_shutdown_mgr, # optional async context manager
|
|
18
|
+
tags={"analytics", "beta"} # optional server tags
|
|
19
|
+
)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. Core Components
|
|
25
|
+
|
|
26
|
+
References: [FastMCP Servers docs](https://gofastmcp.com/servers/fastmcp#components), [GitHub examples](https://github.com/jlowin/fastmcp/blob/main/examples/readme-quickstart.py)
|
|
27
|
+
|
|
28
|
+
1. **Tools**: functions clients invoke
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
@mcp.tool()
|
|
32
|
+
def multiply(a: float, b: float) -> float:
|
|
33
|
+
"""Multiply two numbers."""
|
|
34
|
+
return a * b
|
|
35
|
+
```
|
|
36
|
+
2. **Resources**: read‑only data endpoints
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
@mcp.resource("config://settings")
|
|
40
|
+
def get_settings() -> dict:
|
|
41
|
+
return {"mode": "prod"}
|
|
42
|
+
```
|
|
43
|
+
3. **Resource Templates**: parameterized URIs
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
@mcp.resource("users://{user_id}/profile")
|
|
47
|
+
def user_profile(user_id: int) -> dict:
|
|
48
|
+
return {"id": user_id}
|
|
49
|
+
```
|
|
50
|
+
4. **Prompts**: reusable LLM message builders
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
@mcp.prompt()
|
|
54
|
+
def summarize(text: str) -> str:
|
|
55
|
+
return f"Summarize:\n\n{text}"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 3. Running & Transport
|
|
61
|
+
|
|
62
|
+
References: [FastMCP Servers docs](https://gofastmcp.com/servers/fastmcp#running), [GitHub examples](https://github.com/jlowin/fastmcp/blob/main/examples/streaming.py)
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
if __name__ == "__main__":
|
|
66
|
+
# STDIO (We use this for mostly for easy debugging)
|
|
67
|
+
# mcp.run()
|
|
68
|
+
|
|
69
|
+
# Streamable HTTP
|
|
70
|
+
mcp.run(transport="streamable-http", host="127.0.0.1", port=9000)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 4. Error Handling
|
|
76
|
+
|
|
77
|
+
References: [FastMCP Servers docs](https://gofastmcp.com/servers/fastmcp#error-handling)
|
|
78
|
+
|
|
79
|
+
* **Catch and wrap** exceptions within tools; raise clear, user‑friendly errors instead of raw tracebacks.
|
|
80
|
+
* **Log failures** (timeouts, validation, security) at WARN/ERROR level for diagnostics.
|
|
81
|
+
* **Handle external calls** safely:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
@mcp.tool()
|
|
85
|
+
def fetch_data(url: str) -> dict:
|
|
86
|
+
try:
|
|
87
|
+
return httpx.get(url, timeout=5.0).json()
|
|
88
|
+
except httpx.TimeoutException:
|
|
89
|
+
raise RuntimeError("Upstream timed out—please try again later.")
|
|
90
|
+
except Exception as e:
|
|
91
|
+
mcp.log.error("fetch_data failed", exc_info=e)
|
|
92
|
+
raise
|
|
93
|
+
```
|
|
94
|
+
* **Structured error payloads**: FastMCP marks `isError=true` and includes your message rather than crashing.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 5. Composing & Mounting
|
|
99
|
+
|
|
100
|
+
References: [FastMCP Servers docs](https://gofastmcp.com/servers/fastmcp#composition), [GitHub examples](https://github.com/jlowin/fastmcp/blob/main/examples/mount_example.py)
|
|
101
|
+
|
|
102
|
+
You can split large apps into modular servers and link them:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from fastmcp import FastMCP
|
|
106
|
+
|
|
107
|
+
main = FastMCP(name="Main")
|
|
108
|
+
sub = FastMCP(name="Sub")
|
|
109
|
+
|
|
110
|
+
@sub.tool()
|
|
111
|
+
def hello() -> str:
|
|
112
|
+
return "hi"
|
|
113
|
+
|
|
114
|
+
# Live mount: updates in `sub` appear immediately in `main`
|
|
115
|
+
main.mount("sub", sub)
|
|
116
|
+
|
|
117
|
+
# Static import: snapshot of `sub` is copied into `main`
|
|
118
|
+
main.import_server("sub", sub)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 6. Returning Images
|
|
124
|
+
|
|
125
|
+
References: [FastMCP Servers docs](https://gofastmcp.com/servers/fastmcp#images), [GitHub examples](https://github.com/jlowin/fastmcp/blob/main/examples/image_tool.py)
|
|
126
|
+
|
|
127
|
+
FastMCP provides first‑class support for image content via its `Image` helper class and by returning raw bytes with an explicit MIME type.
|
|
128
|
+
|
|
129
|
+
### As a Tool
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from fastmcp import FastMCP, Image
|
|
133
|
+
from PIL import Image as PILImage
|
|
134
|
+
import io
|
|
135
|
+
|
|
136
|
+
mcp = FastMCP("ImageDemo")
|
|
137
|
+
|
|
138
|
+
@mcp.tool()
|
|
139
|
+
def generate_image(width: int, height: int, color: str) -> Image:
|
|
140
|
+
"""Generate a solid‑color PNG image."""
|
|
141
|
+
img = PILImage.new("RGB", (width, height), color=color)
|
|
142
|
+
buf = io.BytesIO()
|
|
143
|
+
img.save(buf, format="PNG")
|
|
144
|
+
return Image(data=buf.getvalue(), format="png")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### As a Resource
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
@mcp.resource(
|
|
151
|
+
uri="images://logo",
|
|
152
|
+
mime_type="image/png"
|
|
153
|
+
)
|
|
154
|
+
def get_logo() -> bytes:
|
|
155
|
+
"""Serve the company logo as PNG bytes."""
|
|
156
|
+
with open("assets/logo.png", "rb") as f:
|
|
157
|
+
return f.read()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 7. Basic Data Structures & Classes
|
|
163
|
+
|
|
164
|
+
References: [FastMCP SDK source](https://github.com/jlowin/fastmcp/tree/main/fastmcp) for reference
|
|
165
|
+
|
|
166
|
+
* **`FastMCP`**: core server container
|
|
167
|
+
* **`ToolDefinition`**, **`ResourceDefinition`**, **`PromptDefinition`**: internal metadata
|
|
168
|
+
* **`Context`**: passed into async tools for logging, progress, sampling, and resource reads
|
|
169
|
+
* **`Image`**: helper class to wrap image bytes for clients
|
|
170
|
+
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
### Architecture
|
|
2
|
+
|
|
3
|
+
- You MUST NOT over-engineer
|
|
4
|
+
- Always prefer simplicity and direct approaches, instead of unnecessary abstractions.
|
|
5
|
+
|
|
6
|
+
### Documentation
|
|
7
|
+
|
|
8
|
+
- There SHOULD be a `README.md` with the typical sections.
|
|
9
|
+
- The files `PROMPT_*.md` have the prompts for LLMs. You MUST NOT read or edit this file
|
|
10
|
+
- Design documents MUST be saved as markdown in `docs/design`
|
|
11
|
+
- Documentation SHOULD be simple and to the point. Do not write unnecessary explanations or diagrams.
|
|
12
|
+
- When describing, avoid bullet points
|
|
13
|
+
- Use diagrams only when necessary to clarify. Do not draw mermaid diagrams if you have two classes.
|
|
14
|
+
- Do not write a "File Structure" section
|
|
15
|
+
|
|
16
|
+
### Python code style
|
|
17
|
+
|
|
18
|
+
- Type hints:
|
|
19
|
+
- you MUST use type hints in functions and methods signatures
|
|
20
|
+
- you MUST use new way of defining types; e.g. " `dict`, `list`, `| None`, `any`, instead of the old `from typing import Dict, Optional, Any`
|
|
21
|
+
- Docstrings: SHOULD be short but informative. Multi-line comments just saying the same as the signature are not useful
|
|
22
|
+
- Files operations MUST use pathlib's `Path` instead of `str` / `import os`
|
|
23
|
+
- Classes for data: You SHOULD use Pydantic classes or dataclasses instead of `dict` structures, or "record classes" (a class that only has fields and no functionality).
|
|
24
|
+
- Enums: Do not hard-code string values, use `Enum` objects, e.g. `MyEnum(str, Enum)` for better serialization
|
|
25
|
+
- Code line length: The lines SHOULD be coded for modern monitors (not 80 character terminals from 1960). Don't spread one statement to multiple lines unless really necessary for clarity.
|
|
26
|
+
- Code lint:
|
|
27
|
+
- The effective line length for is infinite
|
|
28
|
+
- You SHOULD remove unused imports
|
|
29
|
+
- Functions and methods SHOULD be sorted alphabetically (except underscores)
|
|
30
|
+
- Code files:
|
|
31
|
+
- SHOULD not exceed 500 lines. Refactor code if it's too long.
|
|
32
|
+
- Write classes (and enums) into their own files whenever possible.
|
|
33
|
+
- DRY: Do not repeat yourself
|
|
34
|
+
- Consider `match / case` instead of multiple `elif` statements
|
|
35
|
+
- `config.py`: Config variables
|
|
36
|
+
- You SHOULD store configuration variables and defaults in a file called `config.py`.
|
|
37
|
+
- Also read the variables from `.env`.
|
|
38
|
+
- Simple values should be just be set (not configured).
|
|
39
|
+
- You SHOULD NOT create functions in `config.py`
|
|
40
|
+
- `__str__()`: Classes SHOULD be "printable" so they are easier to understand when developing and debugging
|
|
41
|
+
- `__init__.py`: Don't write unnecessary comments, versions, etc. in `__init__` files. If an empty one can do the trick, that's fine.
|
|
42
|
+
|
|
43
|
+
### Utility scripts
|
|
44
|
+
|
|
45
|
+
You SHOULD create scripts to:
|
|
46
|
+
|
|
47
|
+
- `scripts/config.sh`: Set `PROJECT_DIR` and other project variables (re-export them). Read `.env`, activate virtual environment. All other scripts source `config.sh` to avoid duplicating the same code in every script.
|
|
48
|
+
- `scripts/run.sh`: To run the program (particularly if it's a server)
|
|
49
|
+
- `scripts/lint.sh`: To run linter
|
|
50
|
+
- `scripts/test.sh`: To execute all test cases
|
|
51
|
+
- Not having an `.env` or a `.venv` is an error, they are not optional.
|
|
52
|
+
- When creating scripts follow the "no news is good news" principle, i.e. no unnecessary `echo` commands
|
|
53
|
+
|
|
54
|
+
### Python packages
|
|
55
|
+
|
|
56
|
+
- Use `uv` instead of `pip`
|
|
57
|
+
- Use `ruff` instead of `black`
|
|
58
|
+
|
|
59
|
+
### Python testing rules
|
|
60
|
+
|
|
61
|
+
- You SHOULD use Python's unit test instead of `pytest`
|
|
62
|
+
- You SHOULD Put all test files in a `tests` directory
|
|
63
|
+
- You MUST create a `scripts/test.sh` to run all test cases.
|
|
64
|
+
- `scripts/test_unit.sh` to run all unit test cases
|
|
65
|
+
- `scripts/test_integration.sh` to run all integration cases (if any)
|
|
66
|
+
- Any data necessary for testing MUST be in `tests/data`
|
|
67
|
+
|
|
68
|
+
- For "simple examples" you MAY use Jupyter notebooks rather than isolated scripts
|
|
69
|
+
|
|
70
|
+
### Bash
|
|
71
|
+
|
|
72
|
+
- You MUST start shell script with these two lines:
|
|
73
|
+
```
|
|
74
|
+
#!/bin/bash -eu
|
|
75
|
+
set -o pipefail
|
|
76
|
+
```
|