Skip to content

teamdynamix-mcp is a layered TypeScript MCP server. Each layer has a single responsibility; dependencies only flow downward.

text
┌──────────────────────────────────────────────────────────────┐
│                     MCP Transport                            │  src/index.ts
│               (StdioServerTransport)                         │
├──────────────────────────────────────────────────────────────┤
│                    Tool Handlers                             │  src/tools/*.tools.ts
│      (Gateway action validation, safety guards, routing)     │
├──────────────────────────────────────────────────────────────┤
│             TeamDynamixClient (HTTP + auth)                  │  src/services/teamdynamix/client.service.ts
│          Core helpers (dates, patch, rate limit)             │  src/services/teamdynamix/core.service.ts
└──────────────────────────────────────────────────────────────┘

Directory Structure

text
src/
├── index.ts                         # MCP entry point — registers all gateway tool families
├── config.ts                        # TeamDynamix + MCP env var parsing
├── constants.ts                     # Shared constants (tool prefix, character limits)
├── types.ts                         # Shared TypeScript types (auth config, request options)
├── schemas/
│   └── teamdynamix/index.ts         # All Zod input schemas (tickets, KB, assets, CI, projects …)
├── tools/
│   ├── teamdynamix.domain-gateways.tools.ts  # Domain gateway registrations + action routing
│   ├── teamdynamix.discovery.tools.ts        # Legacy direct tool module (kept for compatibility tests)
│   ├── teamdynamix.tickets.tools.ts          # Legacy direct tool module
│   ├── teamdynamix.ticket-tasks.tools.ts     # Legacy direct tool module
│   ├── teamdynamix.people.tools.ts           # Legacy direct tool module
│   ├── teamdynamix.kb.tools.ts               # Legacy direct tool module
│   ├── teamdynamix.assets.tools.ts           # Legacy direct tool module
│   ├── teamdynamix.services.tools.ts         # Legacy direct tool module
│   ├── teamdynamix.cmdb.tools.ts             # Legacy direct tool module
│   └── teamdynamix.enumeration.tools.ts      # Legacy direct tool module
├── services/
│   ├── teamdynamix/
│   │   ├── client.service.ts        # TeamDynamixClient — HTTP, auth, retry, safety guards
│   │   └── core.service.ts          # Date helpers, JSON Patch builder, rate limit parser, JWT decode
│   └── __tests__/                   # Service unit tests
└── resources/
    └── teamdynamix.resources.ts     # TeamDynamix MCP resources (capabilities, config)

Layer Responsibilities

Transport layer (src/index.ts)

  • Creates the MCP server instance using @modelcontextprotocol/sdk
  • Imports and calls registerTeamDynamixDomainGatewayTools
  • Registers MCP resources
  • Starts StdioServerTransport

Tool handlers (src/tools/*.tools.ts)

  • Accept domain gateway inputs (action, payload, response_format)
  • Validate payload per action with Zod schemas
  • Call assertWriteToolsEnabled or assertAdminToolsEnabled before mutating operations
  • Delegate to TeamDynamixClient methods
  • Format and return the response
  • Keep behavior thin and predictable

Gateway model

The exposed MCP surface is intentionally reduced to domain gateways:

  • teamdynamix_discovery
  • teamdynamix_tickets
  • teamdynamix_ticket_relationships
  • teamdynamix_people
  • teamdynamix_knowledge_base
  • teamdynamix_assets
  • teamdynamix_cmdb
  • teamdynamix_services
  • teamdynamix_projects
  • teamdynamix_time
  • teamdynamix_reference_data

Each gateway routes named actions to the underlying client methods.

TeamDynamixClient (src/services/teamdynamix/client.service.ts)

  • Manages bearer token cache (standard and admin) with expiry-aware refresh
  • Retries on transient failures up to TEAMDYNAMIX_MAX_RETRIES
  • Parses X-RateLimit-Reset and waits at least TEAMDYNAMIX_MIN_RATE_LIMIT_WAIT_MS on 429
  • All HTTP methods are typed Record<string, unknown> to stay schema-agnostic
  • Exports assertWriteToolsEnabled and assertAdminToolsEnabled guards
  • Never imports MCP SDK types

Core helpers (src/services/teamdynamix/core.service.ts)

  • toTeamDynamixDateTime / toTeamDynamixDateOnly — normalises ISO 8601 to TDX wire format
  • buildTeamDynamixJsonPatchDocument — converts user-facing path strings to RFC 6902 op/path/value objects
  • parseRateLimit — extracts wait duration from rate limit response headers
  • decodeJwtExpiryEpochSeconds — reads exp claim from TDX JWT to enable proactive token refresh
  • redactTeamDynamixConfig — strips secrets before logging the config

Schemas

All TeamDynamix Zod schemas live in src/schemas/teamdynamix/index.ts. Each domain section is separated by comments. Schemas are imported into tool files and used as inputSchema directly.

Configuration

src/config.ts parses environment variables at startup and exports a typed TeamDynamixConfig. Tool handlers call getTeamDynamixConfig() rather than reading process.env directly. The config includes all connection, auth, and safety flag values.

Safety policy

Two safety guards gate mutating and administrative operations:

  • assertWriteToolsEnabled(config) — throws unless enableWriteTools is true (TEAMDYNAMIX_ENABLE_WRITE_TOOLS=true)
  • assertAdminToolsEnabled(config) — throws unless enableAdminTools is true (TEAMDYNAMIX_ENABLE_ADMIN_TOOLS=true)

Destructive tools (remove asset link, remove contact, etc.) additionally include a confirm: z.literal(true) field in the input schema. The MCP SDK enforces this at the schema level before the handler is called.

Response Formatting

All tool responses support two formats:

  • "markdown" (default) — human-readable output
  • "json" — a JSON object suitable for programmatic consumption

Formatting helpers are co-located with tool handlers.

Character Limit

Large outputs are truncated to CHARACTER_LIMIT (defined in src/constants.ts) to avoid overwhelming MCP clients.

Error Model

Errors should be returned as structured objects with:

  • A human-readable message explaining what went wrong
  • Where applicable, guidance on how to resolve the issue

No errors should be swallowed silently.

Build

bash
pnpm build       # tsup bundles src/ → dist/
pnpm start       # node dist/index.js
pnpm dev         # tsx watch src/index.ts (hot reload)
pnpm typecheck   # tsc --noEmit

tsup is configured to target Node.js, produce CJS output, and emit type declarations.

Released under the MIT License.