Skip to content

A remote MCP with OAuth that gives AI tools secure access to your Datum resources

Notifications You must be signed in to change notification settings

datum-cloud/datum-mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Datum Logo

Datum MCP Server

Empower agents to help you manage your network infrastructure

datum-mcp

An MCP server for Datum Cloud with OAuth 2.1 (PKCE) auth, macOS Keychain token storage, and tools for listing/operating on organizations, projects, domains, HTTP proxies, HTTP routes, gateways, traffic protection policies, DNS zones/records, and CRD schemas.

Installation

  • Quick install (auto-detects your platform and installs to a user-writable PATH):
curl -fsSL https://github.com/datum-cloud/datum-mcp/releases/latest/download/install.sh | sh
  • Manual download:
    • Download the appropriate binary from the latest release
      • macOS: datum-mcp_darwin_arm64, datum-mcp_darwin_amd64
      • Linux: datum-mcp_linux_amd64, datum-mcp_linux_arm64
      • Windows: datum-mcp_windows_amd64.exe (and optionally windows_arm64)
    • Rename to datum-mcp (or datum-mcp.exe on Windows) and place it somewhere on your PATH.

MCP client config in Claude desktop and Claude:

Mode: stdio

{
  "datum-mcp": {
    "command": "datum-mcp",
    "args": []
  }
}

Cursor config in stdio mode (macOS/Linux):

Install MCP Server

Windows:

On Windows, point your MCP config to the full path where you installed the binary:

{
  "datum-mcp": {
    "command": "<path prefix here>/datum-mcp.exe",
    "args": []
  }
}

Build

go build ./cmd/datum-mcp

Auth flow

  • On first use, the server opens a browser for OAuth (PKCE), then stores credentials (including refresh token) in the system keychain.
  • Subsequent calls reuse/refresh the token from keychain automatically.
  • We log to stderr; JSON-RPC uses stdout.

Environment variables (Optional)

  • DATUM_AUTH_HOSTNAME (default auth.datum.net)
  • DATUM_API_HOSTNAME (derived from auth host if unset)
  • DATUM_CLIENT_ID (inferred for *.datum.net and *.staging.env.datum.net)
  • DATUM_TOKEN (override bearer token; skips login)
  • DATUM_VERBOSE (true to print verbose auth logs)
  • DATUM_USER_ID (override user subject; otherwise from stored credentials)
  • DATUM_ORG (active organization for project listing)

Register with your MCP client

The binary speaks MCP over stdio or streamable http. Register it (e.g., in Claude Desktop) as a command transport pointing to the built executable.

Run modes

  • Stdio (http coming soon):
datum-mcp

Tools

All tools accept JSON inputs and return both structured content and a pretty-printed text block for UIs that show text only.

  • organizationmemberships

    • Actions: list | get | set
    • Input:
      • List memberships for current user: { "action": "list" }
      • Get active organization: { "action": "get" }
      • Set active organization (verifies membership): { "action": "set", "body": { "name": "<org-id>" } }
    • User resolution: DATUM_USER_ID env, else subject from stored credentials.
  • users

    • Actions: list
    • Input:
      • List users (org memberships) under an organization: { "action": "list", "org": "<org-id>" }
    • Lists org-scoped memberships in namespace organization-<org> using the org control-plane client.
  • projects

    • Actions: list | get | set | create
    • Input:
      • List: { "action": "list", "org": "<org-id>" } (or set DATUM_ORG and omit org)
      • Get active: { "action": "get" }
      • Set active (verifies existence in org): { "action": "set", "body": { "name": "<project-id>" }, "org": "<optional>" }
      • Create: { "action": "create", "org": "<org-id>", "body": { "metadata": { "name": "<project-id>" }, "spec": { ... } } }
    • Org resolution: org input, else DATUM_ORG env, else stored active org.
  • domains

    • Actions: list | get | create | update | delete
    • Input:
      • List: { "action": "list", "project": "<optional>" }
      • Get: { "action": "get", "id": "<name>", "project": "<optional>" }
      • Create: { "action": "create", "body": { ... }, "project": "<optional>" }
      • Update: { "action": "update", "id": "<name>", "body": { ... }, "project": "<optional>" }
      • Delete: { "action": "delete", "id": "<name>", "project": "<optional>" }
    • Project resolution: project input, else active project (from projects set).
    • Namespace: list/get/create/update run in namespace default.
  • httpproxies

    • Same shape and behavior as domains (namespaced list/get/create/update; delete by name).
  • httproutes

    • Same shape and behavior as domains (namespaced list/get/create/update; delete by name).
    • Targets Gateway API HTTPRoute resources.
  • gateways

    • Same shape and behavior as domains (namespaced list/get/create/update; delete by name).
    • Targets Gateway API Gateway resources.
  • trafficprotectionpolicies

    • Same shape and behavior as domains (namespaced list/get/create/update; delete by name).
    • Policies are intended to target either Gateway or HTTPRoute resources.
    • Group/kind: networking.datumapis.com / TrafficProtectionPolicy.
  • dnszones

    • Actions: list | get | create | update | delete
    • Input:
      • List: { "action": "list", "project": "<optional>" }
      • Get: { "action": "get", "id": "<name>", "project": "<optional>" }
      • Create: { "action": "create", "body": { ... }, "project": "<optional>" }
      • Update: { "action": "update", "id": "<name>", "body": { ... }, "project": "<optional>" }
      • Delete: { "action": "delete", "id": "<name>", "project": "<optional>" }
    • Project resolution: project input, else active project (from projects set).
    • Namespace: operates in namespace default.
    • Group/kind: dns.networking.miloapis.com / DNSZone.
  • dnsrecordsets

    • Actions: list | get | create | update | delete
    • Input:
      • List: { "action": "list", "project": "<optional>" }
      • Get: { "action": "get", "id": "<name>", "project": "<optional>" }
      • Create: { "action": "create", "body": { ... }, "project": "<optional>" }
      • Update: { "action": "update", "id": "<name>", "body": { ... }, "project": "<optional>" }
      • Delete: { "action": "delete", "id": "<name>", "project": "<optional>" }
    • Project resolution: project input, else active project (from projects set).
    • Namespace: operates in namespace default.
    • Group/kind: dns.networking.miloapis.com / DNSRecordSet.
  • dnszoneclasses

    • Actions: list | get
    • Input:
      • List: { "action": "list", "project": "<optional>" }
      • Get: { "action": "get", "id": "<name>", "project": "<optional>" }
    • Scope: cluster-scoped (no namespace).
    • Group/kind: dns.networking.miloapis.com / DNSZoneClass.
  • apis (CRDs list/describe via upstream OpenAPI/kubectl explain logic)

    • Actions: list | get
    • Input:
      • List groups/versions and resources: { "action": "list", "project": "<optional>" }
      • Get a schema for a specific kind: { "action": "get", "group": "<group>", "version": "<version>", "kind": "<Kind>", "project": "<optional>" }
    • Behavior:
      • list reads the project control-plane OpenAPI v3 index and returns groups, versions, and resources with name, kind, and namespaced.
      • get fetches the OpenAPI v3 document for the given group/version and returns the full upstream-rendered schema for the requested kind (no custom trimming).

Recommended workflow

  1. organizations → list orgs
  2. organizations → set active org
  3. projects → list for an org
  4. projects → set active project
  5. Use domains / httpproxies / httproutes / gateways / trafficprotectionpolicies / dnszones / dnsrecordsets / dnszoneclasses for CRUD/list/get, or apis to inspect CRD schemas

About

A remote MCP with OAuth that gives AI tools secure access to your Datum resources

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 12