codex-images-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. codex_images_mcp-0.1.0/.dockerignore +8 -0
  2. codex_images_mcp-0.1.0/.github/workflows/ci.yml +91 -0
  3. codex_images_mcp-0.1.0/.github/workflows/release.yml +105 -0
  4. codex_images_mcp-0.1.0/.gitignore +68 -0
  5. codex_images_mcp-0.1.0/CHANGELOG.md +29 -0
  6. codex_images_mcp-0.1.0/Dockerfile +26 -0
  7. codex_images_mcp-0.1.0/LICENSE +25 -0
  8. codex_images_mcp-0.1.0/NOTICE +14 -0
  9. codex_images_mcp-0.1.0/PKG-INFO +108 -0
  10. codex_images_mcp-0.1.0/README.md +68 -0
  11. codex_images_mcp-0.1.0/RELEASING.md +40 -0
  12. codex_images_mcp-0.1.0/docker-compose.yml +20 -0
  13. codex_images_mcp-0.1.0/docs/cli.md +72 -0
  14. codex_images_mcp-0.1.0/docs/comparison.md +25 -0
  15. codex_images_mcp-0.1.0/docs/examples.md +107 -0
  16. codex_images_mcp-0.1.0/docs/mcp.md +136 -0
  17. codex_images_mcp-0.1.0/docs/self-hosting.md +68 -0
  18. codex_images_mcp-0.1.0/install.ps1 +84 -0
  19. codex_images_mcp-0.1.0/install.sh +72 -0
  20. codex_images_mcp-0.1.0/packages/pi-codex-images/.gitignore +2 -0
  21. codex_images_mcp-0.1.0/packages/pi-codex-images/LICENSE +24 -0
  22. codex_images_mcp-0.1.0/packages/pi-codex-images/README.md +65 -0
  23. codex_images_mcp-0.1.0/packages/pi-codex-images/config.remote.example.json +13 -0
  24. codex_images_mcp-0.1.0/packages/pi-codex-images/core.ts +236 -0
  25. codex_images_mcp-0.1.0/packages/pi-codex-images/index.ts +118 -0
  26. codex_images_mcp-0.1.0/packages/pi-codex-images/package-lock.json +724 -0
  27. codex_images_mcp-0.1.0/packages/pi-codex-images/package.json +33 -0
  28. codex_images_mcp-0.1.0/packages/pi-codex-images/tests/contract.test.ts +132 -0
  29. codex_images_mcp-0.1.0/packages/pi-codex-images/tsconfig.json +13 -0
  30. codex_images_mcp-0.1.0/pyproject.toml +74 -0
  31. codex_images_mcp-0.1.0/src/codex_images_mcp/__init__.py +11 -0
  32. codex_images_mcp-0.1.0/src/codex_images_mcp/_assets/__init__.py +1 -0
  33. codex_images_mcp-0.1.0/src/codex_images_mcp/_assets/skills/__init__.py +1 -0
  34. codex_images_mcp-0.1.0/src/codex_images_mcp/_assets/skills/codex-images.md +49 -0
  35. codex_images_mcp-0.1.0/src/codex_images_mcp/_auth.py +311 -0
  36. codex_images_mcp-0.1.0/src/codex_images_mcp/_install.py +731 -0
  37. codex_images_mcp-0.1.0/src/codex_images_mcp/_native.py +329 -0
  38. codex_images_mcp-0.1.0/src/codex_images_mcp/_schema.py +35 -0
  39. codex_images_mcp-0.1.0/src/codex_images_mcp/_service.py +492 -0
  40. codex_images_mcp-0.1.0/src/codex_images_mcp/_urls.py +37 -0
  41. codex_images_mcp-0.1.0/src/codex_images_mcp/cli.py +536 -0
  42. codex_images_mcp-0.1.0/src/codex_images_mcp/http_server.py +147 -0
  43. codex_images_mcp-0.1.0/src/codex_images_mcp/mcp_server.py +124 -0
  44. codex_images_mcp-0.1.0/tests/__init__.py +0 -0
  45. codex_images_mcp-0.1.0/tests/test_api_engine.py +165 -0
  46. codex_images_mcp-0.1.0/tests/test_auth.py +155 -0
  47. codex_images_mcp-0.1.0/tests/test_cli.py +244 -0
  48. codex_images_mcp-0.1.0/tests/test_http_server.py +88 -0
  49. codex_images_mcp-0.1.0/tests/test_install.py +620 -0
  50. codex_images_mcp-0.1.0/tests/test_mcp_server.py +89 -0
  51. codex_images_mcp-0.1.0/tests/test_native.py +213 -0
  52. codex_images_mcp-0.1.0/tests/test_schema.py +33 -0
  53. codex_images_mcp-0.1.0/tests/test_service.py +221 -0
  54. codex_images_mcp-0.1.0/tests/test_skill_install.py +330 -0
@@ -0,0 +1,8 @@
1
+ .git
2
+ .venv
3
+ **/__pycache__
4
+ **/.pytest_cache
5
+ packages
6
+ tests
7
+ docs
8
+ examples
@@ -0,0 +1,91 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ python:
14
+ runs-on: ${{ matrix.os }}
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ os: [ubuntu-latest, windows-latest, macos-latest]
19
+ python-version: ['3.11', '3.12', '3.13']
20
+ steps:
21
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
22
+ with:
23
+ persist-credentials: false
24
+
25
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
26
+ with:
27
+ python-version: ${{ matrix.python-version }}
28
+
29
+ - name: Install package and dev deps
30
+ run: python -m pip install -e ".[dev]"
31
+
32
+ - name: Run tests
33
+ run: python -m pytest tests/ -q
34
+
35
+ pi-extension:
36
+ runs-on: ubuntu-latest
37
+ defaults:
38
+ run:
39
+ working-directory: packages/pi-codex-images
40
+ steps:
41
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
42
+ with:
43
+ persist-credentials: false
44
+
45
+ - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
46
+ with:
47
+ node-version: '22'
48
+ cache: npm
49
+ cache-dependency-path: packages/pi-codex-images/package-lock.json
50
+
51
+ - run: npm ci
52
+ - run: npm test
53
+ - run: npm run typecheck
54
+ - name: Check published files
55
+ run: npm pack --dry-run
56
+
57
+ docker:
58
+ runs-on: ubuntu-latest
59
+ steps:
60
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
61
+ with:
62
+ persist-credentials: false
63
+
64
+ - name: Build image
65
+ run: docker build -t codex-images-mcp:ci .
66
+
67
+ - name: Refuses public bind without a token
68
+ env:
69
+ EXPECTED: Refusing to listen on 0.0.0.0 without
70
+ run: |
71
+ set +e
72
+ docker run --rm codex-images-mcp:ci > out.txt 2>&1
73
+ code=$?
74
+ set -e
75
+ cat out.txt
76
+ test "$code" -eq 2
77
+ grep -q "$EXPECTED CODEX_IMAGES_HTTP_TOKEN" out.txt
78
+
79
+ - name: Serves MCP behind the bearer token
80
+ env:
81
+ URL: http://127.0.0.1:8324/mcp/
82
+ run: |
83
+ docker run -d --name cim -p 8324:8324 \
84
+ -e CODEX_IMAGES_HTTP_TOKEN=ci-token codex-images-mcp:ci
85
+ status() { curl -s -o /dev/null -w '%{http_code}' -X POST "$URL"; }
86
+ for _ in $(seq 1 30); do
87
+ [ "$(status || true)" = "401" ] && break
88
+ sleep 1
89
+ done
90
+ test "$(status)" = "401"
91
+ docker rm -f cim
@@ -0,0 +1,105 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*.*.*'
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ pypi:
13
+ runs-on: ubuntu-latest
14
+ environment: pypi
15
+ permissions:
16
+ id-token: write # PyPI Trusted Publishing; no long-lived token
17
+ steps:
18
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
19
+ with:
20
+ persist-credentials: false
21
+
22
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
23
+ with:
24
+ python-version: '3.12'
25
+
26
+ - name: Check tag matches package version
27
+ shell: python
28
+ run: |
29
+ import os, tomllib
30
+ with open("pyproject.toml", "rb") as handle:
31
+ version = tomllib.load(handle)["project"]["version"]
32
+ assert f"v{version}" == os.environ["GITHUB_REF_NAME"], version
33
+
34
+ - name: Build distributions
35
+ run: |
36
+ python -m pip install --upgrade build twine
37
+ python -m build
38
+ python -m twine check dist/*
39
+
40
+ - uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # release/v1
41
+
42
+ ghcr:
43
+ runs-on: ubuntu-latest
44
+ permissions:
45
+ contents: read
46
+ packages: write
47
+ steps:
48
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
49
+ with:
50
+ persist-credentials: false
51
+
52
+ - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
53
+
54
+ - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
55
+ with:
56
+ registry: ghcr.io
57
+ username: ${{ github.actor }}
58
+ password: ${{ secrets.GITHUB_TOKEN }}
59
+
60
+ - id: meta
61
+ uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
62
+ with:
63
+ images: ghcr.io/${{ github.repository_owner }}/codex-images-mcp
64
+ tags: |
65
+ type=semver,pattern={{version}}
66
+ type=semver,pattern={{major}}.{{minor}}
67
+ type=raw,value=latest
68
+
69
+ - uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
70
+ with:
71
+ context: .
72
+ platforms: linux/amd64,linux/arm64
73
+ push: true
74
+ tags: ${{ steps.meta.outputs.tags }}
75
+ labels: ${{ steps.meta.outputs.labels }}
76
+
77
+ npm:
78
+ runs-on: ubuntu-latest
79
+ permissions:
80
+ contents: read
81
+ id-token: write # npm provenance
82
+ defaults:
83
+ run:
84
+ working-directory: packages/pi-codex-images
85
+ steps:
86
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
87
+ with:
88
+ persist-credentials: false
89
+
90
+ - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
91
+ with:
92
+ node-version: '22'
93
+ registry-url: https://registry.npmjs.org
94
+ package-manager-cache: false
95
+
96
+ - name: Check tag matches package version
97
+ run: |
98
+ version=$(node -p "require('./package.json').version")
99
+ test "v$version" = "$GITHUB_REF_NAME"
100
+
101
+ - run: npm ci
102
+ - run: npm test
103
+ - run: npm publish --provenance --access public
104
+ env:
105
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,68 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ MANIFEST
23
+
24
+ # Editable installs
25
+ *.pth
26
+
27
+ # Virtual environments
28
+ venv/
29
+ env/
30
+ ENV/
31
+ .venv/
32
+ .env
33
+
34
+ # Testing
35
+ .pytest_cache/
36
+ .coverage
37
+ htmlcov/
38
+ .tox/
39
+ .mypy_cache/
40
+ .ruff_cache/
41
+
42
+ # IDEs
43
+ .vscode/
44
+ .idea/
45
+ *.swp
46
+ *.swo
47
+
48
+ # OS
49
+ .DS_Store
50
+ Thumbs.db
51
+ desktop.ini
52
+
53
+ # Project-local
54
+ # Probe scripts + their results (used during architecture verification, not part of package)
55
+ probe_*.py
56
+ probe_*.json
57
+ probe_*.txt
58
+ probe_*log*
59
+
60
+ # Output directories from runs
61
+ out/
62
+ runs/
63
+ smoke-test/
64
+ test-runs/
65
+ *.raw.png
66
+
67
+ # Upstream clone (reference only, not part of our package)
68
+ upstream/
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — unreleased
4
+
5
+ First release of codex-images-mcp, a fork of [VelmoAI/codex-imagen](https://github.com/VelmoAI/codex-imagen).
6
+
7
+ ### Added
8
+
9
+ - Native Codex Images engine (`/backend-api/codex/images/{generations,edits}`, gpt-image-2): prompts sent verbatim, native transparency, references and masks.
10
+ - `codex_images` and `codex_images_artifact` MCP tools returning `codex-images.result/v2` with verified `resource_link` artifacts (SHA-256, MIME, dimensions).
11
+ - Output size policies `native`, `exact`, `fit` and `cover`.
12
+ - Streamable HTTP server `codex-images-mcp-http`: built-in bearer auth, refuses a public bind without a token, signed single-use downloads.
13
+ - Docker image and example compose file.
14
+ - `codex-images-mcp login` / `logout`: a device-code ChatGPT session of its own, stored with mode 0600.
15
+ - SSRF-hardened remote references: HTTPS, public addresses only, pinned IP, no redirects.
16
+ - Pi / Gentle Shell extension `pi-codex-images`.
17
+ - Optional OpenAI API engine (`CODEX_IMAGES_ENGINE=api` + `OPENAI_API_KEY`) that honors `model` (default `gpt-image-2.6-flare`), `quality` and `complexity`; the plan route ignores them with a warning. Results report the engine in `models.engine`.
18
+ - CI on Linux, macOS and Windows; releases to PyPI, GHCR and npm.
19
+
20
+ ### Changed
21
+
22
+ - Package, CLI and MCP server renamed to `codex-images-mcp` / `codex-images`. `setup` keeps existing `codex-imagen` entries and explains how to remove them.
23
+ - A borrowed Codex CLI login (`CODEX_HOME/auth.json`) is used read-only and never refreshed.
24
+
25
+ ### Removed
26
+
27
+ - The prompt-rewriting model, reasoning modes, skill-file injection and chroma-key pipeline. Their input fields are accepted and ignored with a warning.
28
+ - The Python SDK (`imagen`, `ImagenOptions`, `ImagenResult`) and the `imagen` console script.
29
+ - The `codex-image-gen` dependency.
@@ -0,0 +1,26 @@
1
+ # codex-images-mcp — self-hosted Streamable HTTP server.
2
+ FROM python:3.12-slim
3
+
4
+ ENV PYTHONDONTWRITEBYTECODE=1 \
5
+ PYTHONUNBUFFERED=1 \
6
+ CODEX_HOME=/data/codex \
7
+ CODEX_IMAGES_AUTH_FILE=/data/auth.json \
8
+ CODEX_IMAGES_OUTPUT_DIR=/data/out \
9
+ CODEX_IMAGES_HTTP_HOST=0.0.0.0 \
10
+ CODEX_IMAGES_HTTP_PORT=8324
11
+
12
+ WORKDIR /src
13
+ COPY pyproject.toml README.md LICENSE ./
14
+ COPY src ./src
15
+ RUN pip install --no-cache-dir ".[http]" \
16
+ && useradd --create-home --uid 10001 app \
17
+ && mkdir -p /data/codex /data/out \
18
+ && chown -R app:app /data
19
+
20
+ USER app
21
+ WORKDIR /home/app
22
+ VOLUME ["/data"]
23
+ EXPOSE 8324
24
+
25
+ # Refuses to start on 0.0.0.0 unless CODEX_IMAGES_HTTP_TOKEN is set.
26
+ CMD ["codex-images-mcp-http"]
@@ -0,0 +1,25 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 wauwa
4
+ Copyright (c) 2026 JlMoreno00
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ This project bundles ideas from the upstream `codex-image-gen` library by
17
+ Small Turtle 2 (MIT-licensed). See https://github.com/smturtle2/codex-image-gen.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
@@ -0,0 +1,14 @@
1
+ codex-images-mcp
2
+ Copyright (c) 2026 JlMoreno00. Licensed under the MIT License (see LICENSE).
3
+
4
+ This project is a fork of codex-imagen
5
+ https://github.com/VelmoAI/codex-imagen
6
+ Copyright (c) 2026 wauwa. MIT License.
7
+
8
+ The OAuth token loading and refresh in src/codex_images_mcp/_auth.py derive from
9
+ codex-image-gen
10
+ https://github.com/smturtle2/codex-image-gen
11
+ Copyright (c) 2026 Small Turtle 2. MIT License.
12
+
13
+ Not affiliated with or endorsed by OpenAI. "ChatGPT", "Codex" and "gpt-image-2"
14
+ are trademarks or product names of OpenAI.
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.5
2
+ Name: codex-images-mcp
3
+ Version: 0.1.0
4
+ Summary: Self-hosted MCP server for Codex Images (gpt-image-2 on your ChatGPT plan): stdio and HTTP, verifiable artifacts, masks
5
+ Project-URL: Homepage, https://github.com/JlMoreno00/codex-images-mcp
6
+ Project-URL: Repository, https://github.com/JlMoreno00/codex-images-mcp
7
+ Project-URL: Issues, https://github.com/JlMoreno00/codex-images-mcp/issues
8
+ Author: wauwa, JlMoreno00
9
+ License: MIT
10
+ License-File: LICENSE
11
+ License-File: NOTICE
12
+ Keywords: ai,cli,codex,gpt-image,image generation,mcp,openai,sdk
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Multimedia :: Graphics
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: click>=8.1
26
+ Requires-Dist: mcp<2,>=1.27
27
+ Requires-Dist: pillow>=10.0
28
+ Requires-Dist: tomli-w>=1.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: httpx; extra == 'dev'
31
+ Requires-Dist: pytest-mock; extra == 'dev'
32
+ Requires-Dist: pytest>=8; extra == 'dev'
33
+ Requires-Dist: pyyaml; extra == 'dev'
34
+ Requires-Dist: starlette>=0.40; extra == 'dev'
35
+ Requires-Dist: uvicorn>=0.30; extra == 'dev'
36
+ Provides-Extra: http
37
+ Requires-Dist: starlette>=0.40; extra == 'http'
38
+ Requires-Dist: uvicorn>=0.30; extra == 'http'
39
+ Description-Content-Type: text/markdown
40
+
41
+ # codex-images-mcp
42
+
43
+ Generate and edit images from any MCP client with **gpt-image-2 on the ChatGPT plan you already pay for**. No OpenAI API key, no per-image bill.
44
+
45
+ codex-images-mcp is an MCP server for the Codex Images endpoint. It runs locally over stdio, or as a **self-hosted HTTP server** that your laptop, your VPS agents and your Pi / Gentle Shell sessions can share. Every image comes back as a verifiable artifact: SHA-256, byte count, MIME type and real dimensions.
46
+
47
+ > **Unofficial.** Not affiliated with or endorsed by OpenAI. It signs in with your own ChatGPT account and uses the same endpoint as the Codex CLI. You are bound by OpenAI's terms for your account, and image generation counts against your plan's limits.
48
+
49
+ ## What you get
50
+
51
+ - **Two tools**: `codex_images` (generate/edit) and `codex_images_artifact` (fetch an image by URI, inline or through a short-lived signed download).
52
+ - **Batches**: `parallel`, `variants`, `chain` and `branded-parallel` (every image references a shared anchor for brand-consistent sets).
53
+ - **Edits with references and masks**: up to five references per request, HTTPS URLs or inline images.
54
+ - **Native transparency**: real alpha PNGs from the model, with a warning when a result comes back opaque.
55
+ - **Exact output sizes**: `native`, `exact`, `fit` or `cover` post-processing, so a 1200×630 card is 1200×630.
56
+ - **Prompts sent verbatim**: no hidden rewriting model in between.
57
+ - **Optional API-key engine**: set `CODEX_IMAGES_ENGINE=api` with an `OPENAI_API_KEY` to choose the model yourself (Images 2.6 `gpt-image-2.6-sunburst` / `-flare`), with quality up to `max` and complexity control. This engine is billed to your API account. On the default ChatGPT plan route OpenAI chooses the model, and the API selectors (`model`, `quality`, `complexity`) are ignored.
58
+ - **Self-hosting that is safe by default**: built-in bearer auth, refuses to listen publicly without a token, SSRF-hardened URL fetching (HTTPS, public addresses only, pinned IP, no redirects), no server paths in results.
59
+ - **Its own ChatGPT session**: `codex-images-mcp login` uses a device code and keeps a separate session, so it never rotates (and breaks) your Codex app's sign-in.
60
+
61
+ ## Quick start (local, stdio)
62
+
63
+ ```bash
64
+ uvx --from codex-images-mcp codex-images-mcp login # sign in once (device code)
65
+ uvx --from codex-images-mcp codex-images-mcp setup # register in Claude Code, Claude Desktop, Codex, Cursor, OpenCode
66
+ ```
67
+
68
+ Or try it from the terminal:
69
+
70
+ ```bash
71
+ uvx --from codex-images-mcp codex-images-mcp generate "a ceramic mug, studio light" --transparent --pretty
72
+ ```
73
+
74
+ Already signed in to the Codex CLI? codex-images-mcp can use that login **read-only** until its token expires. It never refreshes it; run `login` for a session of its own.
75
+
76
+ ## Self-hosted (HTTP)
77
+
78
+ ```bash
79
+ export CODEX_IMAGES_HTTP_TOKEN=$(openssl rand -hex 32)
80
+ docker compose up -d
81
+ docker compose run --rm codex-images codex-images-mcp login
82
+ ```
83
+
84
+ Then point your clients at `https://your-host/mcp/` with `Authorization: Bearer $CODEX_IMAGES_HTTP_TOKEN`. See [docs/self-hosting.md](docs/self-hosting.md) for the reverse proxy, signed downloads and every setting.
85
+
86
+ ## Pi and Gentle Shell
87
+
88
+ [`pi-codex-images`](packages/pi-codex-images) is a Pi extension for a self-hosted server. It reads the local files you authorize, sends them inline, and writes verified results atomically into your project:
89
+
90
+ ```bash
91
+ pi install npm:pi-codex-images
92
+ ```
93
+
94
+ ## Documentation
95
+
96
+ - [MCP tools reference](docs/mcp.md): inputs, results, error codes.
97
+ - [CLI](docs/cli.md): `generate`, `login`, `logout`, `setup`, `status`, `uninstall`.
98
+ - [Self-hosting](docs/self-hosting.md): Docker, reverse proxy, configuration, security model.
99
+ - [Examples](docs/examples.md): batches, edits, masks, transparency, exact sizes.
100
+ - [Comparison](docs/comparison.md): how this differs from similar projects.
101
+
102
+ ## Credits
103
+
104
+ codex-images-mcp started as a fork of [VelmoAI/codex-imagen](https://github.com/VelmoAI/codex-imagen) by wauwa. The installer and much of the original structure come from there. The OAuth token handling derives from [codex-image-gen](https://github.com/smturtle2/codex-image-gen) by Small Turtle 2. The generation engine was replaced with the native Codex Images endpoint, and the prompt-rewriting and chroma-key layers were removed.
105
+
106
+ ## License
107
+
108
+ MIT. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
@@ -0,0 +1,68 @@
1
+ # codex-images-mcp
2
+
3
+ Generate and edit images from any MCP client with **gpt-image-2 on the ChatGPT plan you already pay for**. No OpenAI API key, no per-image bill.
4
+
5
+ codex-images-mcp is an MCP server for the Codex Images endpoint. It runs locally over stdio, or as a **self-hosted HTTP server** that your laptop, your VPS agents and your Pi / Gentle Shell sessions can share. Every image comes back as a verifiable artifact: SHA-256, byte count, MIME type and real dimensions.
6
+
7
+ > **Unofficial.** Not affiliated with or endorsed by OpenAI. It signs in with your own ChatGPT account and uses the same endpoint as the Codex CLI. You are bound by OpenAI's terms for your account, and image generation counts against your plan's limits.
8
+
9
+ ## What you get
10
+
11
+ - **Two tools**: `codex_images` (generate/edit) and `codex_images_artifact` (fetch an image by URI, inline or through a short-lived signed download).
12
+ - **Batches**: `parallel`, `variants`, `chain` and `branded-parallel` (every image references a shared anchor for brand-consistent sets).
13
+ - **Edits with references and masks**: up to five references per request, HTTPS URLs or inline images.
14
+ - **Native transparency**: real alpha PNGs from the model, with a warning when a result comes back opaque.
15
+ - **Exact output sizes**: `native`, `exact`, `fit` or `cover` post-processing, so a 1200×630 card is 1200×630.
16
+ - **Prompts sent verbatim**: no hidden rewriting model in between.
17
+ - **Optional API-key engine**: set `CODEX_IMAGES_ENGINE=api` with an `OPENAI_API_KEY` to choose the model yourself (Images 2.6 `gpt-image-2.6-sunburst` / `-flare`), with quality up to `max` and complexity control. This engine is billed to your API account. On the default ChatGPT plan route OpenAI chooses the model, and the API selectors (`model`, `quality`, `complexity`) are ignored.
18
+ - **Self-hosting that is safe by default**: built-in bearer auth, refuses to listen publicly without a token, SSRF-hardened URL fetching (HTTPS, public addresses only, pinned IP, no redirects), no server paths in results.
19
+ - **Its own ChatGPT session**: `codex-images-mcp login` uses a device code and keeps a separate session, so it never rotates (and breaks) your Codex app's sign-in.
20
+
21
+ ## Quick start (local, stdio)
22
+
23
+ ```bash
24
+ uvx --from codex-images-mcp codex-images-mcp login # sign in once (device code)
25
+ uvx --from codex-images-mcp codex-images-mcp setup # register in Claude Code, Claude Desktop, Codex, Cursor, OpenCode
26
+ ```
27
+
28
+ Or try it from the terminal:
29
+
30
+ ```bash
31
+ uvx --from codex-images-mcp codex-images-mcp generate "a ceramic mug, studio light" --transparent --pretty
32
+ ```
33
+
34
+ Already signed in to the Codex CLI? codex-images-mcp can use that login **read-only** until its token expires. It never refreshes it; run `login` for a session of its own.
35
+
36
+ ## Self-hosted (HTTP)
37
+
38
+ ```bash
39
+ export CODEX_IMAGES_HTTP_TOKEN=$(openssl rand -hex 32)
40
+ docker compose up -d
41
+ docker compose run --rm codex-images codex-images-mcp login
42
+ ```
43
+
44
+ Then point your clients at `https://your-host/mcp/` with `Authorization: Bearer $CODEX_IMAGES_HTTP_TOKEN`. See [docs/self-hosting.md](docs/self-hosting.md) for the reverse proxy, signed downloads and every setting.
45
+
46
+ ## Pi and Gentle Shell
47
+
48
+ [`pi-codex-images`](packages/pi-codex-images) is a Pi extension for a self-hosted server. It reads the local files you authorize, sends them inline, and writes verified results atomically into your project:
49
+
50
+ ```bash
51
+ pi install npm:pi-codex-images
52
+ ```
53
+
54
+ ## Documentation
55
+
56
+ - [MCP tools reference](docs/mcp.md): inputs, results, error codes.
57
+ - [CLI](docs/cli.md): `generate`, `login`, `logout`, `setup`, `status`, `uninstall`.
58
+ - [Self-hosting](docs/self-hosting.md): Docker, reverse proxy, configuration, security model.
59
+ - [Examples](docs/examples.md): batches, edits, masks, transparency, exact sizes.
60
+ - [Comparison](docs/comparison.md): how this differs from similar projects.
61
+
62
+ ## Credits
63
+
64
+ codex-images-mcp started as a fork of [VelmoAI/codex-imagen](https://github.com/VelmoAI/codex-imagen) by wauwa. The installer and much of the original structure come from there. The OAuth token handling derives from [codex-image-gen](https://github.com/smturtle2/codex-image-gen) by Small Turtle 2. The generation engine was replaced with the native Codex Images endpoint, and the prompt-rewriting and chroma-key layers were removed.
65
+
66
+ ## License
67
+
68
+ MIT. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
@@ -0,0 +1,40 @@
1
+ # Releasing
2
+
3
+ A `vX.Y.Z` tag runs `.github/workflows/release.yml`, which publishes three artifacts from the same commit:
4
+
5
+ | Artifact | Where | Auth |
6
+ |---|---|---|
7
+ | Python package `codex-images-mcp` | PyPI | Trusted Publishing (OIDC, no stored token) |
8
+ | Docker image `codex-images-mcp` (amd64, arm64) | `ghcr.io/jlmoreno00/codex-images-mcp` | `GITHUB_TOKEN` |
9
+ | Pi extension `pi-codex-images` | npm, with provenance | `NPM_TOKEN` secret |
10
+
11
+ Each job fails if the tag does not match the version it publishes.
12
+
13
+ ## One-time setup
14
+
15
+ 1. **PyPI**: on https://pypi.org/manage/account/publishing/ add a *pending publisher* for project `codex-images-mcp`, owner `JlMoreno00`, repository `codex-images-mcp`, workflow `release.yml`, environment `pypi`. Then create the `pypi` environment under **Settings → Environments** (optionally with required reviewers).
16
+ 2. **npm**: create a granular access token that can publish `pi-codex-images` and add it as the repository secret `NPM_TOKEN`.
17
+ 3. **GHCR**: nothing to configure. After the first push, open the package settings and set its visibility to public.
18
+
19
+ ## Each release
20
+
21
+ 1. Bump the version in all three places:
22
+ - `pyproject.toml` (`version`)
23
+ - `src/codex_images_mcp/__init__.py` (`__version__`)
24
+ - `packages/pi-codex-images/package.json` (`version`, then `npm install` to refresh the lockfile)
25
+ 2. Add the release notes to `CHANGELOG.md`.
26
+ 3. Commit, push to `main`, wait for CI to pass.
27
+ 4. Tag and push the tag:
28
+
29
+ ```bash
30
+ git tag v0.1.1
31
+ git push origin v0.1.1
32
+ ```
33
+
34
+ 5. Watch https://github.com/JlMoreno00/codex-images-mcp/actions, then check a clean install:
35
+
36
+ ```bash
37
+ uvx --from codex-images-mcp codex-images-mcp --version
38
+ docker run --rm ghcr.io/jlmoreno00/codex-images-mcp:latest codex-images-mcp --version
39
+ npm view pi-codex-images version
40
+ ```
@@ -0,0 +1,20 @@
1
+ # Example deployment. Put a TLS reverse proxy (Caddy, nginx, Traefik) in front
2
+ # and point CODEX_IMAGES_PUBLIC_BASE_URL at its public HTTPS origin if you want
3
+ # signed downloads for large artifacts.
4
+ services:
5
+ codex-images:
6
+ build: .
7
+ image: ghcr.io/jlmoreno00/codex-images-mcp:latest
8
+ restart: unless-stopped
9
+ ports:
10
+ - "127.0.0.1:8324:8324"
11
+ environment:
12
+ CODEX_IMAGES_HTTP_TOKEN: ${CODEX_IMAGES_HTTP_TOKEN:?set a random token}
13
+ # CODEX_IMAGES_PUBLIC_BASE_URL: https://images.example.com
14
+ # Optional paid engine with model choice (Images 2.6):
15
+ # CODEX_IMAGES_ENGINE: api
16
+ # OPENAI_API_KEY: ${OPENAI_API_KEY}
17
+ volumes:
18
+ # ChatGPT session (auth.json) and generated artifacts.
19
+ # Sign in once: docker compose run --rm codex-images codex-images-mcp login
20
+ - ./data:/data