Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Configure Grammarly across multiple environments. Use when setting up dev/staging/prod environments with Grammarly API. Trigger with phrases like "grammarly multi-env", "grammarly environments", "grammarly staging", "grammarly dev prod setup".
.claude/skills/jeremylongshore-grammarly-multi-env-setup/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 8% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -24% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 3% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 9% | 0% |
| case-10 | ✗→✓ | ▲ Improved | -43% | 0% |
Grammarly integration requires environment separation to isolate API credentials, enforce team-scoped style guides, and manage rate limits per tier. Development uses mock API responses for fast iteration without consuming quota, staging connects to the Grammarly sandbox for real grammar checks with test content, and production runs against the live API with full team configurations. Each environment has its own client credentials and style guide settings to prevent dev experiments from affecting production writing standards.
typescriptconst grammarlyConfig = (env: string) => ({ development: { clientId: process.env.GRAMMARLY_DEV_CLIENT_ID!, clientSecret: process.env.GRAMMARLY_DEV_CLIENT_SECRET!, baseUrl: "http://localhost:3100/mock-grammarly", useMockApi: true, concurrency: 1, intervalCap: 2, }, staging: { clientId: process.env.GRAMMARLY_STG_CLIENT_ID!, clientSecret: process.env.GRAMMARLY_STG_CLIENT_SECRET!, baseUrl: "https://api.grammarly.com/sandbox", useMockApi: false, concurrency: 2, intervalCap: 5, }, production: { clientId: process.env.GRAMMARLY_PROD_CLIENT_ID!, clientSecret: process.env.GRAMMARLY_PROD_CLIENT_SECRET!, baseUrl: "https://api.grammarly.com", teamId: process.env.GRAMMARLY_TEAM_ID!, concurrency: 5, intervalCap: 10, }, }[env]);
text# Per-env files: .env.development, .env.staging, .env.production GRAMMARLY_{DEV|STG|PROD}_CLIENT_ID=<client-id> GRAMMARLY_{DEV|STG|PROD}_CLIENT_SECRET=<secret> GRAMMARLY_BASE_URL={http://localhost:3100/mock|https://api.grammarly.com/sandbox|https://api.grammarly.com} GRAMMARLY_TEAM_ID=<team-id> # staging + production only
typescriptfunction validateGrammarlyEnv(env: string): void { const suffix = { development: "_DEV", staging: "_STG", production: "_PROD" }[env]; const required = [`GRAMMARLY${suffix}_CLIENT_ID`, `GRAMMARLY${suffix}_CLIENT_SECRET`]; if (env === "production") required.push("GRAMMARLY_TEAM_ID"); const missing = required.filter((k) => !process.env[k]); if (missing.length) throw new Error(`Missing Grammarly vars for ${env}: ${missing.join(", ")}`); }
bash# 1. Verify mock API coverage in dev npm test -- --grep "grammarly" --env development # 2. Run style guide checks against Grammarly sandbox curl -X POST "https://api.grammarly.com/sandbox/check" \ -H "Authorization: Bearer $GRAMMARLY_STG_TOKEN" -d @test-content.json # 3. Compare suggestion quality between staging and baseline node scripts/grammarly-diff.js --env staging --baseline expected-suggestions.json # 4. Rotate credentials and deploy to production GRAMMARLY_PROD_CLIENT_SECRET=$(vault read -field=secret grammarly/prod) npm run deploy -- --env production
| Setting | Dev | Staging | Prod | |---------|-----|---------|------| | API Endpoint | Mock (localhost) | Grammarly Sandbox | Live API | | Team Style Guide | None | Test guide | Production guide | | Rate Limit | 1 concurrent / 2 per interval | 2 / 5 | 5 / 10 | | Quota Tracking | Disabled | Enabled | Enabled + alerts | | User Scope | Developer only | QA team | All team members |
| Issue | Cause | Fix | |-------|-------|-----| | 401 Unauthorized | Client credentials expired or wrong env | Rotate credentials in Grammarly developer console for target env | | Rate limit 429 | Concurrency exceeds tier plan | Lower intervalCap or upgrade Grammarly plan | | Mock API returns empty | Local mock server not running | Start mock with npm run mock:grammarly before dev tests | | Style guide mismatch | Team ID points to wrong guide | Verify GRAMMARLY_TEAM_ID matches the intended style guide | | Suggestions differ across envs | Sandbox uses older model version | Expected behavior; validate core rules only in staging |
See grammarly-deploy-integration.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 19,448 | 15,183 | -22% | 1 | 1 | 0% | 3,573 | 3,842 | +8% | 0 | 0 | — |
case-02 | fail→fail | 27,511 | 15,655 | -43% | 1 | 1 | 0% | 5,263 | 3,705 | -30% | 0 | 0 | — |
case-03 | fail→pass | 29,321 | 16,294 | -44% | 1 | 1 | 0% | 5,176 | 3,927 | -24% | 0 | 0 | — |
case-04 | pass→pass | 13,383 | 9,126 | -32% | 1 | 1 | 0% | 1,888 | 3,274 | +73% | 0 | 0 | — |
case-05 | pass→pass | 23,037 | 15,333 | -33% | 1 | 1 | 0% | 3,644 | 5,101 | +40% | 0 | 0 | — |
case-06 | pass→pass | 16,176 | 21,615 | +34% | 1 | 1 | 0% | 2,780 | 4,252 | +53% | 0 | 0 | — |
case-07 | fail→pass | 15,717 | 4,120 | -74% | 1 | 1 | 0% | 1,853 | 1,914 | +3% | 0 | 0 | — |
case-08 | fail→fail | 14,462 | 8,620 | -40% | 1 | 1 | 0% | 1,493 | 1,858 | +24% | 0 | 0 | — |
case-09 | fail→pass | 22,160 | 15,218 | -31% | 1 | 1 | 0% | 3,626 | 3,956 | +9% | 0 | 0 | — |
case-10 | fail→pass | 22,014 | 7,664 | -65% | 1 | 1 | 0% | 2,784 | 1,599 | -43% | 0 | 0 | — |
case-11 | fail→pass | 18,813 | 2,523 | -87% | 1 | 1 | 0% | 2,397 | 1,518 | -37% | 0 | 0 | — |
case-12 | fail→pass | 15,464 | 6,915 | -55% | 1 | 1 | 0% | 1,606 | 1,401 | -13% | 0 | 0 | — |
case-13 | fail→pass | 8,122 | 3,742 | -54% | 1 | 1 | 0% | 1,497 | 1,853 | +24% | 0 | 0 | — |
case-14 | fail→pass | 23,098 | 2,290 | -90% | 1 | 1 | 0% | 715 | 1,505 | +110% | 0 | 0 | — |
case-15 | fail→pass | 30,521 | 2,878 | -91% | 1 | 1 | 0% | 1,531 | 1,605 | +5% | 0 | 0 | — |
case-16 | fail→pass | 21,271 | 11,634 | -45% | 1 | 1 | 0% | 2,398 | 2,358 | -2% | 0 | 0 | — |
case-17 | fail→pass | 13,753 | 2,759 | -80% | 1 | 1 | 0% | 1,440 | 1,589 | +10% | 0 | 0 | — |
case-18 | fail→pass | 14,098 | 11,611 | -18% | 1 | 1 | 0% | 2,355 | 2,184 | -7% | 0 | 0 | — |
case-19 | fail→pass | 14,419 | 11,576 | -20% | 1 | 1 | 0% | 2,343 | 2,961 | +26% | 0 | 0 | — |
case-20 | pass→pass | 18,993 | 7,769 | -59% | 1 | 1 | 0% | 2,176 | 2,612 | +20% | 0 | 0 | — |
case-21 | fail→pass | 17,422 | 13,190 | -24% | 1 | 1 | 0% | 2,693 | 2,342 | -13% | 0 | 0 | — |
case-22 | fail→pass | 20,946 | 6,881 | -67% | 1 | 1 | 0% | 2,427 | 1,422 | -41% | 0 | 0 | — |
case-23 | fail→pass | 14,728 | 9,975 | -32% | 1 | 1 | 0% | 1,754 | 1,877 | +7% | 0 | 0 | — |
case-24 | pass→pass | 10,271 | 2,109 | -79% | 1 | 1 | 0% | 1,432 | 1,556 | +9% | 0 | 0 | — |
case-25 | fail→pass | 13,282 | 10,068 | -24% | 1 | 1 | 0% | 2,191 | 2,041 | -7% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 25 cases were attempted, and 23 counted toward the lift figure. The other 2 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +72 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.