mcp-instana 0.1.0__tar.gz → 0.2.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.
Files changed (149) hide show
  1. mcp_instana-0.2.0/.bob/mcp.json +3 -0
  2. mcp_instana-0.2.0/.github/dco.yml +4 -0
  3. mcp_instana-0.2.0/.github/workflows/ci.yml +127 -0
  4. mcp_instana-0.2.0/.gitignore +180 -0
  5. mcp_instana-0.2.0/CONTRIBUTING.md +198 -0
  6. mcp_instana-0.2.0/Dockerfile +60 -0
  7. mcp_instana-0.1.0/LICENSE → mcp_instana-0.2.0/LICENSE.md +3 -3
  8. mcp_instana-0.2.0/PKG-INFO +1229 -0
  9. mcp_instana-0.2.0/README.md +1206 -0
  10. mcp_instana-0.2.0/images/architecture.png +0 -0
  11. mcp_instana-0.2.0/images/call_tools.png +0 -0
  12. mcp_instana-0.2.0/images/claudeResponse.png +0 -0
  13. mcp_instana-0.2.0/images/claudeTools.png +0 -0
  14. mcp_instana-0.2.0/images/copilot.png +0 -0
  15. mcp_instana-0.2.0/images/copilotResponse.png +0 -0
  16. mcp_instana-0.2.0/images/kubernetesEvents.png +0 -0
  17. mcp_instana-0.2.0/images/mcpInstanaFlow.png +0 -0
  18. mcp_instana-0.2.0/images/query_events.png +0 -0
  19. mcp_instana-0.2.0/pyproject-runtime.toml +62 -0
  20. mcp_instana-0.2.0/pyproject.toml +140 -0
  21. mcp_instana-0.2.0/pyrightconfig.json +36 -0
  22. mcp_instana-0.2.0/run_ruff_check.sh +42 -0
  23. mcp_instana-0.2.0/src/application/__init__.py +1 -0
  24. mcp_instana-0.1.0/src/client/application_alert_config_mcp_tools.py → mcp_instana-0.2.0/src/application/application_alert_config.py +251 -273
  25. mcp_instana-0.2.0/src/application/application_analyze.py +628 -0
  26. mcp_instana-0.2.0/src/application/application_catalog.py +155 -0
  27. mcp_instana-0.2.0/src/application/application_global_alert_config.py +653 -0
  28. mcp_instana-0.1.0/src/client/application_metrics_mcp_tools.py → mcp_instana-0.2.0/src/application/application_metrics.py +113 -131
  29. mcp_instana-0.1.0/src/client/application_resources_mcp_tools.py → mcp_instana-0.2.0/src/application/application_resources.py +131 -151
  30. mcp_instana-0.2.0/src/application/application_settings.py +1731 -0
  31. mcp_instana-0.2.0/src/application/application_topology.py +111 -0
  32. mcp_instana-0.2.0/src/automation/action_catalog.py +416 -0
  33. mcp_instana-0.2.0/src/automation/action_history.py +338 -0
  34. mcp_instana-0.2.0/src/core/__init__.py +1 -0
  35. mcp_instana-0.2.0/src/core/server.py +586 -0
  36. mcp_instana-0.2.0/src/core/utils.py +213 -0
  37. mcp_instana-0.2.0/src/event/__init__.py +1 -0
  38. mcp_instana-0.2.0/src/event/events_tools.py +850 -0
  39. mcp_instana-0.2.0/src/infrastructure/__init__.py +1 -0
  40. mcp_instana-0.1.0/src/client/infrastructure_analyze_mcp_tools.py → mcp_instana-0.2.0/src/infrastructure/infrastructure_analyze.py +207 -206
  41. mcp_instana-0.1.0/src/client/infrastructure_catalog_mcp_tools.py → mcp_instana-0.2.0/src/infrastructure/infrastructure_catalog.py +197 -265
  42. mcp_instana-0.2.0/src/infrastructure/infrastructure_metrics.py +171 -0
  43. mcp_instana-0.1.0/src/client/infrastructure_resources_mcp_tools.py → mcp_instana-0.2.0/src/infrastructure/infrastructure_resources.py +198 -227
  44. mcp_instana-0.1.0/src/client/infrastructure_topology_mcp_tools.py → mcp_instana-0.2.0/src/infrastructure/infrastructure_topology.py +110 -109
  45. mcp_instana-0.2.0/src/log/__init__.py +1 -0
  46. mcp_instana-0.2.0/src/log/log_alert_configuration.py +331 -0
  47. mcp_instana-0.2.0/src/prompts/__init__.py +16 -0
  48. mcp_instana-0.2.0/src/prompts/application/__init__.py +1 -0
  49. mcp_instana-0.2.0/src/prompts/application/application_alerts.py +54 -0
  50. mcp_instana-0.2.0/src/prompts/application/application_catalog.py +26 -0
  51. mcp_instana-0.2.0/src/prompts/application/application_metrics.py +57 -0
  52. mcp_instana-0.2.0/src/prompts/application/application_resources.py +26 -0
  53. mcp_instana-0.2.0/src/prompts/application/application_settings.py +75 -0
  54. mcp_instana-0.2.0/src/prompts/application/application_topology.py +30 -0
  55. mcp_instana-0.2.0/src/prompts/events/__init__.py +1 -0
  56. mcp_instana-0.2.0/src/prompts/events/events_tools.py +161 -0
  57. mcp_instana-0.2.0/src/prompts/infrastructure/infrastructure_analyze.py +72 -0
  58. mcp_instana-0.2.0/src/prompts/infrastructure/infrastructure_catalog.py +53 -0
  59. mcp_instana-0.2.0/src/prompts/infrastructure/infrastructure_metrics.py +45 -0
  60. mcp_instana-0.2.0/src/prompts/infrastructure/infrastructure_resources.py +74 -0
  61. mcp_instana-0.2.0/src/prompts/infrastructure/infrastructure_topology.py +38 -0
  62. mcp_instana-0.2.0/src/prompts/settings/__init__.py +0 -0
  63. mcp_instana-0.2.0/src/prompts/settings/custom_dashboard.py +157 -0
  64. mcp_instana-0.2.0/src/prompts/website/__init__.py +1 -0
  65. mcp_instana-0.2.0/src/prompts/website/website_analyze.py +35 -0
  66. mcp_instana-0.2.0/src/prompts/website/website_catalog.py +40 -0
  67. mcp_instana-0.2.0/src/prompts/website/website_configuration.py +105 -0
  68. mcp_instana-0.2.0/src/prompts/website/website_metrics.py +34 -0
  69. mcp_instana-0.2.0/src/settings/__init__.py +1 -0
  70. mcp_instana-0.2.0/src/settings/custom_dashboard_tools.py +417 -0
  71. mcp_instana-0.2.0/src/website/__init__.py +0 -0
  72. mcp_instana-0.2.0/src/website/website_analyze.py +433 -0
  73. mcp_instana-0.2.0/src/website/website_catalog.py +171 -0
  74. mcp_instana-0.2.0/src/website/website_configuration.py +770 -0
  75. mcp_instana-0.2.0/src/website/website_metrics.py +241 -0
  76. mcp_instana-0.2.0/tests/README.md +512 -0
  77. mcp_instana-0.2.0/tests/__init__.py +5 -0
  78. mcp_instana-0.2.0/tests/application/__init__.py +1 -0
  79. mcp_instana-0.2.0/tests/application/test_application_alert_config.py +400 -0
  80. mcp_instana-0.2.0/tests/application/test_application_analyze.py +425 -0
  81. mcp_instana-0.2.0/tests/application/test_application_catalog.py +274 -0
  82. mcp_instana-0.2.0/tests/application/test_application_global_alert_config.py +488 -0
  83. mcp_instana-0.2.0/tests/application/test_application_metrics.py +467 -0
  84. mcp_instana-0.2.0/tests/application/test_application_resources.py +594 -0
  85. mcp_instana-0.2.0/tests/application/test_application_settings.py +367 -0
  86. mcp_instana-0.2.0/tests/application/test_application_topology.py +224 -0
  87. mcp_instana-0.2.0/tests/automation/__init__.py +5 -0
  88. mcp_instana-0.2.0/tests/automation/test_action_catalog.py +346 -0
  89. mcp_instana-0.2.0/tests/core/__init__.py +1 -0
  90. mcp_instana-0.2.0/tests/core/test_server.py +902 -0
  91. mcp_instana-0.2.0/tests/core/test_utils.py +756 -0
  92. mcp_instana-0.2.0/tests/e2e/README.md +520 -0
  93. mcp_instana-0.2.0/tests/e2e/__init__.py +5 -0
  94. mcp_instana-0.2.0/tests/e2e/application/test_application_alert_config.py +1820 -0
  95. mcp_instana-0.2.0/tests/e2e/application/test_application_analyze.py +935 -0
  96. mcp_instana-0.2.0/tests/e2e/application/test_application_catalog.py +832 -0
  97. mcp_instana-0.2.0/tests/e2e/application/test_application_metrics.py +1086 -0
  98. mcp_instana-0.2.0/tests/e2e/application/test_application_resources.py +697 -0
  99. mcp_instana-0.2.0/tests/e2e/application/test_application_settings.py +1232 -0
  100. mcp_instana-0.2.0/tests/e2e/application/test_application_topology.py +423 -0
  101. mcp_instana-0.2.0/tests/e2e/conftest.py +139 -0
  102. mcp_instana-0.2.0/tests/e2e/event/test_events_tools.py +2755 -0
  103. mcp_instana-0.2.0/tests/e2e/infrastructure/test_infrastructure_analyze.py +1999 -0
  104. mcp_instana-0.2.0/tests/e2e/infrastructure/test_infrastructure_catalog.py +1232 -0
  105. mcp_instana-0.2.0/tests/e2e/infrastructure/test_infrastructure_metrics.py +1084 -0
  106. mcp_instana-0.2.0/tests/e2e/infrastructure/test_infrastructure_resources.py +1240 -0
  107. mcp_instana-0.2.0/tests/e2e/infrastructure/test_infrastructure_topology.py +650 -0
  108. mcp_instana-0.2.0/tests/e2e/pytest.ini +29 -0
  109. mcp_instana-0.2.0/tests/e2e/run_e2e_tests.py +139 -0
  110. mcp_instana-0.2.0/tests/e2e/server/test_server_integration.py +1117 -0
  111. mcp_instana-0.2.0/tests/e2e/utils/test_base_instana_client.py +641 -0
  112. mcp_instana-0.2.0/tests/event/__init__.py +1 -0
  113. mcp_instana-0.2.0/tests/event/test_events_tools.py +1455 -0
  114. mcp_instana-0.2.0/tests/infrastructure/__init__.py +1 -0
  115. mcp_instana-0.2.0/tests/infrastructure/test_infrastructure_analyze.py +679 -0
  116. mcp_instana-0.2.0/tests/infrastructure/test_infrastructure_catalog.py +207 -0
  117. mcp_instana-0.2.0/tests/infrastructure/test_infrastructure_metrics.py +312 -0
  118. mcp_instana-0.2.0/tests/infrastructure/test_infrastructure_resources.py +213 -0
  119. mcp_instana-0.2.0/tests/infrastructure/test_infrastructure_topology.py +219 -0
  120. mcp_instana-0.2.0/tests/log/__init__.py +1 -0
  121. mcp_instana-0.2.0/tests/log/test_log_alert_configuration.py +653 -0
  122. mcp_instana-0.2.0/tests/prompts/__init__.py +1 -0
  123. mcp_instana-0.2.0/tests/prompts/application/__init__.py +2 -0
  124. mcp_instana-0.2.0/tests/prompts/application/test_application_alerts.py +41 -0
  125. mcp_instana-0.2.0/tests/prompts/application/test_application_catalog.py +26 -0
  126. mcp_instana-0.2.0/tests/prompts/application/test_application_metrics.py +36 -0
  127. mcp_instana-0.2.0/tests/prompts/application/test_application_resources.py +26 -0
  128. mcp_instana-0.2.0/tests/prompts/application/test_application_settings.py +56 -0
  129. mcp_instana-0.2.0/tests/prompts/application/test_application_topology.py +26 -0
  130. mcp_instana-0.2.0/tests/prompts/events/test_events_tools.py +53 -0
  131. mcp_instana-0.2.0/tests/prompts/infrastructure/__init__.py +2 -0
  132. mcp_instana-0.2.0/tests/prompts/infrastructure/test_infrastructure_analyze.py +38 -0
  133. mcp_instana-0.2.0/tests/prompts/infrastructure/test_infrastructure_catalog.py +43 -0
  134. mcp_instana-0.2.0/tests/prompts/infrastructure/test_infrastructure_metrics.py +28 -0
  135. mcp_instana-0.2.0/tests/prompts/infrastructure/test_infrastructure_resources.py +43 -0
  136. mcp_instana-0.2.0/tests/prompts/infrastructure/test_infrastructure_topology.py +33 -0
  137. mcp_instana-0.2.0/tests/run_all_tests.py +440 -0
  138. mcp_instana-0.2.0/tests/run_all_tests_with_coverage.py +105 -0
  139. mcp_instana-0.2.0/uv.lock +1112 -0
  140. mcp_instana-0.1.0/PKG-INFO +0 -649
  141. mcp_instana-0.1.0/README.md +0 -628
  142. mcp_instana-0.1.0/pyproject.toml +0 -41
  143. mcp_instana-0.1.0/src/client/What is the sum of queue depth for all q +0 -55
  144. mcp_instana-0.1.0/src/client/events_mcp_tools.py +0 -531
  145. mcp_instana-0.1.0/src/client/instana_client_base.py +0 -93
  146. mcp_instana-0.1.0/src/client/log_alert_configuration_mcp_tools.py +0 -316
  147. mcp_instana-0.1.0/src/client/show the top 5 services with the highest +0 -28
  148. mcp_instana-0.1.0/src/mcp_server.py +0 -343
  149. {mcp_instana-0.1.0 → mcp_instana-0.2.0}/src/__init__.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ "mcpServers": {}
3
+ }
@@ -0,0 +1,4 @@
1
+ # This enables DCO bot for you, please take a look https://github.com/probot/dco
2
+ # for more details.
3
+ require:
4
+ members: false
@@ -0,0 +1,127 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main, test-ci ]
8
+
9
+ jobs:
10
+ lint-and-test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ['3.11']
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install uv
25
+ run: pip install uv
26
+
27
+ - name: Install dependencies
28
+ run: uv sync --all-extras
29
+
30
+ - name: Run ruff check
31
+ run: uv run ruff check .
32
+
33
+ - name: Run unit tests with verbose output
34
+ run: |
35
+ # Set environment variables to handle missing SDK modules gracefully
36
+ export PYTHONPATH=${{ github.workspace }}
37
+ export PYTHONUNBUFFERED="1"
38
+ export DISABLE_REAL_API_CALLS="true"
39
+ export CI="true"
40
+
41
+ # Run tests and filter out expected import errors
42
+ # Note: Some Instana SDK modules may not be available in CI environment
43
+ # but tests are designed to handle this gracefully
44
+ uv run test -v 2>&1 | sed '/Error importing Instana SDK/d' || true
45
+
46
+ - name: Run unit tests with coverage
47
+ run: |
48
+ # Set environment variables to handle missing SDK modules gracefully
49
+ export PYTHONPATH=${{ github.workspace }}
50
+ export PYTHONUNBUFFERED="1"
51
+ export DISABLE_REAL_API_CALLS="true"
52
+ export CI="true"
53
+
54
+ # Run tests with coverage and filter out expected import errors
55
+ # Note: Some Instana SDK modules may not be available in CI environment
56
+ # but tests are designed to handle this gracefully
57
+ uv run test-coverage 2>&1 | sed '/Error importing Instana SDK/d' || true
58
+
59
+ - name: Check environment for E2E tests
60
+ run: |
61
+ echo "Checking environment..."
62
+ pwd
63
+ ls -la
64
+ echo "Python version:"
65
+ python --version
66
+ echo "UV version:"
67
+ uv --version
68
+ echo "Checking test directories:"
69
+ ls -la tests/
70
+ ls -la tests/e2e/
71
+ echo "Checking source directories:"
72
+ ls -la src/
73
+
74
+ - name: Run E2E mocked tests
75
+ env:
76
+ INSTANA_API_TOKEN: "test_token"
77
+ INSTANA_BASE_URL: "https://test.instana.io"
78
+ PYTHONPATH: ${{ github.workspace }}
79
+ PYTHONUNBUFFERED: "1"
80
+ DISABLE_REAL_API_CALLS: "true"
81
+ CI: "true"
82
+ run: |
83
+ echo "Running E2E mocked tests..."
84
+
85
+ # Run E2E tests with mocked environment
86
+ uv run -m pytest tests/e2e/ -m "mocked" -v --tb=short --maxfail=10 || {
87
+ echo "E2E tests failed. Checking for specific errors..."
88
+ uv run -m pytest tests/e2e/ -m "mocked" -v --tb=long --maxfail=5
89
+ exit 1
90
+ }
91
+
92
+ - name: Run E2E tests with coverage
93
+ env:
94
+ INSTANA_API_TOKEN: "test_token"
95
+ INSTANA_BASE_URL: "https://test.instana.io"
96
+ PYTHONPATH: ${{ github.workspace }}
97
+ PYTHONUNBUFFERED: "1"
98
+ DISABLE_REAL_API_CALLS: "true"
99
+ CI: "true"
100
+ run: |
101
+ echo "Running E2E tests with coverage..."
102
+
103
+ # Run E2E tests with coverage
104
+ uv run -m pytest tests/e2e/ -m "mocked" --cov=src --cov-report=html --cov-report=term-missing -v --maxfail=10 || {
105
+ echo "E2E tests with coverage failed. Checking for specific errors..."
106
+ uv run -m pytest tests/e2e/ -m "mocked" -v --tb=long --maxfail=5
107
+ exit 1
108
+ }
109
+
110
+ - name: Upload coverage reports as artifacts
111
+ uses: actions/upload-artifact@v4
112
+ if: always()
113
+ with:
114
+ name: coverage-reports
115
+ path: |
116
+ htmlcov/
117
+ .coverage
118
+ retention-days: 30
119
+
120
+ - name: Upload coverage reports to Codecov
121
+ uses: codecov/codecov-action@v4
122
+ with:
123
+ file: ./htmlcov/coverage.xml
124
+ flags: unittests
125
+ name: codecov-umbrella
126
+ fail_ci_if_error: false
127
+ verbose: true
@@ -0,0 +1,180 @@
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
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+
110
+ # pdm
111
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112
+ #pdm.lock
113
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114
+ # in version control.
115
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
116
+ .pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
121
+ __pypackages__/
122
+
123
+ # Celery stuff
124
+ celerybeat-schedule
125
+ celerybeat.pid
126
+
127
+ # SageMath parsed files
128
+ *.sage.py
129
+
130
+ # Environments
131
+ .env
132
+ .venv
133
+ env/
134
+ venv/
135
+ ENV/
136
+ env.bak/
137
+ venv.bak/
138
+
139
+ # Spyder project settings
140
+ .spyderproject
141
+ .spyproject
142
+
143
+ # Rope project settings
144
+ .ropeproject
145
+
146
+ # mkdocs documentation
147
+ /site
148
+
149
+ # mypy
150
+ .mypy_cache/
151
+ .dmypy.json
152
+ dmypy.json
153
+
154
+ # Pyre type checker
155
+ .pyre/
156
+
157
+ # pytype static type analyzer
158
+ .pytype/
159
+
160
+ # Cython debug symbols
161
+ cython_debug/
162
+
163
+ # PyCharm
164
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
165
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
167
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
168
+ #.idea/
169
+
170
+ # Ruff stuff:
171
+ .ruff_cache/
172
+
173
+ # PyPI configuration file
174
+ .pypirc
175
+ .DS_Store
176
+ .venv
177
+
178
+ # Ignore tooling dirs
179
+ .Bob/
180
+ .vscode/
@@ -0,0 +1,198 @@
1
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
2
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
3
+ **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
4
+
5
+ - [Contributing to MCP-Instana](#contributing-to-mcp-instana)
6
+ - [Prerequisites](#prerequisites)
7
+ - [Steps to Build a New MCP Tool](#steps-to-build-a-new-mcp-tool)
8
+ - [1. Fork this repo](#1-fork-this-repo)
9
+ - [2. Set Up Your Development Environment](#2-set-up-your-development-environment)
10
+ - [3. Create a New MCP Tools Module](#3-create-a-new-mcp-tools-module)
11
+ - [4. Implement the MCP Tools class](#4-implement-the-mcp-tools-class)
12
+ - [5. Write API tool Description precisely](#5-write-api-tool-description-precisely)
13
+ - [6. Update the Main Server File](#6-update-the-main-server-file)
14
+ - [7. Test Your MCP Tool](#7-test-your-mcp-tool)
15
+ - [8. Add Documentation](#8-add-documentation)
16
+ - [9. Code Linting](#9-code-linting)
17
+ - [Troubleshooting](#troubleshooting)
18
+ - [Getting Help](#getting-help)
19
+
20
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
21
+
22
+ ### Contributing to MCP-Instana
23
+
24
+ This guide provides step-by-step instructions for building a new MCP (Model Context Protocol) tool for the [Instana API](https://developer.ibm.com/apis/catalog/instana--instana-rest-api/Introduction) within the mcp-instana project.
25
+
26
+ ### Prerequisites
27
+
28
+ - Python 3.11 or higher
29
+ - Access to Instana API (API token and base URL)
30
+ - Access to Instana python SDK [git+https://github.ibm.com/instana/instana-python-sdk](https://github.ibm.com/instana/instana-python-sdk)
31
+ - Basic understanding of the [Instana API endpoints](https://developer.ibm.com/apis/catalog/instana--instana-rest-api/Introduction)
32
+ - Familiarity with Python async programming
33
+
34
+ ### Steps to Build a New MCP Tool
35
+
36
+ #### 1. Fork this repo
37
+
38
+ To begin development, you’ll need your own copy of the repository:
39
+
40
+ - Go to the GitHub page of this repository.
41
+ - Click the Fork button in the top-right corner.
42
+ - Select your personal GitHub account (or your organization’s account) as the destination.
43
+ - GitHub will create a forked copy of the repository under your account, e.g. https://github.com/<Your GitHub Username>/mcp-instana
44
+
45
+ #### 2. Set Up Your Development Environment
46
+
47
+ ```bash
48
+ # Clone the repository
49
+ git clone https://github.com/<Your GitHub Username>/mcp-instana.git
50
+ cd mcp-instana
51
+
52
+ # Set up the environment
53
+ uv sync
54
+
55
+ # Alternative: Install from PyPI
56
+ pip install mcp-instana
57
+ ```
58
+
59
+ #### 3. Create a New MCP Tools Module
60
+
61
+ Create a new file in the src/client directory with a descriptive name following the pattern: <api_name>_mcp_tools.py
62
+
63
+ #### 4. Implement the MCP Tools class
64
+
65
+ Follow any existing tools class under src/client to know the template structure for your new class.
66
+
67
+ #### 5. Write API tool Description precisely
68
+
69
+ For each tool, provide a clear description as per the prompt engineering guidelines that helps the LLM understand when to use this tool:
70
+
71
+
72
+ ```bash
73
+
74
+ @register_as_tool
75
+ async def get_example_data(self, query: str, ctx=None) -> Dict[str, Any]:
76
+ """
77
+ Retrieve example data from Instana based on the provided query.
78
+
79
+ This tool is useful when you need to get information about [specific use case].
80
+ You can filter by [parameters] to narrow down results. Use this when you want
81
+ to [common user intent], understand [specific information], or analyze [metrics/data].
82
+
83
+ For example, use this tool when asked about '[example query 1]', '[example query 2]',
84
+ or when someone wants to '[example intent]'.
85
+
86
+ Args:
87
+ query: Query string to filter results
88
+ ctx: The MCP context (optional)
89
+
90
+ Returns:
91
+ Dictionary containing example data or error information
92
+ """
93
+ ```
94
+
95
+
96
+ #### 6. Update the Main Server File
97
+
98
+ Update src/core/server.py to register your new tools:
99
+
100
+ #### 7. Test Your MCP Tool
101
+
102
+ Build the mcp-instana with:
103
+
104
+ ```bash
105
+ # For development (editable install)
106
+ uv pip install -e .
107
+
108
+ # Or install from PyPI
109
+ pip install mcp-instana
110
+ ```
111
+
112
+ Now open/restart the mcp host like Claude Desktop/GitHub Copilot and then run the query to test your new tool.
113
+
114
+ To run the MCP server locally:
115
+
116
+ **Using Development Installation:**
117
+ ```bash
118
+ # Run in Streamable HTTP mode
119
+ uv run src/core/server.py --transport streamable-http --debug
120
+
121
+ # Run with specific tool categories
122
+ uv run src/core/server.py --tools app,infra --transport streamable-http
123
+
124
+ # List all available tool categories
125
+ uv run src/core/server.py --list-tools
126
+ ```
127
+
128
+ **Using CLI (PyPI Installation):**
129
+ ```bash
130
+ # Run in Streamable HTTP mode
131
+ mcp-instana --transport streamable-http --debug
132
+
133
+ # Run with specific tool categories
134
+ mcp-instana --tools app,infra --transport streamable-http
135
+
136
+ # List all available tool categories
137
+ mcp-instana --list-tools
138
+ ```
139
+
140
+ #### 8. Add Documentation
141
+ Update the README.md file to include your new tool in the tools table:
142
+
143
+ ```bash
144
+
145
+ | Tool | Category | Description |
146
+ |---------------------------|-------------------|------------------------------------------|
147
+ | `[method_name]` | [API Category] | [Brief description of what the tool does]|
148
+ ```
149
+
150
+ #### 9. Code Linting
151
+
152
+ This project uses [Ruff](https://github.com/astral-sh/ruff) for code linting. Ruff is a fast Python linter written in Rust that helps maintain code quality and consistency.
153
+
154
+ The project ignores several linting rules to accommodate the existing codebase. See the `ignore` list in `pyproject.toml` for the complete list of ignored rules, which includes:
155
+
156
+ - `E501`: Line too long
157
+ - `SIM117`: Use a single `with` statement with multiple contexts
158
+ - `PLR0912`: Too many branches
159
+ - `E402`: Module level import not at top of file
160
+ - `ARG001`, `ARG002`, `ARG005`: Unused function/method/lambda arguments
161
+ - `PLR2004`: Magic value comparison
162
+ - `PLR0915`: Too many statements
163
+ - `PLR0911`: Too many return statements
164
+ - `B904`: Within an except clause, raise exceptions with raise from
165
+ - And others as needed for the codebase
166
+
167
+ To run the linter locally:
168
+
169
+ ```bash
170
+ # Run linter to check for issues
171
+ ./run_ruff_check.sh
172
+
173
+ # Run linter and automatically fix issues
174
+ ./run_ruff_check.sh --fix
175
+
176
+ # Run linter and automatically fix issues (including unsafe fixes)
177
+ ./run_ruff_check.sh --fix --unsafe-fixes
178
+ ```
179
+
180
+ The project also includes CI integration via GitHub Actions that automatically runs linting checks on all pull requests and pushes to the main branch. The workflow configuration is located in `.github/workflows/lint.yml`.
181
+
182
+ For pull requests, the CI will:
183
+ 1. Check for linting issues
184
+ 2. Automatically fix safe linting issues
185
+ 3. Commit the fixes back to your branch
186
+
187
+ Before submitting your code, make sure to run the linter and fix any issues. Many common issues can be automatically fixed using the `--fix` option. The CI pipeline will also verify that your code passes all linting checks.
188
+
189
+ #### Troubleshooting
190
+
191
+ If you encounter import errors, check that you're using the correct import paths.
192
+ If API calls fail, verify your API token and base URL.
193
+ Use debug printing to trace the execution flow and identify issues.
194
+ Check the Instana API documentation for any specific requirements or limitations.
195
+
196
+ #### Getting Help
197
+
198
+ If you need assistance, please open an issue on the GitHub repository or contact the project maintainers.
@@ -0,0 +1,60 @@
1
+ # Stage 1: Build stage with minimal runtime dependencies
2
+ FROM python:3.11-slim AS builder
3
+
4
+ # Install system dependencies needed for building
5
+ RUN apt-get update && apt-get install -y --no-install-recommends \
6
+ gcc \
7
+ g++ \
8
+ && rm -rf /var/lib/apt/lists/*
9
+
10
+ # Set working directory
11
+ WORKDIR /app
12
+
13
+ # Copy only the runtime dependency file and source code needed for the build
14
+ COPY pyproject-runtime.toml pyproject.toml
15
+ COPY src ./src
16
+ COPY README.md ./
17
+
18
+ # Install uv for dependency management
19
+ RUN pip install --no-cache-dir uv
20
+
21
+ # Install only runtime dependencies using the minimal pyproject-runtime.toml
22
+ RUN uv pip install --no-cache-dir --system .
23
+
24
+ # Stage 2: Runtime stage
25
+ FROM python:3.11-slim AS runtime
26
+
27
+ # Set working directory
28
+ WORKDIR /app
29
+
30
+ # Create a non-root user for security
31
+ RUN groupadd -r mcpuser && useradd -r -g mcpuser mcpuser
32
+
33
+ # Copy only the Python packages from builder (no source code needed)
34
+ COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
35
+ COPY --from=builder /usr/local/bin /usr/local/bin
36
+
37
+ # Copy only the source code needed for runtime
38
+ COPY src ./src
39
+
40
+ # Set ownership to non-root user
41
+ RUN chown -R mcpuser:mcpuser /app
42
+
43
+ # Switch to non-root user
44
+ USER mcpuser
45
+
46
+ # Expose the default port (configurable via PORT env var)
47
+ EXPOSE 8080
48
+
49
+ # Set environment variables (no hardcoded secrets)
50
+ ENV PYTHONPATH=/app
51
+ ENV PYTHONUNBUFFERED=1
52
+ ENV PORT=8080
53
+
54
+ # Health check using container's internal network
55
+ HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
56
+ CMD python -c "import requests; requests.get('http://127.0.0.1:8080/health', timeout=5)" || exit 1
57
+
58
+ # Run the server
59
+ ENTRYPOINT ["python", "-m", "src.core.server"]
60
+ CMD ["--transport", "streamable-http"]
@@ -1,4 +1,4 @@
1
- Apache License
1
+ Apache License
2
2
  Version 2.0, January 2004
3
3
  http://www.apache.org/licenses/
4
4
 
@@ -178,7 +178,7 @@
178
178
  APPENDIX: How to apply the Apache License to your work.
179
179
 
180
180
  To apply the Apache License to your work, attach the following
181
- boilerplate notice, with the fields enclosed by brackets "[]"
181
+ boilerplate notice, with the fields enclosed by brackets "{}"
182
182
  replaced with your own identifying information. (Don't include
183
183
  the brackets!) The text should be enclosed in the appropriate
184
184
  comment syntax for the file format. We also recommend that a
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright [yyyy] [name of copyright owner]
189
+ Copyright 2017 Solo.io, Inc.
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.