This commit is contained in:
+16
-4
@@ -14,13 +14,25 @@ app inside another person’s ChatGPT account and never stores OAuth tokens.
|
||||
4. Start a new chat or refresh the app connection.
|
||||
5. Test with: `Покажи активные проекты с датой завершения и статусом.`
|
||||
|
||||
The server publishes OAuth 2.1 discovery for the root resource and supports
|
||||
ChatGPT Client ID Metadata Documents (CIMD), PKCE S256 and the
|
||||
`private_key_jwt` token-endpoint authentication method. Keep the app URL as
|
||||
`https://shd.xyz.su/mcp`; the retired `/mcp/system-data` resource is not a
|
||||
valid replacement for the root MCP resource.
|
||||
|
||||
The expected flow is:
|
||||
|
||||
1. ChatGPT calls `shd_list_projects` with `archived: false`.
|
||||
2. ChatGPT may call `shd_render_projects_widget` with the returned project
|
||||
array.
|
||||
3. The widget renders the sorted register and can call `shd_get_project` for
|
||||
a selected row.
|
||||
2. ChatGPT may call a module render tool after the corresponding list tool:
|
||||
`shd_render_projects_widget`, `shd_render_documents_widget`,
|
||||
`shd_render_tasks_widget`, `shd_render_finance_widget` or
|
||||
`shd_render_crm_widget`.
|
||||
3. The selected widget renders a read-only register and can call the matching
|
||||
detail tool for one selected row.
|
||||
|
||||
The widget resources are versioned at `ui://shd/active-projects/v1.html`,
|
||||
`ui://shd/documents/v1.html`, `ui://shd/tasks/v1.html`,
|
||||
`ui://shd/finance/v1.html` and `ui://shd/crm/v1.html`.
|
||||
|
||||
The MCP tools remain usable without the widget. A failed OAuth connection is
|
||||
an account/endpoint configuration problem, not a missing token in this repo.
|
||||
|
||||
@@ -35,7 +35,7 @@ codex plugin add shd-mcp-plugin@shd-public
|
||||
The same commands work with the Gitea clone URL:
|
||||
|
||||
```bash
|
||||
git clone https://git.xyz.su/shd/shd-mcp-plugin.git
|
||||
git clone https://git.xyz.su/markkats/shd-mcp-plugin.git
|
||||
```
|
||||
|
||||
After installation, start a new Codex thread so the plugin Skills are loaded.
|
||||
@@ -62,6 +62,18 @@ The backend serves the checked-in widget artifact at
|
||||
`ui://shd/active-projects/v1.html`; its manifest and `SHA256SUMS` are kept next
|
||||
to the HTML resource under `plugins/shd-mcp-plugin/widgets/active-projects/v1/`.
|
||||
|
||||
The same read-only data/render contract is available for Documents, Tasks,
|
||||
Finance and CRM:
|
||||
|
||||
- `shd_render_documents_widget` → `ui://shd/documents/v1.html`;
|
||||
- `shd_render_tasks_widget` → `ui://shd/tasks/v1.html`;
|
||||
- `shd_render_finance_widget` → `ui://shd/finance/v1.html`;
|
||||
- `shd_render_crm_widget` → `ui://shd/crm/v1.html`.
|
||||
|
||||
Each widget accepts normalized records from its list tool, keeps the plain
|
||||
structured response as a fallback and uses the MCP Apps bridge before the
|
||||
`window.openai` compatibility API.
|
||||
|
||||
The official OpenAI directory is optional. It is useful for public discovery,
|
||||
one-click installation and review of a public app; it is not required for an
|
||||
internal team or a manually added ChatGPT custom app. See the official
|
||||
@@ -85,6 +97,11 @@ token may be used only if the selected MCP client and SHD deployment
|
||||
explicitly support it; enter it in that client's secure connection settings,
|
||||
never in `.mcp.json`, Skills or an issue.
|
||||
|
||||
SHD OAuth supports ChatGPT CIMD clients with PKCE S256 and
|
||||
`private_key_jwt` client authentication. The server validates the client
|
||||
assertion against ChatGPT's published JWKS; the plugin package never stores
|
||||
the assertion, access token or refresh token.
|
||||
|
||||
For ChatGPT or another MCP client without Codex plugin installation, add the
|
||||
same HTTPS endpoint as a custom MCP app and complete OAuth there. The public
|
||||
repository packages the workflows; it does not grant access to the server.
|
||||
@@ -109,9 +126,44 @@ From the repository root:
|
||||
|
||||
```bash
|
||||
python3 -m unittest discover -s tests -v
|
||||
sha256sum --check plugins/shd-mcp-plugin/widgets/active-projects/v1/SHA256SUMS
|
||||
python3 scripts/check_skill_mcp_parity.py --strict
|
||||
for checksum in plugins/shd-mcp-plugin/widgets/*/v1/SHA256SUMS; do
|
||||
(cd "$(dirname "$checksum")" && sha256sum --check SHA256SUMS)
|
||||
done
|
||||
```
|
||||
|
||||
Refresh the catalog snapshot after a backend MCP catalog change:
|
||||
|
||||
```bash
|
||||
node /var/www/admin/scripts/mcp/mcp-catalog.mjs | \
|
||||
python3 scripts/update_mcp_tool_catalog.py
|
||||
```
|
||||
|
||||
The runtime smoke harness checks OAuth metadata, PKCE S256 support, the
|
||||
authenticated MCP handshake and all five widget resources. It never assumes
|
||||
an endpoint or prints a token:
|
||||
|
||||
```bash
|
||||
SHD_MCP_RUNTIME_URL=https://approved-host.example/mcp \
|
||||
SHD_MCP_ACCESS_TOKEN="$TOKEN" \
|
||||
node scripts/mcp-runtime-smoke.mjs --require-auth
|
||||
```
|
||||
|
||||
For a full authorization-code/PKCE browser check, provide an already
|
||||
authenticated Playwright storage state and the client redirect registered with
|
||||
SHD:
|
||||
|
||||
```bash
|
||||
SHD_MCP_RUNTIME_URL=https://approved-host.example/mcp \
|
||||
SHD_OAUTH_E2E_STORAGE_STATE=/secure/oauth-state.json \
|
||||
SHD_OAUTH_E2E_CLIENT_ID="$OAUTH_CLIENT_ID" \
|
||||
SHD_OAUTH_E2E_REDIRECT_URI="$OAUTH_REDIRECT_URI" \
|
||||
node scripts/mcp-oauth-e2e.mjs
|
||||
```
|
||||
|
||||
The browser/OAuth checks are opt-in deployment checks and are not run in the
|
||||
public static-package workflow.
|
||||
|
||||
The full release boundary, including backend deployment and authenticated
|
||||
ChatGPT/browser checks, is documented in [RELEASE.md](RELEASE.md).
|
||||
|
||||
|
||||
+24
-5
@@ -9,7 +9,10 @@ Run from the repository root:
|
||||
|
||||
```bash
|
||||
python3 -m unittest discover -s tests -v
|
||||
sha256sum --check plugins/shd-mcp-plugin/widgets/active-projects/v1/SHA256SUMS
|
||||
python3 scripts/check_skill_mcp_parity.py --strict
|
||||
for checksum in plugins/shd-mcp-plugin/widgets/*/v1/SHA256SUMS; do
|
||||
(cd "$(dirname "$checksum")" && sha256sum --check SHA256SUMS)
|
||||
done
|
||||
```
|
||||
|
||||
The Codex plugin validator is an additional environment check when available:
|
||||
@@ -21,12 +24,27 @@ python3 /home/vscode/.codex/skills/.system/plugin-creator/scripts/validate_plugi
|
||||
|
||||
## Widget changes
|
||||
|
||||
The URI `ui://shd/active-projects/v1.html` is a cache key. For a breaking HTML,
|
||||
Every `ui://shd/<module>/v1.html` URI is a cache key. For a breaking HTML,
|
||||
JavaScript or CSS change, create `v2/`, update the manifest and backend resource
|
||||
registration together, then regenerate `SHA256SUMS`. Keep the widget useful
|
||||
registration together, then regenerate `SHA256SUMS`. Keep each widget useful
|
||||
without ChatGPT-specific APIs: the MCP Apps bridge is the baseline and
|
||||
`window.openai` is only a compatibility extension.
|
||||
|
||||
The public package also contains a one-way Skill-to-catalog parity check. The
|
||||
catalog is a checked-in name snapshot, so a Skill cannot silently reference an
|
||||
unpublished MCP tool. Refresh it from the backend catalog before publishing.
|
||||
|
||||
`scripts/mcp-runtime-smoke.mjs` checks OAuth metadata, authenticated MCP
|
||||
negotiation and the active-projects/Documents/Tasks/Finance/CRM resources.
|
||||
`scripts/mcp-oauth-e2e.mjs` is an opt-in Playwright check for the complete
|
||||
authorization-code + PKCE exchange using an already authenticated storage
|
||||
state. Neither script stores credentials or belongs in the static CI job.
|
||||
|
||||
The OAuth server metadata must advertise the token-endpoint methods used by the
|
||||
ChatGPT CIMD document (`none` and `private_key_jwt`). Before a release, verify
|
||||
that the server accepts the ChatGPT `RS256` client assertion, validates its
|
||||
JWKS signature and rejects a repeated `jti`.
|
||||
|
||||
## Publish and deploy gates
|
||||
|
||||
1. Commit and push the same reviewed revision to the GitHub and Gitea mirrors.
|
||||
@@ -34,8 +52,9 @@ without ChatGPT-specific APIs: the MCP Apps bridge is the baseline and
|
||||
used by `SHD_MCP_WIDGET_ROOT`, or at the repository path documented by the
|
||||
backend loader.
|
||||
3. Run the backend MCP verification and a real authenticated OAuth/tool call.
|
||||
4. Reconnect the custom ChatGPT app and test the active-projects flow, including
|
||||
the plain structured fallback and widget actions.
|
||||
4. Reconnect the custom ChatGPT app and test active projects, Documents, Tasks,
|
||||
Finance and CRM, including the plain structured fallback and each widget’s
|
||||
refresh/detail action.
|
||||
5. Record the exact revision and any runtime/browser checks. Static tests do
|
||||
not prove OAuth, ACLs, production hosting or ChatGPT rendering.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user