Guard Core as a ChatGPT plugin¶
The same tools that power the local MCP server are also served remotely at
https://mcp.guard-core.com/mcp and packaged as a ChatGPT plugin, so ChatGPT
(and Codex, and any MCP client) can validate Guard configs, search the
documentation and run payloads through the real detection engine.
Architecture¶
ChatGPT (MCP client)
|
| 1. POST https://mcp.guard-core.com/mcp -> 401 + WWW-Authenticate
| 2. GET /.well-known/oauth-protected-resource -> points at the platform API
| 3. GET https://api.guard-core.com/.well-known/oauth-authorization-server
| 4. Browser sign-in + consent (guard-core account, PKCE, RS256)
| 5. Bearer access token on every MCP request
v
guard-core-mcp hosted (streamable-http, all nine tools, latest pinned releases)
The hosted server is a pure OAuth 2.1 resource server: it verifies RS256
access tokens against the platform API's JWKS and checks the mcp scope.
It keeps no user data; configs and payloads sent to validate_config and
check_payload are processed transiently and never persisted or logged.
Environment variables¶
| Variable | Required | Purpose |
|---|---|---|
GUARD_CORE_MCP_PUBLIC_URL |
yes | Public origin of the server, advertised as the OAuth resource (https://mcp.guard-core.com) |
GUARD_CORE_MCP_OAUTH_ISSUER |
yes | Authorization server origin (https://api.guard-core.com) |
GUARD_CORE_MCP_OAUTH_JWKS_URL |
one of two | Where to fetch signing keys (https://api.guard-core.com/.well-known/jwks.json) |
GUARD_CORE_MCP_OAUTH_JWKS |
one of two | Inline JWKS JSON, for tests and air-gapped runs; wins over the URL |
GUARD_CORE_MCP_OAUTH_AUDIENCE |
no | Expected aud claim; defaults to GUARD_CORE_MCP_PUBLIC_URL |
GUARD_CORE_MCP_OAUTH_SCOPE |
no | Required scope; defaults to mcp |
GUARD_CORE_MCP_HTTP_HOST |
no | Bind host; defaults to 127.0.0.1 |
GUARD_CORE_MCP_HTTP_PORT |
no | Bind port; defaults to 8020 |
Running it¶
uv sync --extra hosted
export GUARD_CORE_MCP_PUBLIC_URL=https://mcp.guard-core.com
export GUARD_CORE_MCP_OAUTH_ISSUER=https://api.guard-core.com
export GUARD_CORE_MCP_OAUTH_JWKS_URL=https://api.guard-core.com/.well-known/jwks.json
make run-http
Or use the container image, which is what the platform deploys:
docker run -p 8020:8020 \
-e GUARD_CORE_MCP_PUBLIC_URL=https://mcp.guard-core.com \
-e GUARD_CORE_MCP_OAUTH_ISSUER=https://api.guard-core.com \
-e GUARD_CORE_MCP_OAUTH_JWKS_URL=https://api.guard-core.com/.well-known/jwks.json \
ghcr.io/guard-core/guard-core-mcp:v1.4.5
The image installs the hosted extra, so versions reports the exact
guard-core, fastapi-guard and guard-agent releases the container was built
with. The lockfile pins those at build time; refresh them with
uv lock --upgrade when a new engine release ships.
Testing in ChatGPT developer mode¶
- Settings -> Security and login -> enable Developer mode.
- In ChatGPT Plugins, add a connector with the URL
https://mcp.guard-core.com/mcp. - ChatGPT discovers the OAuth metadata and opens the guard-core sign-in; sign in, approve the consent screen.
- From the homepage, switch the tab from Chat to Work, type
@and pick Guard Core. - Ask: "Would fastapi-guard block POST /login with body user=admin' OR 1=1--?" and confirm
check_payloadreports a threat.
Local development against a local API¶
Point every variable at localhost, generate a test signing key on the API side, and pass the public half inline:
GUARD_CORE_MCP_PUBLIC_URL=http://127.0.0.1:8020 \
GUARD_CORE_MCP_OAUTH_ISSUER=http://127.0.0.1:8000 \
GUARD_CORE_MCP_OAUTH_JWKS='{"keys":[ ...public jwk... ]}' \
make run-http
The e2e tests in tests/test_e2e_http.py do exactly this with a throwaway
RSA key.
Plugin package¶
plugin/ holds the directory submission package: plugin.json (identity and
the com.openai presentation metadata), mcp.json (the remote server
declaration) and skills/guard-core/SKILL.md (tool-selection guidance that
ships to the model). The icons under plugin/assets/ are generated
placeholders; swap in official brand assets before submitting if you have
them.
Submission checklist¶
- [ ] DNS record for
mcp.guard-core.comand the Let's Encrypt certificate - [ ] Platform API deployed with the OAuth authorization server enabled
- [ ] Signing key generated (
scripts/generate_oauth_signing_key.pyin guard-core-app) and stored as a secret - [ ] ChatGPT client registered on the OpenAI platform; its redirect URI and client id added to the API's
OAUTH_SERVER_CLIENTS - [ ] Developer-mode test loop passes end to end
- [ ] Privacy policy at guard-core.com/privacy mentions the plugin connection and transient payload processing
- [ ] Upload
plugin/through the plugin submission portal and pass review