Community Voices
Explore thought pieces, announcements and product news
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Christoph_Neum
Dynatrace Mentor
Dynatrace Mentor

TL;DR: We open-sourced dtctl, a CLI for Dynatrace that brings terminal-native workflows and AI agent integration to the platform. Manage workflows, dashboards, SLOs, and 20+ resource types from your terminal or let your AI coding assistant do it. Install it with brew install dynatrace-oss/tap/dtctl.

When you're scripting a deployment pipeline, managing configurations across environments, or letting an AI agent operate your observability stack -- you want a CLI.

What is dtctl?

dtctl is a CLI that gives you a consistent interface to the Dynatrace platform. Single binary, zero dependencies, runs on Linux, macOS, and Windows. One grammar, one tool, all resources:

dtctl get workflows                        # list all workflows
dtctl describe dashboard my-dashboard      # inspect a dashboard by name
dtctl apply -f slo.yaml                    # create or update -- idempotently
dtctl query "fetch logs | limit 10"        # run DQL right from your terminal
dtctl exec copilot "What caused the spike?" # ask Davis CoPilot

If you've used tools like kubectl or gh, the pattern will feel familiar: verb first, resource second, done.

The project is open source under Apache 2.0 and available on GitHub: dynatrace-oss/dtctl.

What It Gives You

You automate everything else -- why not your observability platform?

Here's what dtctl gives you over raw API calls:

  • OAuth login. dtctl auth login opens your browser for SSO authentication -- no more copying API tokens around. Tokens are stored in your OS keyring and refreshed automatically.
  • Multi-environment management. Switch between dev, staging, and prod with dtctl config use-context prod.
  • Idempotent apply. dtctl apply -f workflow.yaml creates if new, updates if it exists. No more manual GET-then-POST-or-PUT dances.
  • Flexible output formats. Switch between table, JSON, YAML, and CSV with -o json, -o yaml, etc. Pipe it into jq, feed it to another script, or just read a table.
  • Name resolution. Use human-readable names instead of UUIDs. When names collide, dtctl asks which one you mean.
  • --mine filter. Scope any listing to resources you own with dtctl get workflows --mine. Handy in shared environments.
  • DQL templates. Parameterize queries with --set env=prod --set host=h-123 and reuse them across environments.
  • Safety guardrails. Set your production context to readonly and sleep well at night. Context-based safety levels prevent accidental mutations before they hit the wire (client side enforcement).
  • Shell completions. Tab-complete commands, resource types, and flags in bash, zsh, fish, and PowerShell.
  • Watch mode. dtctl get workflows --watch gives you a live-updating terminal view with color-coded change indicators.

Built for AI Agents

CLI tools are a natural fit for AI coding agents -- they're already running in a terminal, and a well-structured command with predictable output is exactly the kind of interface an LLM can use reliably. dtctl was designed from the ground up with this in mind, serving as an interface between AI coding agents and the Dynatrace platform. Run it with --plain -o json and any agent gets clean structured output it can reason about -- no spinners, no color codes, no interactive prompts.

It ships with a built-in skill file that teaches AI assistants how to operate your Dynatrace environment. Drop it into your project, and your agent can query logs, check SLO status, trigger workflows, and manage configurations without you writing a single line of glue code.

What's Supported?

Over 20 resource types today, including workflows, dashboards, notebooks, SLOs, buckets, settings, apps, functions, notifications, users, groups, and cloud connections (Azure, GCP). Most support full CRUD, plus extras like history, restore, diff, share, and watch where the underlying API allows it.

Check the implementation status matrix for the full picture.

Getting Started

# Install via Homebrew
brew install dynatrace-oss/tap/dtctl

# Configure your first context
dtctl config set-context my-env \
  --url https://abc12345.apps.dynatrace.com \
  --token <your-api-token>

# Start exploring
dtctl get workflows
dtctl get dashboards --mine
dtctl query "fetch logs | filter loglevel == \"ERROR\" | limit 5"

For detailed setup options (binary download, building from source, shell completions), see the Installation Guide. For hands-on examples covering all resource types, check the Quick Start Guide.

See It in Action

Want to see dtctl in action before installing? Check out the demo video on YouTube.

We'd Love Your Feedback

This is an early release -- v0.13.0 as of this writing -- and we're actively shaping the tool based on real-world usage. If you have ideas, find bugs, or want to contribute, head over to the GitHub repo and open an issue. And if you find dtctl useful, drop us a star on GitHub -- it helps others discover the project and keeps us motivated.

6 Comments
jegron
DynaMight Champion
DynaMight Champion

Congratulations for your work. We have been using it for a few weeks now 🤖

TomLichti
Helper

@Christoph_Neum I'm not sure where to put this, here or on Github, but I've been trying to use the 'update sesttings' feature as it would save a LOT of time with bulk updates, but when I try to use the -f flag to include a file as input as per the documentation, I get an error 'unknown flag':

dtctl --plain update settings *UUID* -f config.yaml --dry-run

{
  "ok": false,
  "result": null,
  "error": {
    "code": "error",
    "message": "unknown flag --f"
  }
}

Am I doing something wrong? Aside from this, I love the tool and feel like it has a lot of potential use cases, but in my particular case, it doesn't work.

Tom

Christoph_Neum
Dynatrace Mentor
Dynatrace Mentor

@TomLichti 
Hi Tom, thanks for the report and glad you're finding the tool useful!
The functionality you're looking for actually already exists via the apply command. Instead of update settings, use:

dtctl apply -f config.yaml
dtctl apply -f config.yaml --dry-run

Your file just needs to include the full settings object structure with objectId, schemaId, scope, and value -- if the objectId exists, it gets updated; otherwise a new object is created. This works for bulk updates too since apply handles the create-or-update logic automatically.
Example config.yaml:


objectId: "vu9U3hXa3q0AAAABAClidWlsdGluOnJ1bS5..."
schemaId: "builtin:rum.frontend.name"
scope: "environment"
value:
enabled: true
name: "my-config"


I made a PR to give a built-in hint about this: https://github.com/dynatrace-oss/dtctl/pull/142

 

TomLichti
Helper

@Christoph_Neum I finally got a chance to exercise this apply command, and it works, sort of. The workflow described in the document says to download the existing settings, edit the file to suit, and then apply the update. I've found that you can download all of the settings, but you can only 'apply' a single object. A multi-object file does not work for me, and it only works with JSON files, YAML files don't work at all. For example, I follow these steps:

dtctl get settings --schema builtin:rum.web.enablement -o yaml > nonprod-rumconfig-demo.yaml

The file has 48 application configurations. I edit the file and change one of the configurations to 50% capture rate, and save the file. Then I run:

dtctl apply -f .\nonprod-rumconfig-demo.yaml

And I get:

←[1m←[31mError:←[0m failed to parse JSON: json: cannot unmarshal array into Go value of type map[string]interface {}

If I edit the YAML file down to just the single objectId, I get the same result. If I do the same thing with JSON, it fails to apply the whole file, but if I reduce it down to a single objectId, I can then apply the update. This is great for a single instance, but my understanding was that it would apply the whole file and only update/create what has changed. I have 29 applications that I need to update, and I thought dtctl would allow me to do them in bulk, but it seems I have to split the downloaded file into individual ones and then apply each one separately.

As an aside, the results always seems to have some odd escape characters at the beginning, as shown above: "←[1m←[31m" If I use '--plain' it then shows the output. I assume this is because I am on Windows Powershell. If the code could compensate for that it would be appreciated.

Additionally, after googling the error, it appears that the dtctl is not expecting an array object in the file to apply, which is why the single one works.

 

 

Christoph_Neum
Dynatrace Mentor
Dynatrace Mentor

@TomLichti Thank you. Sounds like a bug. May I ask you to please file an issue directly on https://github.com/dynatrace-oss/dtctl/issues - thank you!

TomLichti
Helper

Will do, thanks!