From adobe-pack
Installs and configures Adobe OAuth Server-to-Server credentials; sets up SDKs for Firefly Services, PDF Services, I/O Runtime in Node.js or Python.
How this skill is triggered — by the user, by Claude, or both
Slash command
/adobe-pack:adobe-install-authThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Set up Adobe Developer Console OAuth Server-to-Server credentials and install the appropriate SDK for your use case. As of January 2025, JWT (Service Account) credentials are deprecated -- all new integrations must use OAuth Server-to-Server.
Set up Adobe Developer Console OAuth Server-to-Server credentials and install the appropriate SDK for your use case. As of January 2025, JWT (Service Account) credentials are deprecated -- all new integrations must use OAuth Server-to-Server.
client_id, client_secret, and scopes# Firefly Services (Photoshop API, Lightroom API, Firefly API)
npm install @adobe/firefly-apis @adobe/photoshop-apis @adobe/lightroom-apis
# PDF Services (create, extract, convert, generate documents)
npm install @adobe/pdfservices-node-sdk
# Adobe I/O Events (webhooks, event-driven)
npm install @adobe/aio-lib-events
# Adobe I/O SDK (App Builder, Runtime actions)
npm install @adobe/aio-sdk
# Adobe I/O CLI (global install for aio commands)
npm install -g @adobe/aio-cli
# Python — PDF Services
pip install pdfservices-sdk
# .env (NEVER commit — add to .gitignore)
ADOBE_CLIENT_ID=your_client_id_from_console
ADOBE_CLIENT_SECRET=your_client_secret_from_console
ADOBE_SCOPES=openid,AdobeID,read_organizations,firefly_api,ff_apis
ADOBE_IMS_ORG_ID=your_org_id@AdobeOrg
// src/adobe/auth.ts
import 'dotenv/config';
interface AdobeTokenResponse {
access_token: string;
token_type: string;
expires_in: number; // seconds, typically 86400 (24h)
}
let cachedToken: { token: string; expiresAt: number } | null = null;
export async function getAdobeAccessToken(): Promise<string> {
// Return cached token if still valid (with 5min buffer)
if (cachedToken && cachedToken.expiresAt > Date.now() + 300_000) {
return cachedToken.token;
}
const response = await fetch('https://ims-na1.adobelogin.com/ims/token/v3', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
client_id: process.env.ADOBE_CLIENT_ID!,
client_secret: process.env.ADOBE_CLIENT_SECRET!,
grant_type: 'client_credentials',
scope: process.env.ADOBE_SCOPES!,
}),
});
if (!response.ok) {
const error = await response.text();
throw new Error(`Adobe auth failed (${response.status}): ${error}`);
}
const data: AdobeTokenResponse = await response.json();
cachedToken = {
token: data.access_token,
expiresAt: Date.now() + data.expires_in * 1000,
};
return cachedToken.token;
}
# Quick verification with curl
curl -X POST 'https://ims-na1.adobelogin.com/ims/token/v3' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d "client_id=${ADOBE_CLIENT_ID}&client_secret=${ADOBE_CLIENT_SECRET}&grant_type=client_credentials&scope=${ADOBE_SCOPES}"
node_modules or Python site-packages.env file with credentials (git-ignored)getAdobeAccessToken() function with token caching| Error | Cause | Solution |
|---|---|---|
invalid_client | Wrong client_id or client_secret | Verify credentials in Developer Console |
invalid_scope | Scopes not entitled to your org | Check product profile assignments in Admin Console |
401 Unauthorized | Expired or revoked credentials | Regenerate client_secret in Developer Console |
ENOTFOUND ims-na1.adobelogin.com | Network/DNS issue | Check firewall allows outbound HTTPS to *.adobelogin.com |
JWT credentials deprecated | Using old Service Account (JWT) | Migrate to OAuth Server-to-Server (JWT EOL was June 2025) |
import { ServicePrincipalCredentials, PDFServices } from '@adobe/pdfservices-node-sdk';
const credentials = new ServicePrincipalCredentials({
clientId: process.env.ADOBE_CLIENT_ID!,
clientSecret: process.env.ADOBE_CLIENT_SECRET!,
});
const pdfServices = new PDFServices({ credentials });
import { FireflyClient } from '@adobe/firefly-apis';
const firefly = new FireflyClient({
clientId: process.env.ADOBE_CLIENT_ID!,
accessToken: await getAdobeAccessToken(),
});
from adobe.pdfservices.operation.auth.service_principal_credentials import ServicePrincipalCredentials
from adobe.pdfservices.operation.pdf_services import PDFServices
credentials = ServicePrincipalCredentials(
client_id=os.environ["ADOBE_CLIENT_ID"],
client_secret=os.environ["ADOBE_CLIENT_SECRET"]
)
pdf_services = PDFServices(credentials=credentials)
After successful auth, proceed to adobe-hello-world for your first API call.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin adobe-packSets up local dev loop for Adobe APIs (Firefly/PDF/Photoshop) with App Builder CLI, Node.js SDKs, hot reload, and Vitest mocks.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.