apolo-mcp 26.8.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.
- apolo_mcp-26.8.0/.github/dependabot.yml +15 -0
- apolo_mcp-26.8.0/.github/pull_request_template.md +15 -0
- apolo_mcp-26.8.0/.github/workflows/ci.yaml +81 -0
- apolo_mcp-26.8.0/.github/workflows/test.yaml +97 -0
- apolo_mcp-26.8.0/.gitignore +15 -0
- apolo_mcp-26.8.0/.pre-commit-config.yaml +34 -0
- apolo_mcp-26.8.0/.python-version +1 -0
- apolo_mcp-26.8.0/AGENTS.md +133 -0
- apolo_mcp-26.8.0/CHANGELOG.D/.gitignore +1 -0
- apolo_mcp-26.8.0/CHANGELOG.md +16 -0
- apolo_mcp-26.8.0/CONTRIBUTING.md +21 -0
- apolo_mcp-26.8.0/LICENSE +17 -0
- apolo_mcp-26.8.0/Makefile +60 -0
- apolo_mcp-26.8.0/PKG-INFO +108 -0
- apolo_mcp-26.8.0/README.md +60 -0
- apolo_mcp-26.8.0/RELEASE.md +53 -0
- apolo_mcp-26.8.0/SECURITY.md +19 -0
- apolo_mcp-26.8.0/improvements.md +132 -0
- apolo_mcp-26.8.0/pyproject.toml +105 -0
- apolo_mcp-26.8.0/skills/apolo-applications/SKILL.md +69 -0
- apolo_mcp-26.8.0/skills/apolo-applications/agents/openai.yaml +4 -0
- apolo_mcp-26.8.0/skills/apolo-flow-workloads/SKILL.md +50 -0
- apolo_mcp-26.8.0/skills/apolo-flow-workloads/agents/openai.yaml +4 -0
- apolo_mcp-26.8.0/skills/apolo-flow-workloads/references/image-builds.md +80 -0
- apolo_mcp-26.8.0/skills/apolo-platform-user-context/SKILL.md +44 -0
- apolo_mcp-26.8.0/skills/apolo-platform-user-context/agents/openai.yaml +4 -0
- apolo_mcp-26.8.0/skills/apolo-research-job/SKILL.md +45 -0
- apolo_mcp-26.8.0/skills/apolo-research-job/agents/openai.yaml +4 -0
- apolo_mcp-26.8.0/skills/apolo-resource-management/SKILL.md +69 -0
- apolo_mcp-26.8.0/skills/apolo-resource-management/agents/openai.yaml +4 -0
- apolo_mcp-26.8.0/skills/apolo-rnd-session-operate/SKILL.md +75 -0
- apolo_mcp-26.8.0/skills/apolo-rnd-session-operate/agents/openai.yaml +4 -0
- apolo_mcp-26.8.0/skills/apolo-rnd-session-operate/references/claude-code.md +41 -0
- apolo_mcp-26.8.0/skills/apolo-rnd-session-operate/references/codex.md +47 -0
- apolo_mcp-26.8.0/skills/apolo-rnd-session-operate/references/installation.md +136 -0
- apolo_mcp-26.8.0/skills/apolo-rnd-session-operate/references/runtime-bootstrap.md +40 -0
- apolo_mcp-26.8.0/skills/apolo-rnd-session-setup/SKILL.md +71 -0
- apolo_mcp-26.8.0/skills/apolo-rnd-session-setup/agents/openai.yaml +4 -0
- apolo_mcp-26.8.0/skills/apolo-rnd-session-setup/references/grant-planning.md +111 -0
- apolo_mcp-26.8.0/src/apolo_mcp/__init__.py +11 -0
- apolo_mcp-26.8.0/src/apolo_mcp/__main__.py +7 -0
- apolo_mcp-26.8.0/src/apolo_mcp/_client.py +47 -0
- apolo_mcp-26.8.0/src/apolo_mcp/app_plans.py +307 -0
- apolo_mcp-26.8.0/src/apolo_mcp/catalog.py +170 -0
- apolo_mcp-26.8.0/src/apolo_mcp/cli.py +76 -0
- apolo_mcp-26.8.0/src/apolo_mcp/client_setup.py +135 -0
- apolo_mcp-26.8.0/src/apolo_mcp/context.py +52 -0
- apolo_mcp-26.8.0/src/apolo_mcp/errors.py +71 -0
- apolo_mcp-26.8.0/src/apolo_mcp/ledger.py +357 -0
- apolo_mcp-26.8.0/src/apolo_mcp/policy.py +128 -0
- apolo_mcp-26.8.0/src/apolo_mcp/security.py +79 -0
- apolo_mcp-26.8.0/src/apolo_mcp/server.py +46 -0
- apolo_mcp-26.8.0/src/apolo_mcp/skill_installer.py +140 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tool_registry.py +11 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/__init__.py +0 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/admin.py +410 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/apps.py +1369 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/buckets.py +1246 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/context.py +243 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/disks.py +248 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/flow.py +926 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/flow_config.py +352 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/images.py +389 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/jobs.py +1229 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/secrets.py +378 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/service_accounts.py +387 -0
- apolo_mcp-26.8.0/src/apolo_mcp/tools/storage.py +564 -0
- apolo_mcp-26.8.0/src/apolo_mcp/workspace.py +88 -0
- apolo_mcp-26.8.0/tests/__init__.py +0 -0
- apolo_mcp-26.8.0/tests/conftest.py +29 -0
- apolo_mcp-26.8.0/tests/test_admin.py +174 -0
- apolo_mcp-26.8.0/tests/test_app_plans.py +175 -0
- apolo_mcp-26.8.0/tests/test_apps.py +360 -0
- apolo_mcp-26.8.0/tests/test_buckets.py +373 -0
- apolo_mcp-26.8.0/tests/test_client.py +30 -0
- apolo_mcp-26.8.0/tests/test_client_setup.py +64 -0
- apolo_mcp-26.8.0/tests/test_context.py +72 -0
- apolo_mcp-26.8.0/tests/test_context_tools.py +142 -0
- apolo_mcp-26.8.0/tests/test_disks.py +114 -0
- apolo_mcp-26.8.0/tests/test_docs_generation.py +276 -0
- apolo_mcp-26.8.0/tests/test_errors.py +31 -0
- apolo_mcp-26.8.0/tests/test_flow.py +417 -0
- apolo_mcp-26.8.0/tests/test_flow_config.py +187 -0
- apolo_mcp-26.8.0/tests/test_images.py +140 -0
- apolo_mcp-26.8.0/tests/test_jobs.py +615 -0
- apolo_mcp-26.8.0/tests/test_ledger.py +304 -0
- apolo_mcp-26.8.0/tests/test_policy.py +81 -0
- apolo_mcp-26.8.0/tests/test_secrets.py +205 -0
- apolo_mcp-26.8.0/tests/test_server.py +96 -0
- apolo_mcp-26.8.0/tests/test_service_accounts.py +219 -0
- apolo_mcp-26.8.0/tests/test_skill_installer.py +137 -0
- apolo_mcp-26.8.0/tests/test_storage.py +216 -0
- apolo_mcp-26.8.0/tests/test_workspace.py +71 -0
- apolo_mcp-26.8.0/towncrier.toml +9 -0
- apolo_mcp-26.8.0/uv.lock +2766 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: uv
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: daily
|
|
7
|
+
time: "03:00"
|
|
8
|
+
open-pull-requests-limit: 10
|
|
9
|
+
insecure-external-code-execution: allow
|
|
10
|
+
- package-ecosystem: github-actions
|
|
11
|
+
directory: /
|
|
12
|
+
schedule:
|
|
13
|
+
interval: daily
|
|
14
|
+
time: "03:00"
|
|
15
|
+
open-pull-requests-limit: 10
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
## Safety and context impact
|
|
4
|
+
|
|
5
|
+
- [ ] No credential/private data is included.
|
|
6
|
+
- [ ] Tool outputs are bounded and serializable.
|
|
7
|
+
- [ ] Write annotations/policy/approval behavior is covered by tests, or not applicable.
|
|
8
|
+
- [ ] Explicit context does not persist a context switch.
|
|
9
|
+
|
|
10
|
+
## Validation
|
|
11
|
+
|
|
12
|
+
- [ ] `make lint`
|
|
13
|
+
- [ ] `make test`
|
|
14
|
+
- [ ] `make build`
|
|
15
|
+
- [ ] `CHANGELOG.md` and compatibility docs updated when applicable.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
tags: ["v*"]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [master]
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ci-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
test:
|
|
16
|
+
name: All checks are passed
|
|
17
|
+
uses: ./.github/workflows/test.yaml
|
|
18
|
+
secrets: inherit
|
|
19
|
+
|
|
20
|
+
approve:
|
|
21
|
+
name: Approve Dependabot PR
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
if: github.event_name == 'pull_request' && github.actor == 'dependabot[bot]'
|
|
24
|
+
needs: test
|
|
25
|
+
permissions:
|
|
26
|
+
contents: write
|
|
27
|
+
pull-requests: write
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout
|
|
30
|
+
uses: actions/checkout@v7
|
|
31
|
+
- name: Fetch Dependabot metadata
|
|
32
|
+
uses: dependabot/fetch-metadata@v3
|
|
33
|
+
with:
|
|
34
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
35
|
+
- name: Enable auto-merge for Dependabot PR
|
|
36
|
+
run: gh pr merge --auto --squash --delete-branch "$PR_URL"
|
|
37
|
+
env:
|
|
38
|
+
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
39
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
40
|
+
|
|
41
|
+
release-package:
|
|
42
|
+
name: Release apolo-mcp package
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
needs: test
|
|
45
|
+
environment: pypi
|
|
46
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
|
47
|
+
permissions:
|
|
48
|
+
contents: write
|
|
49
|
+
id-token: write
|
|
50
|
+
steps:
|
|
51
|
+
- name: Checkout commit
|
|
52
|
+
uses: actions/checkout@v7
|
|
53
|
+
with:
|
|
54
|
+
fetch-depth: 0
|
|
55
|
+
- name: Install uv
|
|
56
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
57
|
+
with:
|
|
58
|
+
version: "0.11.31"
|
|
59
|
+
enable-cache: true
|
|
60
|
+
cache-dependency-glob: "uv.lock"
|
|
61
|
+
- name: Install project Python
|
|
62
|
+
run: uv python install
|
|
63
|
+
- name: Install dependencies
|
|
64
|
+
run: make setup
|
|
65
|
+
- name: Verify tag and changelog
|
|
66
|
+
shell: bash
|
|
67
|
+
run: |
|
|
68
|
+
[[ "${GITHUB_REF_NAME}" =~ ^v[0-9]{2}\.([1-9]|1[0-2])\.[0-9]+$ ]]
|
|
69
|
+
test "${GITHUB_REF_NAME}" = "v$(uv run python -c 'from apolo_mcp import __version__; print(__version__)')"
|
|
70
|
+
grep -F "## ${GITHUB_REF_NAME#v}" CHANGELOG.md
|
|
71
|
+
test -z "$(find CHANGELOG.D -type f ! -name .gitignore -print -quit)"
|
|
72
|
+
- name: Build apolo-mcp package
|
|
73
|
+
run: make build
|
|
74
|
+
- name: Publish to PyPI
|
|
75
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
76
|
+
- name: Sign the distributions with Sigstore
|
|
77
|
+
uses: sigstore/gh-action-sigstore-python@v3.5.0
|
|
78
|
+
with:
|
|
79
|
+
inputs: >-
|
|
80
|
+
./dist/*.tar.gz
|
|
81
|
+
./dist/*.whl
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call: {}
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
lint:
|
|
8
|
+
name: Linter
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
timeout-minutes: 15
|
|
11
|
+
steps:
|
|
12
|
+
- name: Checkout
|
|
13
|
+
uses: actions/checkout@v7
|
|
14
|
+
with:
|
|
15
|
+
ref: ${{ github.event.pull_request.head.sha }}
|
|
16
|
+
- name: Install uv
|
|
17
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
18
|
+
with:
|
|
19
|
+
version: "0.11.31"
|
|
20
|
+
enable-cache: true
|
|
21
|
+
cache-dependency-glob: "uv.lock"
|
|
22
|
+
- name: Install project Python
|
|
23
|
+
run: uv python install
|
|
24
|
+
- name: Cache pre-commit hooks
|
|
25
|
+
uses: actions/cache@v6
|
|
26
|
+
with:
|
|
27
|
+
path: ~/.cache/pre-commit
|
|
28
|
+
key: pre-commit|${{ runner.os }}|${{ hashFiles('.python-version', '.pre-commit-config.yaml') }}
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: make setup
|
|
31
|
+
- name: Run linters
|
|
32
|
+
run: make lint
|
|
33
|
+
env:
|
|
34
|
+
CI_LINT_RUN: 1
|
|
35
|
+
|
|
36
|
+
unit:
|
|
37
|
+
name: Unit tests (${{ matrix.os }}, Python ${{ matrix.python-version }})
|
|
38
|
+
strategy:
|
|
39
|
+
fail-fast: false
|
|
40
|
+
matrix:
|
|
41
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
42
|
+
os: [ubuntu, macos]
|
|
43
|
+
runs-on: ${{ matrix.os }}-latest
|
|
44
|
+
timeout-minutes: 15
|
|
45
|
+
steps:
|
|
46
|
+
- name: Checkout commit
|
|
47
|
+
uses: actions/checkout@v7
|
|
48
|
+
- name: Install uv and set Python version
|
|
49
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
50
|
+
with:
|
|
51
|
+
version: "0.11.31"
|
|
52
|
+
python-version: ${{ matrix.python-version }}
|
|
53
|
+
enable-cache: true
|
|
54
|
+
cache-dependency-glob: "uv.lock"
|
|
55
|
+
- name: Install dependencies
|
|
56
|
+
run: make setup
|
|
57
|
+
- name: Run unit tests
|
|
58
|
+
run: make test PYTEST_ARGS="-vvv"
|
|
59
|
+
env:
|
|
60
|
+
COLOR: yes
|
|
61
|
+
|
|
62
|
+
build:
|
|
63
|
+
name: Build distributions
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
timeout-minutes: 15
|
|
66
|
+
steps:
|
|
67
|
+
- name: Checkout commit
|
|
68
|
+
uses: actions/checkout@v7
|
|
69
|
+
- name: Install uv
|
|
70
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
71
|
+
with:
|
|
72
|
+
version: "0.11.31"
|
|
73
|
+
enable-cache: true
|
|
74
|
+
cache-dependency-glob: "uv.lock"
|
|
75
|
+
- name: Install project Python
|
|
76
|
+
run: uv python install
|
|
77
|
+
- name: Install dependencies
|
|
78
|
+
run: make setup
|
|
79
|
+
- name: Build package
|
|
80
|
+
run: make build
|
|
81
|
+
|
|
82
|
+
check:
|
|
83
|
+
# This job does nothing and is only used for branch protection.
|
|
84
|
+
name: Check
|
|
85
|
+
needs: [lint, unit, build]
|
|
86
|
+
if: ${{ always() }}
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
steps:
|
|
89
|
+
- name: Check
|
|
90
|
+
if: ${{ needs.lint.result != 'success' || needs.unit.result != 'success' || needs.build.result != 'success' }}
|
|
91
|
+
run: |
|
|
92
|
+
echo "lint result: ${{ needs.lint.result }}"
|
|
93
|
+
echo "unit result: ${{ needs.unit.result }}"
|
|
94
|
+
echo "build result: ${{ needs.build.result }}"
|
|
95
|
+
exit 1
|
|
96
|
+
- name: Success
|
|
97
|
+
run: echo "All checks have passed"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Adapted from neuro-inc/app-types at 44d287f4216b87e0aacd3913aa1a611845875412.
|
|
2
|
+
ci:
|
|
3
|
+
# pre-commit.ci does not install the project's uv environment. The GitHub Actions
|
|
4
|
+
# lint job runs this hook after `make setup` and remains the docs-drift gate.
|
|
5
|
+
skip: [generate-mcp-docs]
|
|
6
|
+
|
|
7
|
+
exclude: ^uv\.lock$
|
|
8
|
+
repos:
|
|
9
|
+
- repo: local
|
|
10
|
+
hooks:
|
|
11
|
+
- id: generate-mcp-docs
|
|
12
|
+
name: Generate MCP docs
|
|
13
|
+
language: system
|
|
14
|
+
entry: make docs
|
|
15
|
+
pass_filenames: false
|
|
16
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
17
|
+
rev: v5.0.0
|
|
18
|
+
hooks:
|
|
19
|
+
- id: check-added-large-files
|
|
20
|
+
- id: check-merge-conflict
|
|
21
|
+
- id: check-toml
|
|
22
|
+
- id: check-yaml
|
|
23
|
+
- id: end-of-file-fixer
|
|
24
|
+
- id: trailing-whitespace
|
|
25
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
26
|
+
rev: v0.9.9
|
|
27
|
+
hooks:
|
|
28
|
+
- id: ruff
|
|
29
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
30
|
+
- id: ruff-format
|
|
31
|
+
- repo: https://github.com/twisted/towncrier
|
|
32
|
+
rev: 25.8.0
|
|
33
|
+
hooks:
|
|
34
|
+
- id: towncrier-check
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
**`apolo-mcp`** is an MCP (Model Context Protocol) server that gives AI agents the ability to work with the [Apolo platform](https://apolo.us) — running training jobs, deploying long-lived applications, and managing artifacts in storage.
|
|
6
|
+
|
|
7
|
+
It is a thin adapter layer over `apolo-sdk`. It does **not** shell out to the `apolo` CLI.
|
|
8
|
+
|
|
9
|
+
## Architecture Decisions
|
|
10
|
+
|
|
11
|
+
- **Separate package** from `apolo-cli`/`apolo-sdk` to avoid MCP deps polluting the SDK.
|
|
12
|
+
- **Uses `apolo-sdk` directly** (not the CLI subprocess) for structured errors and typed responses.
|
|
13
|
+
- **Auth via Apolo configuration** — local use normally reads `~/.apolo/` after
|
|
14
|
+
`apolo login`; isolated jobs may use `APOLO_PASSED_CONFIG`. No tool accepts a token.
|
|
15
|
+
- **`apolo_sdk.get()`** is the entry point: an async context manager yielding `Client`.
|
|
16
|
+
- **`MCPServer`** from the `mcp` package for tool registration and server lifecycle.
|
|
17
|
+
|
|
18
|
+
## Workload boundary
|
|
19
|
+
|
|
20
|
+
- Use **jobs** for bounded R&D, experiments, builds, migrations, batch work, and tests.
|
|
21
|
+
- Use **Apps** for long-running deployments and managed services, including databases,
|
|
22
|
+
APIs, and web UIs. Do not emulate a deployment by keeping a job alive.
|
|
23
|
+
- A remote image builder may run as a job because the build is bounded; deploy the
|
|
24
|
+
resulting image through an App template such as Service Deployment.
|
|
25
|
+
|
|
26
|
+
## Tool Surface
|
|
27
|
+
|
|
28
|
+
`src/apolo_mcp/catalog.py` is the canonical ordered catalog for capability groups,
|
|
29
|
+
runtime registration, documentation descriptions, and owning skills. Registered
|
|
30
|
+
MCPServer metadata remains canonical for individual tool schemas and operation types. It
|
|
31
|
+
generates the complete [tool reference](docs/capabilities/tools/README.md); do not
|
|
32
|
+
maintain a duplicate tool table here.
|
|
33
|
+
|
|
34
|
+
## Package Structure
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
src/apolo_mcp/
|
|
38
|
+
cli.py — server and packaged-skill command-line interface
|
|
39
|
+
catalog.py — declarative capability and skill ownership catalog
|
|
40
|
+
server.py — MCPServer app and stdio server lifecycle
|
|
41
|
+
skill_installer.py — packaged skill installation implementation
|
|
42
|
+
_client.py — apolo_sdk.get() context manager helper
|
|
43
|
+
workspace.py — server-controlled local filesystem confinement
|
|
44
|
+
tools/ — registered capability modules; see catalog.py
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Tooling
|
|
48
|
+
|
|
49
|
+
- **uv** for all dependency management, building, and publishing — no pip/setuptools/twine.
|
|
50
|
+
- `pyproject.toml` is the single config source (no `setup.cfg` / `setup.py`).
|
|
51
|
+
- `uv.lock` is committed for reproducible installs.
|
|
52
|
+
- Build backend: **hatchling**.
|
|
53
|
+
|
|
54
|
+
## Documentation Contract
|
|
55
|
+
|
|
56
|
+
- Maintain exactly one authoritative source for each fact, interface, or workflow.
|
|
57
|
+
Prefer generating documentation from executable code and structured metadata. When
|
|
58
|
+
generation is impractical, designate one maintained canonical Markdown page. Every
|
|
59
|
+
other README, guide, skill reference, or example must link to that source instead of
|
|
60
|
+
copying its tables, commands, configuration blocks, or normative prose.
|
|
61
|
+
- The current source-ownership map is:
|
|
62
|
+
|
|
63
|
+
| Subject | Authoritative source | Published documentation |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| Capability order, descriptions, runtime registration, and skill ownership | `src/apolo_mcp/catalog.py` | generated tool navigation, skills catalog, and safety sections |
|
|
66
|
+
| MCP tool names, schemas, annotations, and operation types | registered MCPServer metadata in `src/apolo_mcp/tools/` | generated `docs/capabilities/tools/` and generated sections of the safety model |
|
|
67
|
+
| Policy modes and lifecycle journal behavior | `src/apolo_mcp/policy.py`, `src/apolo_mcp/ledger.py`, and `build-tools/docs-templates/safety.md` | generated `docs/getting-started/safety.md` |
|
|
68
|
+
| Canonical skill names and summaries | `src/apolo_mcp/catalog.py`, skill frontmatter, and `agents/openai.yaml` | generated `docs/capabilities/skills.md` |
|
|
69
|
+
| Complete skill instructions and supporting references | `skills/*/SKILL.md` and `skills/*/references/` | generated `docs/capabilities/skills/*/` |
|
|
70
|
+
| Installation, client registration, policy forwarding, startup-directory confinement, and skill installation | `build-tools/docs-templates/installation.md` | generated `docs/getting-started/installation.md` |
|
|
71
|
+
| Full-mode dedicated-service-account workflow | `build-tools/docs-templates/full-mode-service-account.md` | generated `docs/guides/full-mode-service-account.md` |
|
|
72
|
+
| Self-contained R&D runtime and isolated-job configuration | `build-tools/docs-templates/rnd-runtime.md` | embedded unchanged in the generated full-mode guide and packaged R&D skill reference |
|
|
73
|
+
| Supported, unsupported, and CLI-fallback capabilities | `docs/capabilities/README.md` | the same canonical maintained page |
|
|
74
|
+
|
|
75
|
+
- Treat MCP code, registered tool metadata, policy constants, and canonical skill
|
|
76
|
+
metadata as documentation inputs. Any change to a tool name, description, schema,
|
|
77
|
+
annotation, safety behavior, policy, skill, supported capability, or CLI fallback
|
|
78
|
+
must include the corresponding documentation update in the same change.
|
|
79
|
+
- Edit maintained prose under `docs/` and generator templates under
|
|
80
|
+
`build-tools/docs-templates/`. Never edit generated files under
|
|
81
|
+
`docs/capabilities/tools/`, `docs/capabilities/skills.md`,
|
|
82
|
+
`docs/capabilities/skills/`, or
|
|
83
|
+
`docs/getting-started/installation.md`, `docs/getting-started/safety.md`,
|
|
84
|
+
`docs/guides/full-mode-service-account.md`, or the packaged R&D skill's generated
|
|
85
|
+
`references/installation.md` directly.
|
|
86
|
+
- Run `make docs` after relevant code or skill changes, commit the generated Markdown,
|
|
87
|
+
then run `make docs-check` and pre-commit. Generation must not modify GitBook-owned
|
|
88
|
+
navigation such as `docs/SUMMARY.md`.
|
|
89
|
+
- Do not create a second installation or client-configuration guide. The canonical
|
|
90
|
+
`build-tools/docs-templates/installation.md` owns all install commands and
|
|
91
|
+
configuration snippets. Generated and maintained pages should link to the published
|
|
92
|
+
`docs/getting-started/installation.md`.
|
|
93
|
+
- Keep `docs/capabilities/README.md` current and use complete executable CLI commands,
|
|
94
|
+
including the `apolo` or `apolo-flow` entry point. Do not use internal shorthand such
|
|
95
|
+
as `job/root`.
|
|
96
|
+
|
|
97
|
+
## Development Commands
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
make setup # uv sync --all-groups + pre-commit install
|
|
101
|
+
make format # pre-commit run --all-files
|
|
102
|
+
make lint # format + mypy
|
|
103
|
+
make test # pytest unit tests
|
|
104
|
+
make build # uv build (sdist + wheel into dist/)
|
|
105
|
+
make docs # regenerate code-derived documentation
|
|
106
|
+
make docs-check # verify committed generated documentation is current
|
|
107
|
+
make publish # uv publish (set UV_PUBLISH_TOKEN)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Running the Server
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# stdio (default for Claude Desktop / Claude Code MCP config)
|
|
114
|
+
python -m apolo_mcp
|
|
115
|
+
|
|
116
|
+
# or via installed entry point
|
|
117
|
+
apolo-mcp
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Client configuration
|
|
121
|
+
|
|
122
|
+
Do not duplicate Codex or Claude Code setup here. Use the
|
|
123
|
+
[installation and client configuration](docs/getting-started/installation.md).
|
|
124
|
+
|
|
125
|
+
## Key Conventions
|
|
126
|
+
|
|
127
|
+
- Storage paths: accept `apolo://...` URIs or bare paths like `/my/dir` (resolved against the current cluster/org/project from config).
|
|
128
|
+
- Centralize all local path confinement in `src/apolo_mcp/workspace.py`; document its
|
|
129
|
+
behavior only in `build-tools/docs-templates/safety.md`.
|
|
130
|
+
- All tools return plain dicts or strings — no SDK objects cross the boundary.
|
|
131
|
+
- Async tools throughout; MCPServer handles the event loop.
|
|
132
|
+
- Python ≥ 3.11 (matches `apolo-sdk` minimum).
|
|
133
|
+
- Ruff owns formatting and import sorting; `apolo_mcp` is the configured first-party package.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!.gitignore
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes are documented here. Releases use `YY.MM.NN`, where `YY` is the
|
|
4
|
+
two-digit year, `MM` is the month without a leading zero, and `NN` is the zero-based
|
|
5
|
+
release sequence within that month.
|
|
6
|
+
|
|
7
|
+
[comment]: # (towncrier release notes start)
|
|
8
|
+
|
|
9
|
+
## 26.8.0 (2026-08-03)
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
- Establish the standalone MCP server with typed Apolo tools, explicit context, released
|
|
14
|
+
Flow integration, protected credential sinks, operational skills, code-derived docs,
|
|
15
|
+
packaged Codex and Claude Code skill installation, a declarative capability catalog,
|
|
16
|
+
and calendar-based release tooling. ([#1](https://github.com/neuro-inc/apolo-mcp/issues/1))
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Use Python 3.11+ and `uv`. Create a focused branch, add tests for every tool/schema or
|
|
4
|
+
policy change, and run:
|
|
5
|
+
|
|
6
|
+
```console
|
|
7
|
+
make setup
|
|
8
|
+
make lint
|
|
9
|
+
make test
|
|
10
|
+
make build
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Never put credentials or private platform data in fixtures, recordings, logs, or pull
|
|
14
|
+
requests. Tool results must be serializable and bounded. Write tools need accurate MCP
|
|
15
|
+
annotations, explicit resolved context, unit tests, and server-policy enforcement where
|
|
16
|
+
high risk. Interactive or high-bandwidth behavior belongs in a documented CLI workflow,
|
|
17
|
+
not an unbounded MCP response.
|
|
18
|
+
|
|
19
|
+
Add a `CHANGELOG.D/<issue>.feature`, `.bugfix`, `.doc`, `.removal`, or `.misc`
|
|
20
|
+
fragment for each user-visible change. Maintainers assemble fragments with
|
|
21
|
+
`make changelog VERSION=<version>` through the protected release workflow.
|
apolo_mcp-26.8.0/LICENSE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
https://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Copyright 2026 Apolo
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
https://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
SHELL := /bin/bash
|
|
2
|
+
|
|
3
|
+
PYTEST_ARGS=
|
|
4
|
+
|
|
5
|
+
.PHONY: help
|
|
6
|
+
.SILENT: help
|
|
7
|
+
help:
|
|
8
|
+
@grep -hE '^[a-zA-Z_-]+:[^#]*?### .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
|
9
|
+
|
|
10
|
+
.PHONY: setup
|
|
11
|
+
setup: ### Install dev dependencies and pre-commit hooks
|
|
12
|
+
uv sync --locked --all-groups
|
|
13
|
+
uv run pre-commit install
|
|
14
|
+
|
|
15
|
+
.PHONY: format fmt
|
|
16
|
+
format fmt: ### Reformat source files
|
|
17
|
+
ifdef CI_LINT_RUN
|
|
18
|
+
uv run pre-commit run --all-files --show-diff-on-failure
|
|
19
|
+
else
|
|
20
|
+
uv run pre-commit run --all-files || uv run pre-commit run --all-files
|
|
21
|
+
endif
|
|
22
|
+
|
|
23
|
+
.PHONY: lint
|
|
24
|
+
lint: format ### Reformat, lint, and type-check
|
|
25
|
+
uv run mypy src/ --show-error-codes
|
|
26
|
+
|
|
27
|
+
.PHONY: test
|
|
28
|
+
test: ### Run unit tests
|
|
29
|
+
uv run pytest $(PYTEST_ARGS) tests/
|
|
30
|
+
|
|
31
|
+
.PHONY: build
|
|
32
|
+
build: ### Build sdist and wheel
|
|
33
|
+
uv build
|
|
34
|
+
|
|
35
|
+
.PHONY: docs
|
|
36
|
+
docs: ### Regenerate code-derived documentation
|
|
37
|
+
uv run python build-tools/generate-docs.py
|
|
38
|
+
|
|
39
|
+
.PHONY: docs-check
|
|
40
|
+
docs-check: ### Verify code-derived documentation is current
|
|
41
|
+
uv run python build-tools/generate-docs.py --check
|
|
42
|
+
|
|
43
|
+
.PHONY: changelog
|
|
44
|
+
changelog: ### Build the changelog for calendar VERSION (for example, VERSION=26.7.0)
|
|
45
|
+
test -n "$(VERSION)"
|
|
46
|
+
uv run towncrier build --yes --version "$(VERSION)"
|
|
47
|
+
|
|
48
|
+
.PHONY: publish
|
|
49
|
+
publish: ### Publish to PyPI (set UV_PUBLISH_TOKEN env var)
|
|
50
|
+
uv publish
|
|
51
|
+
|
|
52
|
+
.PHONY: run
|
|
53
|
+
run: ### Run the MCP server (stdio transport)
|
|
54
|
+
uv run python -m apolo_mcp
|
|
55
|
+
|
|
56
|
+
.PHONY: clean
|
|
57
|
+
clean: ### Remove build artifacts
|
|
58
|
+
find . -name '*.egg-info' -exec rm -rf {} +
|
|
59
|
+
find . -name '__pycache__' -exec rm -rf {} +
|
|
60
|
+
rm -rf .mypy_cache dist build
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: apolo-mcp
|
|
3
|
+
Version: 26.8.0
|
|
4
|
+
Summary: MCP server for the Apolo platform
|
|
5
|
+
Project-URL: Homepage, https://github.com/neuro-inc/apolo-mcp
|
|
6
|
+
Project-URL: Documentation, https://github.com/neuro-inc/apolo-mcp/tree/master/docs
|
|
7
|
+
Project-URL: Repository, https://github.com/neuro-inc/apolo-mcp
|
|
8
|
+
Project-URL: Issues, https://github.com/neuro-inc/apolo-mcp/issues
|
|
9
|
+
Author-email: Apolo Team <dev@apolo.us>
|
|
10
|
+
License: Apache License
|
|
11
|
+
Version 2.0, January 2004
|
|
12
|
+
https://www.apache.org/licenses/
|
|
13
|
+
|
|
14
|
+
Copyright 2026 Apolo
|
|
15
|
+
|
|
16
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
17
|
+
you may not use this file except in compliance with the License.
|
|
18
|
+
You may obtain a copy of the License at
|
|
19
|
+
|
|
20
|
+
https://www.apache.org/licenses/LICENSE-2.0
|
|
21
|
+
|
|
22
|
+
Unless required by applicable law or agreed to in writing, software
|
|
23
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
24
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
25
|
+
See the License for the specific language governing permissions and
|
|
26
|
+
limitations under the License.
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Classifier: Development Status :: 3 - Alpha
|
|
29
|
+
Classifier: Intended Audience :: Developers
|
|
30
|
+
Classifier: Intended Audience :: Science/Research
|
|
31
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
32
|
+
Classifier: Operating System :: OS Independent
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
38
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
39
|
+
Requires-Python: >=3.11
|
|
40
|
+
Requires-Dist: apolo-flow>=26.7.2
|
|
41
|
+
Requires-Dist: apolo-sdk>=26.7.2
|
|
42
|
+
Requires-Dist: async-timeout>=5
|
|
43
|
+
Requires-Dist: jsonschema<5,>=4.23
|
|
44
|
+
Requires-Dist: mcp<3,>=2.0.0
|
|
45
|
+
Requires-Dist: pyyaml>=6.0
|
|
46
|
+
Requires-Dist: tomlkit<1,>=0.13
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# apolo-mcp
|
|
50
|
+
|
|
51
|
+
`apolo-mcp` is a local stdio Model Context Protocol server for typed Apolo platform
|
|
52
|
+
operations. It is a thin adapter over `apolo-sdk`: it never shells out to the CLI and
|
|
53
|
+
uses the configured Apolo identity, permissions, and defaults. Local sessions normally
|
|
54
|
+
come from `apolo login`; isolated jobs may use `APOLO_PASSED_CONFIG`.
|
|
55
|
+
|
|
56
|
+
The server exposes bounded context discovery and typed platform operations. Every
|
|
57
|
+
operational tool accepts explicit `cluster`, `org`, and `project` inputs where the
|
|
58
|
+
SDK supports them; explicit inputs never modify the user's saved context. Secret
|
|
59
|
+
values and one-time credentials are intentionally outside the model-visible interface.
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
Follow the
|
|
64
|
+
[installation and client configuration guide](docs/getting-started/installation.md)
|
|
65
|
+
for prerequisites, server and skill installation, Codex and Claude Code registration,
|
|
66
|
+
per-session policy selection, and verification. Local stdio is the only supported
|
|
67
|
+
transport; shared-credential remote service operation is unsupported.
|
|
68
|
+
|
|
69
|
+
See the [Apolo MCP documentation](docs/README.md) for prerequisites, safety controls,
|
|
70
|
+
the capability matrix, generated tools and skills catalogs, and task-oriented guides.
|
|
71
|
+
|
|
72
|
+
## Development
|
|
73
|
+
|
|
74
|
+
```console
|
|
75
|
+
make setup
|
|
76
|
+
make lint
|
|
77
|
+
make test
|
|
78
|
+
make build
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Dependencies are locked with `uv.lock`. Tests use an `ApoloClientProvider` fake and do
|
|
82
|
+
not require credentials. Integration tests, when added, must be opt-in and target an
|
|
83
|
+
isolated non-production project.
|
|
84
|
+
|
|
85
|
+
Wheel and source-distribution files are generated release artifacts and must not be
|
|
86
|
+
committed. Tagged releases build them in CI and publish the exact outputs to PyPI via
|
|
87
|
+
Trusted Publishing; local `dist/` contents are disposable. Maintainers should follow
|
|
88
|
+
[RELEASE.md](RELEASE.md) for changelog, validation, signing, and publication.
|
|
89
|
+
|
|
90
|
+
Release versions use `YY.MM.NN`: the two-digit year, the month without a leading zero,
|
|
91
|
+
and a zero-based release sequence within that month. For example, `v26.7.0` is the
|
|
92
|
+
first July 2026 release, and its Python package version is `26.7.0`.
|
|
93
|
+
|
|
94
|
+
## Safety configuration
|
|
95
|
+
|
|
96
|
+
The server defaults to `APOLO_MCP_POLICY_MODE=read-only`. Use `managed` to create
|
|
97
|
+
resources and manage only their exact journaled lifecycles, or `full` to permit
|
|
98
|
+
mutations of any exact-context resource. Policy never grants Apolo permissions or
|
|
99
|
+
replaces Apolo RBAC, and it is not a security boundary against an agent with direct
|
|
100
|
+
CLI or SDK access. **Never run `full` with a personal administrator, owner, or other
|
|
101
|
+
broadly privileged Apolo account.** Use a dedicated least-privileged service account
|
|
102
|
+
and follow the [full-mode service-account guide](docs/guides/full-mode-service-account.md).
|
|
103
|
+
Select policy per launch rather than permanently storing `managed` or `full`; the
|
|
104
|
+
installation guide contains the client-specific configuration. Read the generated
|
|
105
|
+
[safety model](docs/getting-started/safety.md) before enabling writes, and consult the
|
|
106
|
+
[capability matrix](docs/capabilities/) for the complete current contract.
|
|
107
|
+
|
|
108
|
+
Licensed under Apache-2.0. See [SECURITY.md](SECURITY.md) for private reporting.
|