feat(pulumi): @mcpctl/pulumi — generic Pulumi provider for mcpctl
Some checks failed
CI/CD / lint (pull_request) Successful in 1m3s
CI/CD / typecheck (pull_request) Successful in 2m5s
CI/CD / test (pull_request) Successful in 1m19s
CI/CD / smoke (pull_request) Failing after 2m46s
CI/CD / build (pull_request) Successful in 2m25s
CI/CD / publish (pull_request) Has been skipped

New workspace package: a Pulumi dynamic provider (TypeScript, in-process) that
manages mcpctl resources declaratively from any Pulumi program. Motivated by
model drift: when the deployed vLLM/LiteLLM model changes, mcpctl's llm target
must follow, and a Pulumi resource makes that automatic on `pulumi up`.

- Generic core `McpctlResource({ kind, name, spec, mcpd })` round-trips ANY
  mcpctl resource kind; typed `Llm` wrapper for ergonomics.
- Engine talks direct HTTP to mcpd's REST API (ported from cli/api-client.ts),
  mirroring apply's name-keyed upsert (PUT strips immutable name/type) and
  get -o json's read field-stripping. No mcpctl binary needed → CI-friendly.
- CRUD/diff/check with correct replace semantics (name/type/kind/mcpd.url force
  delete-before-replace), 429 retry, secret token in state.
- Validation deferred to mcpd's Zod schemas, so new resource kinds work with no
  provider release.
- CommonJS build so the serialized dynamic provider's module refs are captured.
- 18 Vitest tests (mocked mcpd + Pulumi mocks); build + lint clean; README with
  auth (PAT) setup and consumer example for kubernetes-deployment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michal
2026-07-17 22:02:22 +01:00
parent e2db8d9003
commit f3d92235db
16 changed files with 2222 additions and 10 deletions

34
src/pulumi/package.json Normal file
View File

@@ -0,0 +1,34 @@
{
"name": "@mcpctl/pulumi",
"version": "0.0.1",
"description": "Pulumi dynamic provider for mcpctl resources (llms, servers, projects, ...). Manage mcpctl declaratively from any TypeScript Pulumi program.",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"exports": {
".": {
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"scripts": {
"build": "tsc --build",
"clean": "rimraf dist",
"test": "vitest",
"test:run": "vitest run"
},
"keywords": [
"pulumi",
"mcpctl",
"mcp",
"provider"
],
"peerDependencies": {
"@pulumi/pulumi": "^3.0.0"
},
"devDependencies": {
"@pulumi/pulumi": "^3.0.0"
}
}