aixtools 0.1.0__tar.gz → 0.1.2__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.

Files changed (101) hide show
  1. aixtools-0.1.2/.env_template +42 -0
  2. aixtools-0.1.2/.github/workflows/build_and_publish_docker.yml +34 -0
  3. aixtools-0.1.2/.github/workflows/lint.yml +37 -0
  4. aixtools-0.1.2/.github/workflows/release.yml +36 -0
  5. aixtools-0.1.2/.gitignore +188 -0
  6. aixtools-0.1.2/.python-version +1 -0
  7. aixtools-0.1.2/.roo/rules/rules-mcp.md +170 -0
  8. aixtools-0.1.2/.roo/rules/rules.md +76 -0
  9. aixtools-0.1.2/.vscode/settings.json +8 -0
  10. {aixtools-0.1.0 → aixtools-0.1.2}/PKG-INFO +1 -1
  11. aixtools-0.1.2/aixtools/.chainlit/config.toml +113 -0
  12. aixtools-0.1.2/aixtools/.chainlit/translations/bn.json +214 -0
  13. aixtools-0.1.2/aixtools/.chainlit/translations/en-US.json +214 -0
  14. aixtools-0.1.2/aixtools/.chainlit/translations/gu.json +214 -0
  15. aixtools-0.1.2/aixtools/.chainlit/translations/he-IL.json +214 -0
  16. aixtools-0.1.2/aixtools/.chainlit/translations/hi.json +214 -0
  17. aixtools-0.1.2/aixtools/.chainlit/translations/ja.json +214 -0
  18. aixtools-0.1.2/aixtools/.chainlit/translations/kn.json +214 -0
  19. aixtools-0.1.2/aixtools/.chainlit/translations/ml.json +214 -0
  20. aixtools-0.1.2/aixtools/.chainlit/translations/mr.json +214 -0
  21. aixtools-0.1.2/aixtools/.chainlit/translations/nl.json +214 -0
  22. aixtools-0.1.2/aixtools/.chainlit/translations/ta.json +214 -0
  23. aixtools-0.1.2/aixtools/.chainlit/translations/te.json +214 -0
  24. aixtools-0.1.2/aixtools/.chainlit/translations/zh-CN.json +214 -0
  25. aixtools-0.1.2/aixtools/__init__.py +11 -0
  26. aixtools-0.1.2/aixtools/_version.py +34 -0
  27. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/agents/agent_batch.py +2 -5
  28. aixtools-0.1.2/aixtools/chainlit.md +14 -0
  29. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/mcp/faulty_mcp.py +30 -30
  30. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/model_patch/model_patch.py +3 -5
  31. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools.egg-info/PKG-INFO +1 -1
  32. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools.egg-info/SOURCES.txt +38 -1
  33. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools.egg-info/top_level.txt +0 -1
  34. aixtools-0.1.2/docker/mcp-base/Dockerfile +36 -0
  35. aixtools-0.1.2/notebooks/example_faulty_mcp_server.ipynb +74 -0
  36. aixtools-0.1.2/notebooks/example_mcp_server_stdio.ipynb +76 -0
  37. aixtools-0.1.2/notebooks/example_raw_mcp_client.ipynb +84 -0
  38. aixtools-0.1.2/notebooks/example_tool_doctor.ipynb +65 -0
  39. {aixtools-0.1.0 → aixtools-0.1.2}/pyproject.toml +10 -8
  40. aixtools-0.1.2/scripts/config.sh +28 -0
  41. aixtools-0.1.2/scripts/lint.sh +32 -0
  42. aixtools-0.1.2/scripts/log_view.sh +18 -0
  43. aixtools-0.1.2/scripts/run_example_mcp_server.sh +14 -0
  44. aixtools-0.1.2/scripts/run_faulty_mcp_server.sh +13 -0
  45. aixtools-0.1.2/scripts/run_server.sh +29 -0
  46. aixtools-0.1.2/uv.lock +5163 -0
  47. aixtools-0.1.0/aixtools/__init__.py +0 -5
  48. {aixtools-0.1.0 → aixtools-0.1.2}/README.md +0 -0
  49. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/a2a/__init__.py +0 -0
  50. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/a2a/app.py +0 -0
  51. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/a2a/utils.py +0 -0
  52. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/agents/__init__.py +0 -0
  53. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/agents/agent.py +0 -0
  54. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/app.py +0 -0
  55. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/context.py +0 -0
  56. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/db/__init__.py +0 -0
  57. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/db/database.py +0 -0
  58. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/db/vector_db.py +0 -0
  59. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/log_view/__init__.py +0 -0
  60. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/log_view/app.py +0 -0
  61. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/log_view/display.py +0 -0
  62. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/log_view/export.py +0 -0
  63. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/log_view/filters.py +0 -0
  64. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/log_view/log_utils.py +0 -0
  65. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/log_view/node_summary.py +0 -0
  66. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/logfilters/__init__.py +0 -0
  67. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/logfilters/context_filter.py +0 -0
  68. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/logging/__init__.py +0 -0
  69. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/logging/log_objects.py +0 -0
  70. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/logging/logging_config.py +0 -0
  71. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/logging/mcp_log_models.py +0 -0
  72. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/logging/mcp_logger.py +0 -0
  73. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/logging/model_patch_logging.py +0 -0
  74. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/logging/open_telemetry.py +0 -0
  75. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/mcp/__init__.py +0 -0
  76. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/mcp/example_client.py +0 -0
  77. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/mcp/example_server.py +0 -0
  78. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/mcp/fast_mcp_log.py +0 -0
  79. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/server/__init__.py +0 -0
  80. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/server/app_mounter.py +0 -0
  81. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/server/path.py +0 -0
  82. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/server/utils.py +0 -0
  83. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/testing/__init__.py +0 -0
  84. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/testing/aix_test_model.py +0 -0
  85. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/testing/mock_tool.py +0 -0
  86. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/testing/model_patch_cache.py +0 -0
  87. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/tools/doctor/__init__.py +0 -0
  88. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/tools/doctor/tool_doctor.py +0 -0
  89. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/tools/doctor/tool_recommendation.py +0 -0
  90. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/utils/__init__.py +0 -0
  91. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/utils/chainlit/cl_agent_show.py +0 -0
  92. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/utils/chainlit/cl_utils.py +0 -0
  93. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/utils/config.py +0 -0
  94. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/utils/config_util.py +0 -0
  95. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/utils/enum_with_description.py +0 -0
  96. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/utils/persisted_dict.py +0 -0
  97. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools/utils/utils.py +0 -0
  98. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools.egg-info/dependency_links.txt +0 -0
  99. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools.egg-info/entry_points.txt +0 -0
  100. {aixtools-0.1.0 → aixtools-0.1.2}/aixtools.egg-info/requires.txt +0 -0
  101. {aixtools-0.1.0 → aixtools-0.1.2}/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,36 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build-and-publish:
9
+ runs-on: ubuntu-latest
10
+ environment: release
11
+
12
+ steps:
13
+ - name: Checkout code
14
+ uses: actions/checkout@v4
15
+ with:
16
+ fetch-depth: 0 # Fetch full history for setuptools_scm
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v4
20
+
21
+ - name: Install build dependencies
22
+ run: uv sync --group dev
23
+
24
+ - name: Build package
25
+ run: uv run python -m build
26
+
27
+ - name: Check package contents
28
+ run: |
29
+ ls -la dist/
30
+ uv run python -m twine check dist/*
31
+
32
+ - name: Publish to PyPI
33
+ uses: pypa/gh-action-pypi-publish@release/v1
34
+ with:
35
+ password: ${{ secrets.PYPI_API_TOKEN }}
36
+ 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
+ ```
@@ -0,0 +1,8 @@
1
+ {
2
+ "[python]": {
3
+ "editor.formatOnType": true,
4
+ "editor.defaultFormatter": "charliermarsh.ruff",
5
+ },
6
+ "python.testing.pytestEnabled": false,
7
+ "python.testing.unittestEnabled": false,
8
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aixtools
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Tools for AI exploration and debugging
5
5
  Requires-Python: >=3.11.2
6
6
  Description-Content-Type: text/markdown