BucketName { get; set; }
}
```
**Java:**
```java
package s3site;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.aws.s3.Bucket;
public class Infra {
public static void main(String[] args) {
Pulumi.run(Infra::stack);
}
private static void stack(Context ctx) {
final var myBucket = new Bucket("my-bucket");
ctx.export("bucketName", myBucket.id());
}
}
```
**YAML:**
```yaml
name: my-stack
runtime: yaml
resources:
bucket:
type: aws:s3:Bucket
outputs:
bucketName: ${bucket.id}
```
# Brand MCP server
> A remote Model Context Protocol server that exposes the Pulumi brand guidelines as structured resources, tools, and prompts for AI agents and LLM-powered workflows.
The Pulumi Brand MCP Server is a remote [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the Pulumi brand guidelines as structured resources, tools, and prompts. It's designed to be consumed by AI agents and LLM-powered workflows that create, review, or audit brand content, and it's deployed at `brand.pulumi.com` and compatible with any MCP client that supports streamable HTTP.
**Notice:**
Please review the [Generative AI Guidelines](/guidelines/generative-ai/) before using the Brand MCP Server.
## Configuration
Point any MCP-compatible client at the public URL:
```
https://brand.pulumi.com/mcp
```
In the snippets below, we've named the connection `pulumi-brand`, but you can change that if you like.
### Claude
You can use the MCP server with Claude Code, Claude Desktop, and in the browser at Claude.ai.
#### Claude Code
Add the MCP server with the CLI:
```bash
claude mcp add --transport http pulumi-brand https://brand.pulumi.com/mcp
```
By default, the server is scoped to the current project. Add `--scope user` to make it available across all of your projects:
```bash
claude mcp add --transport http --scope user pulumi-brand https://brand.pulumi.com/mcp
```
To confirm the connection succeeded, run `claude mcp list`. To inspect the server's tools, run `/mcp` in an active Claude Code session.
#### Claude Desktop
You can configure Claude Desktop with the MCP server in one of two ways.
##### With a custom connector
1. In Claude Desktop, open **Customize → Connectors**.
1. Click **Add → Add custom connector**.
1. Enter a name (e.g., "Pulumi Brand") and paste the URL: `https://brand.pulumi.com/mcp`.
1. Save the connector and begin using the MCP server.
##### With a local MCP server
This approach uses the [`mcp-remote`](https://github.com/geelen/mcp-remote) connector.
1. In Claude Desktop, open **Developer → Local MCP servers**.
1. Click **Edit config** and open the file in your text editor of choice.
1. Add a `pulumi-brand` block to the `mcpServers` list (add that list if it doesn't exist):
```json
{
"mcpServers": {
"pulumi-brand": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://brand.pulumi.com/mcp"]
}
}
}
```
1. Save the file and begin using the MCP server.
#### Claude.ai
1. Visit https://claude.ai, sign in, and navigate to **Customize → Connectors**.
1. Click **Add → Add custom connector**.
1. Enter a name (e.g., "Pulumi Brand") and paste the URL: `https://brand.pulumi.com/mcp`.
1. Save the connector and begin using the MCP server.
### Codex
1. Add the following block to `~/.codex/config.toml` for all projects, or to `./.codex/config.toml` for the current one:
```toml
[mcp_servers.pulumi-brand]
url = "https://brand.pulumi.com/mcp"
```
1. Save the file, restart Codex, and begin using the MCP server.
### Cursor
You can use the MCP server with Cursor in several ways.
#### Cursor Desktop
1. Open **Settings → Cursor Settings → Tools & MCPs**.
1. Under Installed MCP Servers, click **Add Custom MCP**.
1. Add the following block to `~/.cursor/mcp.json` for all projects, or to `./.cursor/mcp.json` for the current one:
```json
{
"mcpServers": {
"pulumi-brand": {
"transport": "http",
"url": "https://brand.pulumi.com/mcp"
}
}
}
```
1. Save the file and begin using the MCP server.
#### Cursor CLI
1. Add the following block to `~/.cursor/mcp.json` for all projects, or to `./.cursor/mcp.json` for the current one:
```json
{
"mcpServers": {
"pulumi-brand": {
"transport": "http",
"url": "https://brand.pulumi.com/mcp"
}
}
}
```
1. Save the file, restart Cursor, and begin using the MCP server.
### OpenCode
1. Add the following block to `~/.config/opencode/opencode.json` for all projects, or to `./opencode.json` for the current one:
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"pulumi-brand": {
"type": "remote",
"url": "https://brand.pulumi.com/mcp",
"enabled": true
}
}
}
```
1. Save the file, restart OpenCode, and begin using the MCP server.
### Other clients
Any MCP client that supports a remote Streamable HTTP server works. Give it the URL `https://brand.pulumi.com/mcp` directly if it accepts one, or bridge through stdio with `npx -y mcp-remote https://brand.pulumi.com/mcp` (the same pattern as the Claude Desktop config-file option above).
## Resources
Static brand content served via `resources/read`. Each resource uses a `brand://` URI scheme.
| URI | Name | Content |
| --- | ---- | ------- |
| `brand://colors` | Brand Colors | Full color system — 8 palettes × 11 steps, semantic roles, utility colors, accessibility notes |
| `brand://colors/{palette}` | Brand Color Palette | A single palette (e.g., `brand://colors/violet`) |
| `brand://tokens` | Brand Design Tokens | Pulumi Design System core tokens ([pulumi/pulumi-design-system](https://github.com/pulumi/pulumi-design-system), the source of truth) — primitive color palettes (light + dark), shared color semantics, per-palette roles, typography, spacing |
| `brand://design-tokens` | Brand Design Tokens Guide | The design-token reference — per-palette roles, shared color semantics (brand, status, text), typography, spacing, and light/dark resolution |
| `brand://typography` | Brand Typography | Inter + Monaspace Neon typefaces, font stacks, usage rules, typographic scale |
| `brand://voice` | Brand Voice & Tone | Voice principles, tone-by-context matrix, preferred/avoided words, inclusive language |
| `brand://writing-style` | Writing Style | Grammar, punctuation, style rules (Chicago Manual of Style) |
| `brand://terminology` | Names & Terminology | Canonical product, feature, and category names; retired and disallowed names with replacements |
| `brand://logo` | Logo Guidelines | Lockups, sizing, approved backgrounds, clear space, dos/don'ts |
| `brand://identity` | Brand Identity | Brand attributes, purpose, values, Phosphor iconography guidelines |
| `brand://visuals` | Visual Guidelines | Illustration style, accent lines, photography, mascot (Pulumipus) |
| `brand://guidelines` | Usage Guidelines | Generative AI usage rules, when to bend brand rules |
| `brand://templates` | Templates | On-brand starting points: Slidev theme, Google Docs/Slides, Figma, Claude Design |
| `brand://assets` | Brand Assets | Hosted static asset files (Neo icons, fonts, color CSS, accent lines, raw logos) with naming conventions and a complete URL index |
## Tools
The tools fall into two groups: **brand lookup** (colors, typography, search) and **asset access** (logo generation and hosted asset URLs).
### `get_brand_overview`
Return the brand orientation — how to use this server and which `get_guidelines` section to pull for the task at hand. The same text MCP clients receive as server `instructions` at session start; call this when your client doesn't surface those, or to re-orient mid-task. It routes you to the rules rather than restating them — use `get_guidelines` for the full guidance on a topic.
Takes no arguments.
### `get_guidelines`
Return the complete text of a brand guideline section — the full guidance, not a summary. Call it before producing or reviewing the matching kind of artifact (for example, `voice`, `writing-style`, and `terminology` before writing copy). For color, use the color tools below; to search across sections, use `search_guidelines`.
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `section` | string | Yes | One of: `voice`, `writing-style`, `terminology`, `typography`, `design-tokens`, `logo`, `identity`, `visuals`, `guidelines`, `templates`, `assets` |
### `get_color_palette`
Get a specific brand color palette with all 11 steps (50–950) and semantic roles.
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `palette` | string | Yes | One of: `violet`, `gray`, `green`, `aqua`, `blue`, `red`, `orange`, `yellow`, or `utility` (black, white, Service Black) |
| `format` | string | No | Color format hint: `hex`, `hsl`, `rgb`, `oklch`. Stored values are hex; other formats available via `brand://colors`. |
| `response_format` | string | No | `json` (default) for structured data or `markdown` for a human-readable table |
### `find_nearest_brand_color`
Find the perceptually closest brand color to any CSS color value using OKLab Euclidean color difference.
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `color` | string | Yes | Any CSS color: `#6366f1`, `rgb(99,102,241)`, `hsl(239,84%,67%)`, `oklch(...)`, or a named color |
| `mode` | string | No | `light`, `dark`, or `both` (default). Which mode's palette to match against. |
Returns the matched token name, palette, step, mode, and hex value with a replacement recommendation.
### `get_color_tokens`
Get semantic color tokens (primary, accent, muted, background) for one or all palettes.
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `palette` | string | No | A specific palette name. Omit to get tokens for all 8 palettes. |
### `check_color_accessibility`
Check contrast between two colors using **WCAG 3 APCA** (Accessible Perceptual Contrast Algorithm). Returns the Lc value, polarity, pass/fail thresholds, and a font-size lookup per weight.
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `foreground` | string | Yes | Hex value or brand token name (e.g., `violet-700-light`) |
| `background` | string | Yes | Hex value or brand token name |
**APCA thresholds:**
| Lc (absolute) | Use case |
| ------------- | -------- |
| ≥ 90 | Preferred body text |
| ≥ 75 | Body text minimum |
| ≥ 60 | Large / heading text |
| ≥ 45 | Large non-text elements |
| ≥ 30 | Non-text / spot elements |
| < 30 | Insufficient — do not use |
### `get_design_tokens`
Return the Pulumi Design System core tokens — the canonical source of truth from [pulumi/pulumi-design-system](https://github.com/pulumi/pulumi-design-system) (`@pulumi/design-tokens`): primitive color palettes (50–950, light + dark), shared color semantics (brand colors, status, text roles), per-palette roles (primary/accent/muted/background), typography, and spacing. The tool route to the `brand://tokens` resource. References resolve against the light palettes; use the `primitivesDark` group for dark-mode values. The typography tokens beyond the root typefaces (Inter and Monaspace Neon) and all spacing tokens are Pulumi Cloud-specific today; values for marketing and docs are coming soon. For the human-readable reference with resolved light/dark values, use `get_guidelines` with the `design-tokens` section (the [Design tokens](/foundations/design-tokens/) page).
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `group` | string | No | Scope to one top-level group: `primitives`, `primitivesDark`, `semantic`, `paletteSemantics`, `typography`, `spacing`. Omit for the whole document. |
| `resolve` | boolean | No | Resolve token references (e.g., `{green.800}`) to concrete light-mode values (e.g., `#165a31`). Default `false`. |
### `get_font_stack`
Get the correct brand font stack and usage rules for a given typographic context.
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `context` | string | Yes | `heading` (Inter Semibold), `body` (Inter Regular), or `mono` (Monaspace Neon) |
### `search_guidelines`
Full-text search across all brand guideline content. Returns excerpts with surrounding context.
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `query` | string | Yes | Search terms or natural language question about the brand |
### `get_logo`
Return a URL for a Pulumi logo in any approved variant, format, background, and size. The URL is served by the brand site's logo endpoint at [`brand.pulumi.com/api/logo`](/api) (CDN-cached) — surface it directly to the user. Pass `inline: true` to embed the bytes (SVG markup or a base64 data URI) in the tool response instead, for runtimes that can't fetch a URL at render time.
Serves the **Pulumi** logo system only — Neo icons and other static assets come from `list_brand_assets`.
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `usage` | string | No | Preset that sets sensible defaults: `web`, `print`, `slide-deck`, `email-signature`, `favicon`, `social-avatar`, `custom`. Explicit params override. |
| `lockup` | string | No | `auto` (default), `mark`, `horizontal`, `stacked`, or `icon-circle` / `icon-rounded` / `icon-square` |
| `treatment` | string | No | `color` (default) or `monotone`. Icons are always color. |
| `theme` | string | No | `light` or `dark`. Auto-derived from the background when omitted. |
| `format` | string | No | `svg` (default), `png`, `jpg`, `pdf`, or `eps` |
| `background` | string | No | `transparent` (default), `white`, `black`, `service-black`, `violet-50`, `violet-950` |
| `width` / `height` | number | No | Size in `units`. One alone → logo-only; both → centered on a padded canvas. |
| `units` | string | No | `px` (default), `cm`, or `in` (with `dpi`, default 300) |
| `inline` | boolean | No | `true` to embed the asset bytes in the response instead of returning a URL. Default `false`. |
### `list_brand_assets`
List the permanent, CDN-served URLs for the static brand asset files hosted under [`brand.pulumi.com/brand-assets/`](/brand-assets/README.md) — Neo (AI agent) icons, font files (Inter, Monaspace Neon), color CSS custom-property files, accent-line SVGs, raw logo source files, and the downloadable [asset zip](/pulumi-brand-assets.zip). The listing is generated from the hosted directory at build time, so it always reflects what's actually published.
For Pulumi logos, `get_logo` remains the front door — it validates variants and supports themes, backgrounds, resizing, and format conversion. The `logos` category here exposes the raw static source files only.
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `category` | string | No | One of: `logos`, `neo`, `color`, `fonts`, `example-lines`. Returns that category's complete file list with URLs. Omit for an overview of all categories with counts and naming conventions. |
## Prompts
Pre-built prompt templates that inject brand context for LLM-powered workflows.
Prompts are **user-invoked** — the agent doesn't call them automatically. You trigger one, fill in its arguments, and it expands into a ready-made message (pre-loaded with the relevant brand guidelines) that's sent to the model. How you invoke them depends on your client:
- **Claude Code** — they appear as slash commands. Type `/` and look for the `pulumi-brand` entries (e.g., `/mcp__pulumi-brand__review_copy`).
- **Claude Desktop / Claude.ai** — open the `+` (connectors) menu in the composer, pick the **pulumi-brand** server, choose the prompt, and fill in the fields.
- **Other clients** — wherever the client surfaces MCP prompts (a command palette or MCP panel). Under the hood it's the standard `prompts/list` → `prompts/get` flow.
Note that `review_image` takes no arguments — attach the image to your message first, then invoke it.
### `review_copy`
Review text content first from your target reader's point of view, then for compliance with brand voice, tone, writing style, and naming (including a check of every product and feature name against the retired-names list). Returns a reader's-eye read (does the main point land, what's left unanswered, where it's too long or vague), an overall assessment, a list of specific issues with quotes and suggested rewrites, and a clean rewritten version if issues were found.
| Argument | Required | Description |
| -------- | -------- | ----------- |
| `copy` | Yes | The text content to review |
| `context` | No | `product`, `marketing` (default), `community`, or `enterprise` |
### `review_image`
Evaluate an image against brand visual guidelines — color, typography, iconography, illustration, and photography. Attach the image to your message, then invoke the prompt.
Takes no arguments — the prompt reads the attached image directly.
### `review_design`
Review a design in Figma for brand adherence — covers colors, typography, logo usage, spacing, and overall alignment. Works in combination with the Figma MCP, which retrieves the design from the URL.
| Argument | Required | Description |
| -------- | -------- | ----------- |
| `figma_url` | Yes | Figma file or node URL (`figma.com/design/…`) to review |
# Templates
> On-brand starting points for slide decks, documents, and design files.
Use the templates below to create on-brand starting points for your slide decks, docs, and design efforts.
## Slide decks
### Slidev
[Slidev](https://sli.dev/) lets you build rich, interactive slide decks with Markdown and Node.js. Use the [`@pulumi/slidev-theme`](https://www.npmjs.com/package/@pulumi/slidev-theme) package to bootstrap a new project quickly:
**pnpm:**
```bash
pnpm init
pnpm add -D @slidev/cli @pulumi/slidev-theme
cp node_modules/@pulumi/slidev-theme/starter.md slides.md
pnpm exec slidev slides.md --open
```
**npm:**
```bash
npm init -y
npm install -D @slidev/cli @pulumi/slidev-theme
cp node_modules/@pulumi/slidev-theme/starter.md slides.md
npx slidev slides.md --open
```
**bun:**
```bash
bun init -y
bun add -d @slidev/cli @pulumi/slidev-theme
cp node_modules/@pulumi/slidev-theme/starter.md slides.md
bunx slidev slides.md --open
```
Alternatively, you can use your agent of choice by [connecting the brand MCP server](/mcp-server/#configuration), then asking the agent to create a new deck for you:
```text
Make me a slide deck called "Why Pulumi is awesome".
```
When you're finished, consult the Slidev docs for help [building your deck](https://sli.dev/guide/hosting) or [exporting](https://sli.dev/guide/exporting) to other formats. Be sure to check out Slidev's [authoring](https://sli.dev/guide/syntax) and [agent](https://sli.dev/guide/work-with-ai) guides as well.
For bugs or new feature requests, [file an issue](https://github.com/pulumi/marketing-web/issues).
### Google Slides
We also have a Google Slides template with light and dark slides, a color theme, and typography.
To use it:
- [Open the slide-deck template](https://docs.google.com/presentation/d/1pftemnNstfdIljqHj6Oe2BaJYkppiUCsevugcuI8-UI/edit?usp=sharing) in Google Drive, then choose **File → Make a copy**.
- Alternatively, choose a different template from the [template gallery](https://docs.google.com/presentation/u/0/?tgif=d&ftv=1). Be sure to choose a template that uses our current branding and not an outdated one.
## Docs
### Google Docs
We have a basic Google Docs template as well that includes text styles and a cover page.
To use it:
- [Open the doc template](https://docs.google.com/document/d/1tO0DBkdE-BPAfY3HSnhHFod0Sy2hkWI7Wh0-ANVZxJg/edit?usp=sharing) in Google Drive, then choose **File → Make a copy**.
- Alternatively, choose a different template from the [template gallery](https://docs.google.com/document/u/0/?tgif=d&ftv=1). Be sure to choose a template that uses our current branding and not an outdated one.
## Diagrams and charts
### Mermaid
[Mermaid](https://mermaid.js.org/) renders diagrams and charts from plain text: flowcharts, sequence diagrams, git graphs, pie charts, and more. Our portable `pulumi-mermaid-theme.js` styles all of them for both light and dark mode.
Decks built with the [`@pulumi/slidev-theme`](#slidev) package get this styling automatically, with nothing to install.
For any other Mermaid v11 setup, pass one of the theme's exports — `pulumiMermaidLight` or `pulumiMermaidDark` — to `mermaid.initialize()`. Follow the steps below for a working example.
1. [Download the theme file](/brand-assets/mermaid/pulumi-mermaid-theme.js) and save it as `pulumi-mermaid-theme.js`.
1. Save the following file as `index.html` in the same folder:
```html
Pulumi Mermaid example
flowchart LR
Code[Write code] --> Preview{pulumi preview}
Preview -->|Looks good| Up[pulumi up]
Preview -->|Needs work| Code
Up --> Cloud[(Pulumi Cloud)]
```
1. Start a local web server to view the rendered SVG in a browser:
```bash
npx serve
```
## Design
### Figma
We also have many design templates [available in Figma](https://www.figma.com/files/team/675050069160030672/project/575443132). Ask in the [#marketing](https://pulumi.slack.com/archives/C7XHM1GNT) channel if you need access to Figma or if you need any help finding what you're looking for.
When working in Figma, be sure to reference the [Global Design Primitives](https://www.figma.com/design/I4WYbethjl5yBxhysRPXPb/Global-Design-Primitives?node-id=1-70&p=f&t=86eHLphYN38cDVaK-0) file for color values, tokens, and design assets. You should use this library across all of your Figma design files.
### Claude Design
We're currently exploring how to integrate Claude Design into asset-creation workflows. For now, please avoid using it. Even with brand context, it can produce unpredictable, off-brand output.
**Need help?**
Ask anytime in the [#marketing](https://pulumi.slack.com/archives/C7XHM1GNT) channel.
# Accent lines
> How to use Pulumi's curved accent lines in compositions.
Pulumi Accent Lines
A collection of curved accent lines can be combined and either used on their own or integrated into larger compositions.
- ✓ Always terminate lines off canvas or fade them into the background.
- ✓ Space multiple lines evenly and arrange them in a balanced, intentional way.
- ✓ Keep all lines the same weight.
- ✓ Lines can be used to indicate connection between elements.
- ✗ Don't end lines abruptly or crop them in a way that creates a hard edge.
- ✗ Don't let lines bisect or overlap each other in a way that creates visual clutter.
- ✗ Don't use lines in complex flow diagrams to indicate directionality — use simpler connectors instead. (See [Illustration](/visuals/illustration/).)
# Illustration
> Pulumi's illustration style — line art, isometric shapes, and the distinction between illustrations and diagrams.
## Illustration style
Pulumi Illustration
The illustration style for the Pulumi brand is a simple line art style featuring the brand violet as the primary color, with supporting colors used as needed.
- Isometric shapes can be included, but should avoid making important text illegible.
- All stroke weights should match within a composition. This is typically 1px for digital use, but can be adjusted as needed for larger format designs.
- Use Phosphor [icons](/identity/iconography/) where icons are needed within illustrations.
## Illustrations vs. diagrams
Pulumi Illustration vs Diagrams
**Illustrations** are used to communicate high-level concepts, add visual interest, and for empty states. These can be more abstract and decorative, and can include more complex compositions with isometric shapes and accent lines.
**Diagrams** are used to communicate more detailed concepts or flows and should be created in a simple style that prioritizes clarity and ease of understanding. Avoid isometric views here and use simple connector lines to clearly show flows and relationships.
# Photography
> Guidelines for using photography in Pulumi brand materials.
Photography should be used sparingly — primarily in blog posts, event content, community content, and company culture materials.
- ✓ Feature real people and aim for an authentic, candid feel rather than overly staged or posed compositions.
- ✗ Don't use stock photography or AI-generated photographic images.
# Names & terminology
> The canonical reference for Pulumi product, feature, and category names, including the names we've retired.
This is the canonical reference for Pulumi product names, features, and categories, as well as the names we no longer use. It's here to help us keep our naming (and the automated processes around it) consistent.
* **Some replacements can't be automated.** "Pulumi Service" resolves to a different product in different sentences — Pulumi Cloud most often, but Pulumi ESC or Pulumi Deployments where the sentence is about secrets or remote execution. Replacements like these may need a human to specify the right one.
* **Historical usage is fine.** Prose that intentionally describes past behavior — "before v3.0 this was called X" — is acceptable, and dated blog posts should remain as they are.
For voice, tone, and word choice, see [voice and tone](/voice/voice-and-tone/) and [writing style](/voice/writing-style/).
## Product names
Always capitalize product names exactly as they are here.
| Name | Notes |
| --- | --- |
| **Pulumi IaC** | The practice of IaC is _infrastructure as code_, lowercase. |
| **Pulumi Cloud** | The commercial cloud product. Its web frontend is the _Pulumi Cloud console_ or the _Pulumi console_, with _console_ in lowercase, since it isn't a proper noun. Never _Pulumi UI_. |
| **Pulumi ESC** | Expands to _Environments, Secrets, and Configuration_. |
| **Pulumi Neo** | Our infrastructure agent. _Neo_ is also acceptable. |
| **Pulumi Deployments** | _Deployments_ is also acceptable. |
| **Pulumi Discovery** | Peer of Pulumi Policies under [Discovery & governance](#discovery--governance). |
| **Pulumi Policies** | A singular proper noun, like _United States_: "Pulumi Policies enforces compliance", never "enforce" in this context. |
| **Pulumi IDP** | The concept of an IDP is _internal developer platform_, lowercase. |
| **Pulumi CLI** | In prose, _the Pulumi CLI_. |
| **Pulumi SDK** | In prose, _the Pulumi SDK_. |
| **Pulumi Kubernetes Operator** | In prose, _the Pulumi Kubernetes Operator_. May be abbreviated as _PKO_ after an initial on-page mention. |
Expand product names on first mention ("Pulumi ESC"), then use just the product name ("ESC") afterward. Similarly, for non-Pulumi acronyms, spell out the acronym on first use, then use the abbreviation (e.g., "Virtual Private Cloud (VPC)", then just "VPC"). Widely known acronyms (API, HTTP, REST) don't need explanation.
## Features and capabilities
Two rules decide the casing of every name on this page:
- Features and capabilities are always lowercase: _drift detection and remediation_, _review stacks_, _scheduled deployments_, _secrets rotation_. Exceptions, if any, are rare, and noted below.
- Where a proper noun is followed by a common noun describing what it is, capitalize only the proper part: the _Pulumi Cloud console_, the _Resources view_, a _Discovery scan_.
Pulumi has no title-case convention: [headings are sentence case](/voice/writing-style/#headings-and-titles), and names keep their own casing wherever they appear.
### Pulumi IaC
- **Automation API**: A feature, but capitalized to distinguish it from the generic concept of automation. In prose, _the Automation API_.
- **Pulumi package**: A component or provider shipped with a plugin and consumable in any Pulumi language. A _native language package_ is the single-language counterpart.
- **Pulumi Cloud provider**: The provider for managing Pulumi Cloud resources. The registry package is still published as `pulumiservice`, so it's referenced in code as such.
### Pulumi Deployments
- **Drift detection**: _Drift remediation_ is the action it enables, and is also lowercase.
- **Review stacks**: Ephemeral stacks created for pull requests.
- **Click-to-deploy**: The one-click deployment flow for templates and examples.
- **Time-to-live stacks**: Stacks that are destroyed automatically. May be abbreviated as _TTL stacks_ after an initial on-page mention.
- **Scheduled deployments**, **deployment triggers**, **webhooks**, and **Pulumi-managed** and **customer-managed runners** are all lowercase.
### Pulumi ESC
- **Environments**: Always lowercase (_create an environment_, _ESC environments_, _duplicating environments_, and so on).
- **Login providers**: The identity providers an environment authenticates against.
- **Dynamic credentials**, **dynamic secrets**, **rotated secrets** and **secrets rotation**, **composable environments**, **revisions**, and **tags** are all lowercase.
### Discovery & governance
- **Discovery & governance** is a category label that covers two products, Discovery and Policies. When used alone, Discovery is a product name, unless it's being used to describe the concept of discovering. So it's _Discovery scans your cloud accounts_, and _when the discovery is complete_. _Governance_, as a concept, is always lowercase.
Discovery's features are all lowercase as well: _resource search_, _unified resources_, _data export_, _discovered stacks_, and _visual import_. A scan is a _scan_ or a _Discovery scan_, the inventory is _the resource graph_ or _the Discovery inventory_, and what it surfaces are _discovered resources_ or _unmanaged resources_.
- **Policies** have _policy packs_, _policy groups_, and _policy findings_. Compliance frameworks (CIS, NIST, PCI DSS) and enforcement modes (_preventative_ and _audit_) are all lowercase.
### Pulumi Neo
- **Neo tasks** and **Neo automations**: The units of work that Neo performs.
- **Neo tokens**: The units of Neo usage.
- **Neo code reviews**, **MCP integrations**, and **scheduled tasks** are all lowercase.
### Pulumi IDP
- **Product features** like _services_, _private registry_, _private components_, _organization templates_, _Terraform modules_, _no-code stacks_, the _new-project wizard_, and _the Backstage plugin_ are lowercase.
- **Concepts** like _golden paths_ are also lowercase.
### Pulumi Cloud
- **Pulumi Cloud console**: The web frontend for Pulumi Cloud. _Pulumi console_ is also acceptable. The _Dashboard_, as a named view in the console, is capitalized.
- **Approvals**: The deployment-approval feature, lowercase.
- **Version control accounts**: Lowercase and written in full. _Version control integrations_ refers to the feature. _VCS accounts_ and _VCS integrations_ are also acceptable.
- **Context API**: A feature, but capitalized to distinguish it from the generic concept of context.
- **Pulumi Credits**: Capitalized to distinguish it from the concept of a credit (the opposite of a debit). _Workflow minutes_ and _Neo tokens_, however, are lowercase.
- **Features within the console**, like _custom roles_, _teams_, _audit logs_, and _access tokens_ (including their types: _organization_, _team_, _machine_, and _personal_) are lowercase. Their named pages, views, and sections, however — the _Dashboard_, _Stacks_, _Environments_, _Resources_, _Deployments_ — are capitalized.
## Retired and disallowed names
The following names are no longer used. Notes may be added to historical content (e.g., blogs) to clarify their updated names so as not to confuse readers.
| Don't use | Use instead | Notes |
| --- | --- | --- |
| Insights, Pulumi Insights, Insights Discovery, Account Discovery, IAS | Discovery | |
| Insights & Governance, Insights and Policy, Insights 2.0, Discovery & Governance, Discovery and governance | Discovery & governance | A category label, not a product name, so lowercase, and with ampersand. |
| CrossGuard, Pulumi CrossGuard, Policy as Code (as a product name), Insights Policy | Pulumi Policies | _Policy as code_ in reference to the practice. |
| Policy Violations (as the console page name) | policy findings | Lowercase _policy violations_ is fine in prose for what a policy check surfaces. |
| Insights account | cloud account | Avoid just "account", as it collides with version control accounts. |
| Insights scan | scan, Discovery scan | |
| the Insights supergraph | the resource graph, the Discovery inventory | |
| Insights resources | discovered resources, unmanaged resources | |
| Pulumi Service | Pulumi Cloud | |
| Pulumi Service provider (PSP) | Pulumi Cloud provider | The package id remains `pulumiservice`. |
| Pulumi Console, Pulumi Cloud Console, Pulumi UI | Pulumi console, Pulumi Cloud console | Lowercase _console_. |
| Copilot, Pulumi Copilot | Pulumi Neo | |
| public beta | public preview | Use this for anything pre-GA. |
| cross-language package | Pulumi package | |
| single-language package, language-native package | native language package | Not _language-native_ package. |
| runtime code | function serialization | _Runtime_ has too many unrelated live meanings to swap on sight. |
| self-managed backend | DIY backend | This is different from _self-hosted_ (i.e., customer-managed, on-prem) deployments of Pulumi Cloud. |
## General terminology rules
- Don't overcapitalize. Only [proper nouns](https://en.wikipedia.org/wiki/Proper_noun) should be capitalized — not concepts (even Pulumi-specific ones). So for example, it's _stack_, not _Stack_; _environment_, not _Environment_; _token_, not _Token_; and _infrastructure as code_, not _Infrastructure as Code_.
- The phrase _infrastructure as code_ is usable as both a noun and an adjective. The noun form ("infrastructure as code is the practice of...") should never be hyphenated. The adjectival form ("Pulumi is an infrastructure-as-code tool") _may_ be hyphenated, but typically doesn't need to be. If the sentence is clear and unambiguous without the hyphens, omit them.
- It's _open source_ when used as a noun ("we love open source"), but _open-source_ when used as an adjective ("Pulumi is an open-source platform"). It's _set up_ as a verb but _setup_ as a noun; _log in_ as a verb but _login_ as a noun; and _command line_ as a noun but _command-line_ as an adjective.
- _Cloud_ and _internet_ are both lowercase, and _data center_ is two words. _Frontend_ and _backend_ are both one word.
- Match each project's own casing for names like Kubernetes, GitHub, and npm. When a lowercase name like npm would land at the start of a sentence, reword so it doesn't.
## See also
- [Writing style](/voice/writing-style/) — grammar, punctuation, and the mechanics of how we write.
- [Words and phrases](/voice/voice-and-tone/#words-and-phrases) — which words to prefer and avoid for voice and tone.
# Voice & tone
> Pulumi's voice principles, tone by context, and word choices.
Everything we put out into the world — every blog post, doc, page, guide, deck, and social-media post — is an expression of the Pulumi brand. The content we create doesn't exist separately from the brand; it _is_ the brand, and one of the main ways our users connect with us.
## Voice
Our voice — the language we use and how we use it — should be as authentic and consistent as possible across all of our communications, from blogs and demos to case studies and whitepapers. How we communicate is an expression of who we are, so we do our best to adhere to certain key principles.
* **Practitioner-first**. Most of our content is written for users of technical products like ours, so we write like engineers in conversation with engineers, with the words and language our audience uses, without dumbing things down or dressing things up.
* **Direct and confident**. Technical people appreciate clarity, so we say what we mean, and we're tactfully and respectfully open about our opinions when we have them. When we're talking about Pulumi, we're clear about what our products actually do and don't do.
* **Concrete over abstract**. Wherever possible, we show, don't tell, with examples and concrete numbers where it helps. "A P99 performance improvement of 93%" is better than "significantly faster", and "supports AWS and Azure" is better than "supports most major cloud providers". Ambiguity leads to confusion.
* **Honest and respectful**. We openly acknowledge real-world tradeoffs and alternatives because that's what our audience needs and appreciates. "Already happy with Pulumi open source? Many teams are — and we love that." That's true, so we say it. We never trash competitor brands or products, and when Pulumi isn't the right fit, we say that too, because doing so builds trust, and trust is what it's all about.
* **Warm, but not cute**. We're genuinely approachable and conversational, so our prose should reflect that ("it just works", "Pulumi takes care of the rest"), but we don't force humor or cleverness. We keep it light, but always professional.
Everywhere we communicate, we should sound like ourselves: human, kind, warm, approachable, empathetic, opinionated but balanced, and honest. Authenticity and trust, above all, are the goal.
### Your own voice
Our collective voice is important, but when your name's on a piece, like a blog or a conference talk, we want _your_ voice and personality to come through as well. The purpose of this guide is to help us keep our communications consistent, not to flatten us all into a uniform blob. When in doubt, just write like the human you are. See [Drafting, revision, and review](/voice/writing-style/#drafting-revision-and-review) for help.
## Who we write for
We write for our fellow humans. While the web may be trafficked increasingly by bots, our words are ultimately meant for people. As we write, we're aware there's a person on the other end of the line, and we craft our words accordingly, even if what we're writing is intended to connect with that person by way of a bot.
## Tone by context
While our voice should be consistent, the tone we use may shift depending on audience and context.
* **In product and technical content**, we lead with the motivating problem, then move to the solution, how it works, and the value it delivers. We keep it brisk, but don't go so fast that we skip over the substance the reader needs. We're specific and scannable, and we assume technical competence, using headings and bullet points to make details easy to find.
* **In marketing and landing pages**, we're more narrative, but still grounded in concrete details, and we avoid the vague, inflated language of typical marketing content. Rather than just listing features, we communicate the value those features deliver, because that's what the reader cares about. Context and well-chosen examples are much better than feature lists, which require the reader to fill in the blanks on their own.
* **In community and social content**, we're genuine, casual, and conversational. For these, we generally use the first-person plural perspective (_we_), because it reads more naturally and is closer to how we'd communicate with the reader in person.
* **In enterprise and sales content**, our tone is less casual, more grounded and formal, but still human, and we're careful to avoid using overly promotional, salesy, or marketing-heavy language.
For guidance on whether to address the reader as _you_ or _we_, see [Person and point of view](/voice/writing-style/#person-and-point-of-view).
## Words and phrases
The following sections are included to help us keep our language consistent. For how to spell, capitalize, and hyphenate specific terms, including Pulumi product and feature names, see [Names & terminology](/voice/names-and-terminology/).
### Prefer
- _Engineers_ and _developers_ over _users_ or _customers_. (The latter are colder and less personal.)
- _Humans and agents_ as a natural pairing when describing who Pulumi is built for.
- _Agents_ or _coding agents_ when referring to AI agents that provision and manage infrastructure.
- _Building blocks_, _components_, and _composable_ when describing our compositional capabilities.
- _Estate_ for the full scope of an organization's infrastructure, as opposed to the less specific _environment_ or _footprint_.
- _Build_, _deploy_, _ship_, and _manage_ as active, concrete verbs.
- _Works with_ or _integrates with_ over the more awkward and inflated _leverages_ or _utilizes_.
- Short sentences and parallel structure in lists.
### Avoid
- Superlatives without evidence like _the best_, _the only_, _the most powerful_, etc.
- Tired buzzwords like _synergy_ and the like.
- Exclamation points and emojis just about everywhere other than social-media posts.
- Sharply negative or combative language and profanity.
## Inclusive language
We strive to use language that's clear, inclusive, and respectful.
- Avoid ableist terms. Instead of _crazy_, use _wild_. Instead of _dummy_, use _placeholder_.
- Avoid unnecessarily gendered language. Instead, use words like _folks_ and _everyone_.
- Avoid violent or aggressive imagery and terms like _kill_ or _clobber_.
- Avoid pop-culture references that may not be globally understood.
- When writing docs, consider _select_ or _choose_ over _click_.
- Instead of _go to_, use _navigate to_.
- Avoid directional terms like _above_ or _below_ unless the reference is close at hand.
- Avoid words like _easy_ or _simple_, as these may alienate readers.
# Writing style
> Grammar, punctuation, and style rules for Pulumi communications.
While closely related to [voice and tone](/voice/voice-and-tone/), style is more about the mechanics of how writing (and content in general) is constructed. Where voice and tone are about emotion and personality, style is more about structure and technique.
## The essentials
- Always [write like a human](#natural-voice). Even when you've used an LLM to help you, your words belong to you.
- Always [respect the reader's time and attention](#respect-the-readers-time-and-attention).
- Give every piece a [clear thesis or driving question](#revision).
- Use headings to [carry the structure and convey the gist](#headings-and-titles).
- Almost always, [address the reader directly](#person-and-point-of-view).
- Nothing ever ships without [human revision and review](#review).
## Respect the reader's time and attention
Our time and attention are among our scarcest resources. When writing for a human (which you should pretty much [always be doing](/voice/voice-and-tone/#who-we-write-for)), never forget there's a person on the other end of the line trying to get value out of your words as they read them. None of us has the time or energy to slog through vague, incomplete, unedited, or overly inflated prose.
See [Drafting, revising, and reviewing](#drafting-revision-and-review) below for help keeping to this principle.
## Natural voice
All of the copy we write should sound like a human being wrote it, even if an LLM helped to create it. Pulumians [are people](/foundations/brand-attributes/), so our readers assume the words we put in front of them are our own. We therefore write like people, not like machines, avoiding patterns that signal generated text, like:
- Awkward sentence fragments used for emphasis. Like this. And this.
- Leading negatives, with or without the typical em-dashes, like _This isn't just about foo — it's about bar._ Cut the negative, say it's about bar, and get on with it.
- Three-item series — a big AI tell. They're fine when you write them yourself, but LLMs use them as filler, and you can usually tell when that's the case. Check each one against your own voice, and if it doesn't feel right, revise or delete.
- Overuse of tables. Unless the table is truly valuable as a table (i.e., it has data in it), consider rewriting it as a list or in prose — or just delete it.
- Too many bullet lists. A few well-placed bullets are a great way to break up walls of text, but a screenful of them is another AI tell. Consider revising as prose to break things up and make the writing more human.
As a rule: Never ship raw LLM output. Every piece of writing we produce must go through a human review and revision cycle in which you, as the author, bring the copy in line with how you — and how we, the keepers of the Pulumi brand — would say it. See [Drafting, revising, and reviewing](#drafting-revision-and-review) for details.
## Person and point of view
### Addressing the reader
In technical content for hands-on engagement (blogs, tutorials, how-to guides), we use the second-person singular perspective (_you_), not the first-person plural (_we_). It's often tempting to use _we_, but except in synchronous workshop scenarios, _we_ aren't doing anything — the reader is. We therefore keep the focus on the reader and on their learning and experience: "In this walkthrough, _you'll_ build", not "_we'll_ build".
The same is true in most marketing content. Instead of "ESC enables teams and organizations to consolidate secrets management", prefer "ESC lets you manage all of your secrets in one place". There are exceptions, but as a rule, second person is clearer and more engaging — as well as how we'd most likely say it in face-to-face conversation.
## Attribution and accuracy
Every claim we make in our copy should come from an attributable source, even if that source is our own internal data.
- Never round up, infer, or embellish.
- If the source describes one person's experience, don't generalize it as "companies" or "teams".
- If the source doesn't give a number, don't invent or estimate one.
## Grammar and punctuation
- We're users of the Oxford (serial) comma, so it's "build, deploy, and manage", not "build, deploy and manage".
- Since human writers use em-dashes ("—"), you're free to use them, too. Revise away, however, the em-dashes emitted by LLMs, because they're strong markers of LLM-generated copy — but don't just swap them out for alternative punctuation like hyphens or commas, because that's just another marker of lazily revised LLM-generated copy. Make the words and the phrasing both grammatically correct and your own.
- Contractions are not only fine, they're preferable, even in docs. ([We write for people](/voice/voice-and-tone/#who-we-write-for).)
- Put commas, periods, and semicolons outside closing quotation marks unless they belong to the quoted text to keep the punctuation from looking like it's part of the literal. For example, write "us-west-2", and a quoted phrase like "it just works", with the punctuation outside.
- Reserve "e.g.," and "i.e.," — both followed by commas — for parenthetical asides, and spell out "for example" or "that is" in running prose.
## Dates, times, and numbers
- Write dates as "June 14, 2026" in prose, and use ISO 8601 ("2026-06-14") in technical and code contexts.
- Write times in 12-hour form with a lowercase "am" or "pm", and always include the time zone, as in "9:00am UTC". Default to UTC unless there's a good reason not to.
- Use an en-dash for numeric ranges ("10–20"), commas in numbers of a thousand or more ("10,000"), and spelled-out scale for large round numbers ("$5 million", not "$5,000,000").
## Code samples
When writing code samples:
- Use four-space indentation for all languages except YAML and Go. With YAML, use two-space indentation. With Go, use tabs.
- Use double-quotes across all languages, single quotes within double-quoted strings.
- Use comments and highlights to call out important sections of the code. Keep comments brief, ideally to one line.
- When quoting a section of code that's indented in the source, omit the leading indentation. For example, to declare a local variable in the body of a JavaScript method belonging to a class (e.g., two levels of indentation), do this:
```javascript
const foo = "bar";
```
Not this:
```javascript
const foo = "bar";
```
The latter may be truer to the source, but without local context, the leading space looks unintentional and can push longer lines, and further nesting, out of view.
- Horizontal scrolling in code samples is usually fine, except when the code under discussion drifts offscreen. Consider splitting up longer lines to ensure the important parts remain visible at desktop width.
- Split long CLI commands into multiple lines to help readers see what's important:
```bash
pulumi do aws:s3:BucketV2 create \
--aws:region us-west-2 \
--aws:access-key \
--aws:allowed-account-ids \
--force-destroy \
--yes
```
## Text formatting
- Use `code` font (backticks) for code, commands, filenames, paths, environment variables, and literal values, as in `pulumi up`, `~/.pulumi`, `AWS_REGION`, and `true`.
- Use bold sparingly for the names of UI elements the reader acts on ("click **Save**"), and for the rare phrase that genuinely needs emphasis. Bold sprinkled throughout is both visually noisy and a common AI tell.
- Use italics for a word or short term you're introducing, defining, or describing — for example: _setup_ is a noun, _set up_ is a verb. Italics are generally appropriate for emphasis, but should also be used sparingly.
- Write placeholders in angle brackets with code elements, like ``, so it's clear what the reader needs to replace.
## Headings and titles
- Avoid clickbaity titles.
- Always use sentence case for headings (e.g., "This is a heading", not "This Is a Heading").
- Avoid ending headings with punctuation.
- Use headings to communicate structure and content. Skimming only the headings, the reader should be able to discern the piece's overall outline and what it's about. Avoid clever headings that don't convey meaning.
- Nest headings properly. For example, don't put an `h3` (`###`) directly under an `h1`. Make it an `h2` instead.
- Keep SEO in mind. Use titles and headings that contain the keywords you're targeting. This'll make it easier for humans to find your content by helping the bots index and rank it. See [the review checklist](#review) for guidance.
- Scrub away common LLMisms like "Stop doing X. Y.", "Why this matters", "What this unlocks", "What this means — and what it doesn't", and the like. See [Generative AI](/guidelines/generative-ai/) for additional details.
## Names & terminology
Product and feature names have their own page: [Names & terminology](/voice/names-and-terminology/). It covers how to spell, capitalize, and hyphenate them, the names we've retired, and the general rules for capitalizing everyday technical terms. That page is canonical; check it whenever you name a Pulumi thing in writing.
For which words to prefer or avoid for voice and tone, see [words and phrases](/voice/voice-and-tone/#words-and-phrases).
## Links
- Make link text descriptive. Avoid linking nondescript words like _here_ or _click here_, and describe what the link points to or what will happen when the reader follows it. This is helpful for humans as well as SEO.
- Look for opportunities for internal linking. When writing about a Pulumi feature, link to that feature's documentation, landing page, or other related resources. This encourages readers to engage and continue learning and also strengthens overall SEO.
## Images and alt text
- Give every meaningful image alt text that describes its content or function in a few words. Omit phrases like "image of" and "screenshot of", since screen readers already announce these.
- Name image files descriptively, both for accessibility and for SEO. (See [the review checklist](#review).)
## Lists
- Introduce lists with a sentence or fragment, usually ending in a colon.
- Write list items as complete sentences — capitalized, and ending with a period — unless the list is deliberately terse, like a set of single terms, in which case drop the periods. Either way, stay consistent within a single list.
- Keep list items parallel. If the first item starts with a verb, they all should start with verbs.
- Only use lists when lists are called for, and prefer prose otherwise. See [Natural voice](#natural-voice) for additional guidance.
## Paragraphs
- Keep paragraphs short, ideally to five sentences or fewer.
- In Markdown documents, separate paragraphs with a blank line.
- Pay attention to how your paragraphs stack up on one another. Each one should follow from the last and set up the next. If two in a row feel interchangeable, or the jump between them seems jarring, reorder or revise until the piece reads as one continuous line of thought.
## Drafting, revision, and review
The following guide applies mainly to longer-form work like blog posts, docs, and whitepapers. Shorter pieces require less, but everything we publish still needs a human review before it goes out.
### Drafting
- Start by asking _What do I want to say?_ _Who is this for?_ and _What will they want to know?_ Answering these questions up front helps you define your thesis and point of view, which makes the writing more interesting, and keeps things focused on what's actually useful to the reader.
- Sketch an outline before you start writing, so the structure is deliberate rather than something you figure out as you go.
- Keep the scope under control. Any piece over 2,500 words is almost surely too long. If you can't say what you need to say within that range, consider breaking it up into multiple pieces.
### Revision
- First drafts aren't final drafts, they're first cuts. Every first draft deserves at least one revision.
- When you're finished with the first draft, read it aloud. If it sounds like you, great. If it doesn't, revise the parts that don't until it does. Remember, [we're humans writing for humans](/voice/voice-and-tone/#who-we-write-for).
- After that, set it aside — at least for an hour, ideally overnight — then give it another read. Does it say what you want it to say? Does it deliver the value the user expects? If not, continue revising.
- Before reviewing, check your title, headings, and overall narrative progression. Sentences, paragraphs, and sections should all build on one another, and the piece should end with next steps and a clear (and contextually appropriate) call to action, not a generic "conclusion".
### Review
- Conduct a self-review with your agent of choice, asking it to critique the piece from your target reader's point of view. The [brand MCP server](/mcp-server/) can do this for you using the contents of this guide. [Add the MCP server](/mcp-server#configuration), paste your draft, and ask your agent for a review:
```text
You're the reader I wrote this for: [and describe your audience]. Read the draft
below and tell me: What's the one thing I'm trying to say, and does it land?
What questions does it leave unanswered? Where is it too long, too vague, or
too generic? What did I overlook, and how could it be stronger? Use the Pulumi
brand guidelines in your assessment.
```
- Ensure you've covered the SEO basics:
- Use the keywords you're targeting in the URL slug, page title, H1, and H2s.
- Use a descriptive, social media-friendly meta description.
- Use descriptive link text, and be sure to include links to relevant internal and external resources.
- Use well-labeled images.
- Request a human review. Every piece — docs, blogs, landing pages, social posts, even ad copy — must be reviewed by one of your fellow Pulumians before you can publish it. Longer-form works must be reviewed by a member of the Editorial Board.
- Address the feedback. If a human raises an issue, you must address and resolve the issue before you can publish.
## See also
- [Guidelines for voice and tone](/voice/voice-and-tone/)
- [Names & terminology](/voice/names-and-terminology/)
- [Rules for using generative AI](/guidelines/generative-ai/)