Skip to content

Commit 8232bd3

Browse files
committed
Release 0.4.0: MCP read operations and safe publishing path
This release makes the optional MCP server significantly more useful for inspecting and preparing publications without steering agents toward immediate publishing.
1 parent 24ab63d commit 8232bd3

12 files changed

Lines changed: 552 additions & 56 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ ENV/
110110
env.bak/
111111
venv.bak/
112112

113+
# Gemini CLI and Testing artifacts
114+
.gemini/
115+
tmp_pytest/
116+
113117
# Spyder project settings
114118
.spyderproject
115119
.spyproject

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ repos:
1414
hooks:
1515
- id: isort
1616
name: isort (python)
17+
args: ["--profile", "black"]

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Changelog
22

3+
## 0.4.0
4+
5+
### Added
6+
7+
- Seven new MCP tools for read operations and safe publishing: `get_status`, `list_publications`, `list_drafts`, `get_draft`, `schedule_draft`, `unschedule_draft`, and `publish_draft_checked`.
8+
- Pre-publish validation, interactive confirmation requirements, and no-email defaults for the new `publish_draft_checked` MCP tool.
9+
- Verified MCP client configuration examples in `docs/mcp.md`.
10+
- Documentation for Gemini CLI with Vertex AI (`docs/gemini-vertex-ai.md`).
11+
12+
### Improved
13+
14+
- Simplify MCP draft creation by routing through the existing `Api.create_draft_from_markdown` SDK helper, preserving response format.
15+
- Document the legacy `publish_draft` MCP tool as the compatibility interface.
16+
- Bump `cryptography` dependency from `48.0.1` to `50.0.0` (#68).
17+
318
## 0.3.0
419

520
### Added

GEMINI.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# python-substack maintainer instructions
2+
3+
## Project
4+
5+
This repository is a Python 3.10+ library, CLI, and optional MCP server for
6+
creating and managing Substack drafts from Markdown. Poetry owns dependencies,
7+
packaging, scripts, and the lock file. The public package is `python-substack`.
8+
9+
Read the relevant implementation, tests, and documentation before editing.
10+
Keep changes focused and preserve existing public interfaces, defaults, JSON
11+
keys, environment variables, console scripts, and MCP tool signatures through
12+
the 1.x series as required by `docs/compatibility.md`.
13+
14+
## Development
15+
16+
- Use the existing style and the simplest working implementation.
17+
- Add a regression test for every bug fix and offline tests for new behavior.
18+
- Update user-facing documentation and `CHANGELOG.md` for behavior changes.
19+
- Do not edit `poetry.lock` unless dependency declarations change.
20+
- Never expose or commit `.env` contents, passwords, cookies, credentials,
21+
tokens, captured request headers, or local service-account files.
22+
- Preserve user changes in a dirty worktree. Do not reset, restore, or delete
23+
unrelated work.
24+
25+
Install and validate with:
26+
27+
```bash
28+
poetry install --all-extras
29+
poetry run pytest -q -m "not live" --strict-markers
30+
poetry run pre-commit run --all-files
31+
```
32+
33+
Live tests call Substack and create disposable drafts. Run them only after the
34+
maintainer explicitly authorizes the live operation and confirms suitable test
35+
credentials. Live tests must never publish, and their drafts must be removed.
36+
37+
## Releases
38+
39+
Follow `docs/releasing.md` exactly. Use `/release:prepare X.Y.Z` to prepare a
40+
candidate and `/release:verify` to validate it.
41+
42+
- Keep both version files unchanged during ordinary development.
43+
- For a release candidate, synchronize `pyproject.toml` and
44+
`substack/__init__.py`, prepend `CHANGELOG.md`, and add
45+
`docs/releases/X.Y.Z.md` using only verified changes.
46+
- Treat the Git tag, GitHub release, and built distributions as one immutable
47+
release. Never reuse a published version.
48+
- Do not commit, tag, push, create a GitHub release, publish to PyPI, run live
49+
tests, or announce a release without explicit maintainer authorization for
50+
that action.
51+
- Never bypass a failing check. Report the failure and preserve its output.
52+
- Publish only from the exact commit that passed CI, using tag `vX.Y.Z`.
53+
54+
At handoff, state files changed, checks run, checks not run, and any external
55+
actions still requiring maintainer approval.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ See [MCP server](docs/mcp.md) for the tool list and safety notes.
227227
- [Low-level Python API](docs/low-level-api.md)
228228
- [YAML drafts](docs/yaml.md)
229229
- [MCP server](docs/mcp.md)
230+
- [Gemini CLI with Vertex AI](docs/gemini-vertex-ai.md)
230231
- [Safety and publishing behavior](docs/safety.md)
231232
- [Troubleshooting](docs/troubleshooting.md)
232233
- [Compatibility policy](docs/compatibility.md)

docs/gemini-vertex-ai.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
layout: default
3+
title: Gemini CLI with Vertex AI
4+
---
5+
6+
# Gemini CLI with Vertex AI
7+
8+
The repository includes project settings, maintainer instructions, and release
9+
commands for Gemini CLI. The project settings require Vertex AI authentication.
10+
Routine file edits, repository inspection, dependency setup, offline tests, and
11+
pre-commit checks are pre-approved. Commands that commit, tag, push, publish,
12+
or run live tests still require explicit approval.
13+
14+
## Prerequisites
15+
16+
- Node.js 20 or later.
17+
- Gemini CLI installed with `npm install -g @google/gemini-cli`.
18+
- Google Cloud CLI with Application Default Credentials (ADC).
19+
- A Google Cloud project with billing and the Vertex AI API enabled.
20+
- The Vertex AI User role (`roles/aiplatform.user`) on that project.
21+
22+
Authenticate locally:
23+
24+
```powershell
25+
gcloud auth application-default login
26+
gcloud services enable aiplatform.googleapis.com --project YOUR_PROJECT_ID
27+
```
28+
29+
Copy the checked-in environment template and set the project and region:
30+
31+
```powershell
32+
Copy-Item .gemini/.env.example .gemini/.env
33+
```
34+
35+
`.gemini/.env` is ignored by Git. Do not put API keys or service-account JSON
36+
in the repository. ADC is preferred for local maintainer work.
37+
38+
## Start Gemini
39+
40+
Install the project dependencies, then start Gemini from the repository root:
41+
42+
```powershell
43+
poetry install --all-extras
44+
gemini
45+
```
46+
47+
Trust the folder when Gemini CLI asks so it can load the checked-in project
48+
settings and custom commands. Use `/memory show` to confirm `GEMINI.md` is
49+
loaded and `/commands list` to confirm the release commands are available.
50+
51+
## Release workflow
52+
53+
Prepare a candidate without publishing it:
54+
55+
```text
56+
/release:prepare 0.4.0
57+
```
58+
59+
Review the diff, then run the independent release verification:
60+
61+
```text
62+
/release:verify
63+
```
64+
65+
Both commands deliberately stop before live Substack tests, commits, tags,
66+
pushes, GitHub releases, PyPI publication, and announcements. Authorize those
67+
steps explicitly only after reviewing the candidate and confirming CI passed.

docs/mcp.md

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,59 @@ python -c "from substack_mcp.mcp_server import main; main()"
2121
The server uses the same `EMAIL`, `PASSWORD`, `PUBLICATION_URL`,
2222
`COOKIES_PATH`, and `COOKIES_STRING` environment variables as the SDK.
2323

24-
Available tools:
24+
## Available Tools
2525

26-
- `post_draft_from_markdown(...)`
27-
- `put_draft(draft_id, update_payload)`
28-
- `add_tags(draft_id, tags)`
29-
- `prepublish_draft(draft_id)`
30-
- `publish_draft(draft_id, send=True, share_automatically=False)`
26+
The server exposes tools for reading content, managing drafts, and publishing.
3127

32-
`post_draft_from_markdown` creates an unpublished draft unless `publish=True`
33-
is explicitly supplied. `publish_draft` publishes immediately and defaults to
34-
sending email. Review the draft ID and arguments before invoking it.
28+
**Read Operations (Safe to run automatically):**
29+
- `get_status()` - Verify authentication and get basic user/publication information.
30+
- `list_publications()` - List all publications you have access to.
31+
- `list_drafts(filter="draft", offset=0, limit=25)` - View recent drafts.
32+
- `get_draft(draft_id)` - Read the content and metadata of a specific draft.
3533

36-
The server currently exposes the compatibility tools listed above.
34+
**Draft Creation and Reversible Writes:**
35+
- `post_draft_from_markdown(...)` - Creates an unpublished draft from Markdown.
36+
- `put_draft(draft_id, update_payload)` - Update draft metadata (e.g. slug).
37+
- `add_tags(draft_id, tags)` - Attach tags to a draft.
38+
- `prepublish_draft(draft_id)` - Run Substack's pre-publication checks on a draft.
39+
- `schedule_draft(draft_id, at)` - Schedule a draft for publication at an ISO timestamp.
40+
- `unschedule_draft(draft_id)` - Remove a publication schedule from a draft.
41+
42+
**Publishing Operations (Use with caution):**
43+
- `publish_draft_checked(draft_id, confirm=False, send=False, share_automatically=False)` - **Recommended**. A safer publishing path that requires explicit confirmation (`confirm=True`), runs prepublish checks automatically, and defaults to *not* sending emails.
44+
- `publish_draft(draft_id, send=True, share_automatically=False)` - *Legacy compatibility interface*. Publishes immediately and defaults to sending email.
45+
46+
## Client Configuration Examples
47+
48+
### Claude Desktop
49+
50+
You can configure Claude Desktop to use `python-substack` as an MCP server by adding it to your `claude_desktop_config.json`:
51+
52+
```json
53+
{
54+
"mcpServers": {
55+
"substack": {
56+
"command": "substack-mcp",
57+
"env": {
58+
"EMAIL": "your-email@example.com",
59+
"PASSWORD": "your-password"
60+
}
61+
}
62+
}
63+
}
64+
```
65+
66+
If you prefer to use session cookies instead of a password, use the `COOKIES_STRING` variable:
67+
68+
```json
69+
{
70+
"mcpServers": {
71+
"substack": {
72+
"command": "substack-mcp",
73+
"env": {
74+
"COOKIES_STRING": "cookie1=value1; cookie2=value2"
75+
}
76+
}
77+
}
78+
}
79+
```

docs/releases/0.4.0.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
layout: default
3+
title: Release 0.4.0
4+
parent: Releases
5+
---
6+
7+
# Release 0.4.0
8+
9+
This release makes the optional MCP server significantly more useful for inspecting and preparing publications without steering agents toward immediate publishing.
10+
11+
### Added
12+
13+
- Seven new MCP tools for read operations and safe publishing: `get_status`, `list_publications`, `list_drafts`, `get_draft`, `schedule_draft`, `unschedule_draft`, and `publish_draft_checked`.
14+
- Pre-publish validation, interactive confirmation requirements, and no-email defaults for the new `publish_draft_checked` MCP tool.
15+
- Verified MCP client configuration examples in `docs/mcp.md`.
16+
- Documentation for Gemini CLI with Vertex AI (`docs/gemini-vertex-ai.md`).
17+
18+
### Improved
19+
20+
- Simplify MCP draft creation by routing through the existing `Api.create_draft_from_markdown` SDK helper, preserving response format.
21+
- Document the legacy `publish_draft` MCP tool as the compatibility interface.
22+
- Bump `cryptography` dependency from `48.0.1` to `50.0.0` (#68).

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "python-substack"
3-
version = "0.3.0"
3+
version = "0.4.0"
44
description = "Write and safely manage Substack drafts from Markdown with Python, CLI, and MCP."
55
authors = ["Paolo Mazza <mazzapaolo2019@gmail.com>"]
66
license = "MIT"

substack/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
__author__ = "Paolo Mazza"
44
__email__ = "mazzapaolo2019@gmail.com"
55
__license__ = "MIT License"
6-
__version__ = "0.3.0"
6+
__version__ = "0.4.0"
77
__url__ = "https://github.com/ma2za/python-substack"
88
__download_url__ = "https://pypi.python.org/pypi/python-substack"
99
__description__ = (

0 commit comments

Comments
 (0)