Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"name": "nutrient",
"source": "./plugins/nutrient",
"description": "Parse, extract from and classify documents with Nutrient DWS: OCR for scans, Markdown with layout, structured fields with citations, and labels, as stored runs in your Nutrient account.",
"version": "1.0.0",
"version": "1.0.1",
"author": { "name": "Nutrient", "url": "https://www.nutrient.io" },
"homepage": "https://www.nutrient.io/api/",
"license": "MIT"
Expand Down
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ OpenAI's directory takes a ZIP of `plugins/nutrient`, uploaded for each release.

Never change `name` in `plugin.json`: it is the plugin's permanent identity.

Keep `scopes` in `.mcp.json`. Without it, Codex asks for every scope the authorization server lists instead of the
service's own, and the service can't exchange that grant, so every tool call fails. Claude Code asks for the same pair,
taken from the service's sign-in challenge, and ChatGPT for the scopes the service advertises. `ci/check.py` checks it.

## Refreshing the tool snapshot

`ci/tools.json` and `ci/tools-chatgpt.json` are the catalogs Hosted MCP (`hosted-mcp/` in the private Nutrient monorepo)
Expand Down
3 changes: 3 additions & 0 deletions ci/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ def collect(node, names):
servers = load(PLUGIN / ".mcp.json").get("mcpServers", {})
check(list(servers) == ["nutrient"] and servers["nutrient"].get("type") == "http" and servers["nutrient"].get("url") == SERVICE,
f".mcp.json declares one server, nutrient, at {SERVICE} over HTTP (OpenAI connects one server per plugin)")
# Without scopes, Codex asks for every scope the authorization server lists, and the service can't use that grant.
check(servers.get("nutrient", {}).get("scopes") == ["mcp:invoke", "offline_access"],
".mcp.json requests the service's own scopes, mcp:invoke and offline_access")

skills = sorted((PLUGIN / "skills").glob("*/SKILL.md"))
check(len(skills) > 0, "the plugin has at least one skill")
Expand Down
2 changes: 1 addition & 1 deletion plugins/nutrient/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "nutrient",
"displayName": "Nutrient",
"version": "1.0.0",
"version": "1.0.1",
"description": "Parse, extract from and classify documents with Nutrient DWS: OCR for scans, Markdown with layout, structured fields with citations, and labels, as stored runs in your Nutrient account.",
"author": { "name": "Nutrient", "url": "https://www.nutrient.io" },
"homepage": "https://www.nutrient.io/api/",
Expand Down
2 changes: 1 addition & 1 deletion plugins/nutrient/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nutrient",
"version": "1.0.0",
"version": "1.0.1",
"description": "Parse, extract from and classify documents with Nutrient DWS: OCR for scans, Markdown with layout, structured fields with citations, and labels, as stored runs in your Nutrient account.",
"author": {
"name": "Nutrient",
Expand Down
6 changes: 5 additions & 1 deletion plugins/nutrient/.mcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
"mcpServers": {
"nutrient": {
"type": "http",
"url": "https://mcp.nutrient.io/mcp"
"url": "https://mcp.nutrient.io/mcp",
"scopes": [
"mcp:invoke",
"offline_access"
]
}
}
}
9 changes: 6 additions & 3 deletions plugins/nutrient/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ file is attached to the chat.

## Use it

1. Add the plugin, then connect the Nutrient connector and sign in with your Nutrient account. In Claude Code, install it
with `/plugin install nutrient --marketplace PSPDFKit-labs/nutrient-mcp-plugins`; in Codex, with
`codex plugin marketplace add PSPDFKit-labs/nutrient-mcp-plugins` and `codex plugin add nutrient@nutrient`.
1. Add the plugin, then connect the Nutrient connector and sign in with your Nutrient account. The tools appear once
you're signed in.
- In Claude Code, install it with `/plugin install nutrient --marketplace PSPDFKit-labs/nutrient-mcp-plugins`, then
run `/mcp`, choose `plugin:nutrient:nutrient` and sign in.
- In Codex, install it with `codex plugin marketplace add PSPDFKit-labs/nutrient-mcp-plugins` and
`codex plugin add nutrient@nutrient`, sign in with `codex mcp login nutrient`, then start a new session.
2. Attach a PDF, Office document or image, point to a file on disk or an HTTPS link, and ask to parse it, convert it to
Markdown, extract fields or tables, or classify it.
3. The assistant sends the file to your Nutrient account and returns the result: Markdown with layout, structured fields
Expand Down
Loading