by PreMan-Inc
Turn REST APIs into hosted MCP servers with scoped agent tokens, continuous health probes, automated self‑healing, and audit logging.
Turn REST APIs into hosted MCP servers, add scoped consumer tokens, record audit logs, and enable continuous health monitoring with automated repair workflows.
npm install preman-sdk or run commands directly with npx.npx preman-sdk init --api-key pm_live_your_key
# or export PREMAN_API_KEY
npx preman-sdk register --file endpoints.json --upstream https://api.company.com
npx preman-sdk monitor \
--endpoint-id <endpoint-id> \
--interval-seconds 60 \
--expected-status 200
npx preman-sdk healing-rule \
--endpoint-id <endpoint-id> \
--after-failures 3
npx preman-sdk deploy --name "Auth MCP" --file endpoints.json --upstream https://api.company.com
npx preman-sdk token list --mcp-id mcp_123
npx preman-sdk token create --mcp-id mcp_123 --scopes auth:login --consumer-label cursor-agent
npx preman-sdk assert --file preman.assert.json
npx preman-sdk test --suite preman.agent-tests.json
PremanClient in TypeScript and call the same operations via the SDK.Do I need a PreMan account? Yes, an account provides a workspace and API key required for most operations.
Can I use the SDK without the CLI? Absolutely – import PremanClient in your TypeScript code and call the same methods.
What environments are supported for the hosted MCP? Any HTTP API reachable by PreMan; you can also run a local STDIO process via the tunnel command.
How are secrets protected? Secrets are passed only via environment variables; the CLI never writes them to config files or command histories.
Is there a rate limit on token usage? Tokens can be created with optional RPM limits; enforcement occurs in the hosted MCP runtime.
Can I run the SDK in CI without an API key? Assertion and agent‑test commands (assert, test) work offline and do not require a key.
How do I generate TypeScript types for my endpoints? Use preman typegen --file endpoints.json --out preman-endpoints.ts or preman typegen --mcp-id <id> --client for hosted catalogs.
PreMan continuously tests API endpoints and turns production failures into validated code fixes and pull requests.
Use this SDK to register endpoints, schedule safe probes, define when failures should trigger repair, inspect incidents, and run PreMan's native self-healing workflow. Hosted MCP access controls and post-agent action verification remain available as secondary capabilities.
Your API endpoints
-> continuous probes and failure rules
-> incident with a reproducible fix task
-> native repair + validation
-> fix branch and pull request
npm install preman-sdk
Or run the CLI directly:
npx preman-sdk init --api-key pm_live_your_key
The CLI uses your PreMan workspace API key. Create or copy one from PreMan Settings. The key currently starts with pm_live_.
You can also skip init and set an environment variable:
export PREMAN_API_KEY=pm_live_your_key
# PREMAN_API_KEY also works for compatibility with the PreMan MCP.
Create endpoints.json:
[
{
"method": "POST",
"path": "/auth/login",
"description": "Login with email and password.",
"scope": "auth:login",
"requestBodySchema": {
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"password": { "type": "string" }
},
"required": ["email", "password"]
}
}
]
Register the endpoints from code or CI:
npx preman-sdk register --file endpoints.json --upstream https://api.company.com
Once the endpoint is saved in your PreMan workspace, enable a one-minute health probe:
npx preman-sdk monitor \
--endpoint-id <endpoint-id> \
--interval-seconds 60 \
--expected-status 200
Create a rule that starts native repair after three consecutive failures:
npx preman-sdk healing-rule \
--endpoint-id <endpoint-id> \
--after-failures 3
healing-rule enables autofix by default. When the rule fires and the workspace has an eligible connected repository, PreMan packages the failing request and observed response, maps it to the code, patches and validates the fix, pushes a branch, and opens a PR. It does not merge automatically.
Follow incidents and repairs from the CLI:
npx preman-sdk incidents
npx preman-sdk fixes --status open
npx preman-sdk heal --fix-task-id <fix-task-id> --wait
Or configure the same loop in TypeScript:
import { PremanClient } from "preman-sdk";
const preman = new PremanClient();
const endpointId = process.env.PREMAN_ENDPOINT_ID!;
await preman.configureEndpointProbe({
endpointId,
intervalSeconds: 60,
expectedStatus: 200,
});
await preman.createHealingRule({
targetId: endpointId,
thresholdFailures: 3,
autofixEnabled: true,
});
Probe credentials are encrypted at rest and only their header names are returned. Scheduled requests default to read_only; destructive or billing-sensitive endpoints require an explicit unattendedPolicy.
Open app.preman.live to watch endpoint health, investigate incidents, and follow each repair through validation and PR creation.
To embed the same deterministic Investigate with agent path, create a durable Workbench conversation and queue the repository task against it. The returned fix-task id is the stable handle for progress and the eventual review PR; the SDK never merges or deploys it.
const conversation = await preman.createWorkbenchConversation({
title: "Investigate GET /health",
});
const handoff = await preman.createCodingAgentTask({
conversationId: conversation.id,
title: "Investigate GET /health",
instructions: "Use the captured failure, repair it, validate it, and open a review PR.",
executionMode: "workspace_write",
});
const task = await preman.getFixTask(handoff.fixTask.id);
console.log(task.dispatchStage, task.prUrl);
For conversational investigations, streamWorkbenchMessage() emits typed
status, delta, done, and error events and returns the persisted final
turn.
Execute a request already saved in the Workbench and receive the server-graded result, including assertion details and Pulse correlation identifiers:
const run = await preman.runSavedRequest({
requestId: "saved-request-id",
workspaceId: "workspace-id", // optional; defaults to the API key's workspace
});
console.log(run.status, run.responseStatus, run.latencyMs);
console.log(run.assertions, run.classification);
console.log(run.correlationId, run.pulseRunId);
PreMan blocks requests classified as destructive or billing-sensitive unless
that specific run is explicitly approved. Only after intentionally reviewing
the saved request, opt in for one execution with approveDestructive: true.
The approval is sent for that run only; it does not change the saved request or
create standing authorization.
Use the project-scoped Pulse APIs for custom health views and evidence-backed blast-radius analysis:
const health = await preman.listEndpointHealth({
projectId: "project_123",
window: "24h",
statuses: ["failed", "error"],
sort: "error_rate",
limit: 50,
});
const metrics = await preman.getEndpointHealthMetrics({
projectId: health.projectId,
window: "24h",
endpointKey: health.endpoints[0]?.endpointKey,
});
const dependencies = await preman.getEndpointDependencies({
projectId: health.projectId,
});
Dependency edges mean source depends on target. They come from explicit
collection declarations or stored endpoint-edge evidence; PreMan does not infer
them from route names or shared trace IDs.
For a current-health summary, use the latest available result for each endpoint
(including observations.probes[].lastOk) instead of treating every failure in
the selected range as still open. Present aggregate failures as failed checks
inside the response's start/end window; when run-level history shows a newer
successful check for the same endpoint, mark the earlier failure resolved. Keep
the returned window visible beside any count derived from it.
PreMan can also expose registered APIs as hosted MCP servers with scoped consumer tokens, policy controls, and audit logs. This remains supported for teams that need to secure agent access, but it is no longer the SDK's primary workflow.
PreMan can sit in front of APIs you discover from docs or MCP servers you already run. Agents install one PreMan URL; PreMan stores the approved tool catalog, applies auth and policy, and logs every call.
Create a hosted MCP from public API docs:
npx preman-sdk import-docs \
--url https://docs.company.com/api-reference \
--name "Company API MCP" \
--upstream https://api.company.com \
--max-endpoints 120
Preview discovery without deploying:
npx preman-sdk import-docs \
--url https://docs.company.com/api-reference \
--preview
Put an existing remote MCP server behind a PreMan gateway:
npx preman-sdk import-remote-mcp \
--url https://mcp.company.com/mcp \
--name "Company MCP Proxy" \
--upstream-secret-env COMPANY_MCP_TOKEN \
--auth-type header \
--auth-name Authorization \
--auth-prefix "Bearer "
Register and run a local STDIO MCP through a PreMan tunnel:
npx preman-sdk tunnel \
--name "Local Files MCP" \
--command npx \
--arg -y \
--arg @modelcontextprotocol/server-filesystem \
--arg . \
--scope files:read \
--env FILESYSTEM_ROOT
tunnel sends command metadata and env var names to PreMan, but env values stay
on your machine. The local connector process forwards JSON-RPC messages between
the hosted PreMan gateway and the STDIO MCP process so hosted audit logs,
consumer-token scoping, and policy checks can stay in the PreMan runtime. Use
--register-only when you only want to create the hosted tunnel record without
starting the local process.
List the hosted MCPs in your workspace:
npx preman-sdk hosted-mcps
npx preman-sdk hosted-mcps --id mcp_123
preman assert evaluates deterministic state checks against either a supplied
observation or one read from a staging/system-of-record API with a read-only HTTP
probe. This command does not call the PreMan API and does not require
PREMAN_API_KEY.
Create preman.assert.json:
{
"id": "refund-created-correctly",
"probe": {
"url": "https://staging.example.com/refunds?order_id=1049",
"method": "GET",
"headersFromEnv": {
"Authorization": "STAGING_AUTHORIZATION"
},
"notFoundStatuses": [404],
"timeoutMs": 5000
},
"assertions": [
{ "op": "exists", "pointer": "/refunds/0" },
{ "op": "equals", "pointer": "/refunds/0/amount", "expected": 82 },
{ "op": "equals", "pointer": "/refunds/0/status", "expected": "issued" },
{ "op": "no_duplicate", "pointer": "/refunds" },
{ "op": "latency_threshold", "maxMs": 1000 }
]
}
Run it:
export STAGING_AUTHORIZATION="Bearer staging-token"
npx preman-sdk assert --file preman.assert.json
The command prints structured JSON. A fully passing check exits 0; assertion mismatches or verifier errors exit non-zero.
Assertion semantics are intentionally strict:
exists checks structural presence, not truthiness. null, false, 0, and "" exist.not_exists passes only for structural absence.equals uses deep strict JSON equality. Object key order does not matter; array order does.contains supports string substring checks and array member checks with deep equality.no_duplicate expects an already-filtered array and passes when it has at most one item.latency_threshold compares the observation latency to maxMs.Verdicts distinguish business-state mismatch from verifier failure:
passed means the observed state satisfies the assertion.failed means trustworthy observed state contradicted the assertion.error means the verifier could not establish the assertion reliably.For HTTP probes, 2xx responses produce an observation, 404 represents absence,
only when the probe explicitly includes "notFoundStatuses": [404], and
401/403/404/429/other 4xx/5xx/timeout/network/malformed JSON responses are
verifier errors otherwise. Probes support only GET and HEAD, reject URL
username/password credentials, use environment-backed headers for target
credentials in file-based CLI configs, and do not serialize resolved secrets.
Endpoint evidence preserves query parameter names but redacts query values and
strips URL fragments.
File-based assertion configs reject literal probe.headers values to avoid
committing credentials accidentally. Use headersFromEnv for preman assert --file .... Programmatic TypeScript callers may still pass literal headers
to runHttpAssertionCheck when they construct the probe in code. HTTP probe
latency measures the time required to obtain a usable observation, including
response body consumption and parsing.
Programmatic use:
import { evaluateStateAssertions, runHttpAssertionCheck } from "preman-sdk/assertions";
const pure = evaluateStateAssertions(
{ found: true, value: { refunds: [{ amount: 82 }] }, latencyMs: 37 },
[
{ op: "exists", pointer: "/refunds/0" },
{ op: "equals", pointer: "/refunds/0/amount", expected: 82 },
],
);
const probed = await runHttpAssertionCheck({
probe: {
url: "https://staging.example.com/refunds?order_id=1049",
headersFromEnv: { Authorization: "STAGING_AUTHORIZATION" },
notFoundStatuses: [404],
},
assertions: [{ op: "no_duplicate", pointer: "/refunds" }],
});
This is the SDK-side assertion/probe foundation. It does not define an action-contract schema, consistency-window polling, replay, certification, or server-side verification event storage.
preman test runs a suite of action tests: it drives an action, checks the
response, then verifies backend state with the same assertions described above.
Like preman assert, it runs without a PreMan API key.
npx preman-sdk test --suite preman.agent-tests.json
npx preman-sdk test --suite preman.agent-tests.json --json --bail
npx preman-sdk test --suite preman.agent-tests.json --dry-run
A suite is a JSON file. Each test has an action, and at least one of expect
(assertions against the action response) or verify (an assertion config,
identical in shape to preman assert, run against backend state afterwards).
{
"version": 1,
"name": "refund-agent-actions",
"tests": [
{
"id": "refund-created",
"action": {
"kind": "http",
"method": "POST",
"url": "https://staging.example.com/agent/refund",
"headersFromEnv": { "Authorization": "STAGING_AUTHORIZATION" },
"body": { "order_id": 1049, "amount": 82 }
},
"expect": [{ "op": "equals", "pointer": "/status", "expected": "accepted" }],
"verify": {
"probe": { "url": "https://staging.example.com/refunds?order_id=1049" },
"assertions": [{ "op": "no_duplicate", "pointer": "/refunds" }]
}
}
]
}
Action kinds are http and noop. Use noop for a state-only check that
verifies without driving an action first. method defaults to POST and
timeoutMs defaults to 5000.
As with probes, literal headers are rejected in a suite file so credentials
stay out of version control - use headersFromEnv. Action URLs may not embed
username or password credentials, and are redacted in output. A non-2xx action
response is reported as an errored test rather than a failed assertion, so an
action that could not run is distinguishable from one whose result was wrong.
Action responses must be JSON, text, empty, or a HEAD response.
Exit codes: 0 when every test passed, 1 when any test failed or errored, and
2 when the suite file could not be read or parsed. See
examples/preman.agent-tests.example.json for a complete suite.
import { parseAgentTestSuite, runAgentTestSuite } from "preman-sdk";
const suite = parseAgentTestSuite(await readFile("preman.agent-tests.json", "utf8"));
const result = await runAgentTestSuite(suite);
import { PremanClient } from "preman-sdk";
const preman = new PremanClient({
apiKey: process.env.PREMAN_API_KEY,
apiUrl: "https://api.preman.live",
appUrl: "https://app.preman.live",
});
const endpoints = [
{
method: "POST" as const,
path: "/auth/login",
scope: "auth:login",
description: "Login with email and password.",
requestBodySchema: {
type: "object",
properties: {
email: { type: "string", format: "email" },
password: { type: "string" },
},
required: ["email", "password"],
},
},
];
const session = await preman.registerEndpoints({
upstreamBaseUrl: "https://api.company.com",
intent: "Auth endpoints",
endpoints,
});
console.log(session.dashboardUrl);
const mcp = await preman.deployMcp({
sessionId: session.sessionId,
name: "Auth MCP",
upstreamBaseUrl: "https://api.company.com",
endpoints,
});
console.log(mcp.hostedUrl);
console.log(mcp.installSnippet?.mcpJsonString);
Import docs or a remote MCP directly from TypeScript:
const docsMcp = await preman.importFromDocs({
docsUrl: "https://docs.company.com/api-reference",
name: "Company API MCP",
upstreamBaseUrl: "https://api.company.com",
maxEndpoints: 120,
});
const remoteMcp = await preman.importRemoteMcp({
mcpUrl: "https://mcp.company.com/mcp",
name: "Company MCP Proxy",
initialUpstreamSecret: process.env.COMPANY_MCP_TOKEN,
upstreamAuthStyle: { type: "header", name: "Authorization", prefix: "Bearer " },
});
console.log(docsMcp.hostedUrl);
console.log(remoteMcp.installSnippet?.mcpJsonString);
Start a local STDIO tunnel from TypeScript:
import { PremanClient, runLocalStdioTunnel } from "preman-sdk";
const preman = new PremanClient({ apiKey: process.env.PREMAN_API_KEY });
await runLocalStdioTunnel(preman, {
name: "Local Files MCP",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "."],
envNames: ["FILESYSTEM_ROOT"],
env: { FILESYSTEM_ROOT: process.env.FILESYSTEM_ROOT },
scopes: ["files:read"],
});
PreMan hosted MCPs use two URLs:
/h/{id}/mcp)You host the API and pass upstreamBaseUrl (CLI --upstream). PreMan proxies tool calls there.
upstreamMode: "preman")PreMan builds and runs your upstream container. Discover support first, then deploy without a tunnel:
import { PremanClient } from "preman-sdk";
import {
resolveUpstreamDeployPlan,
supportsPremanUpstreamHosting,
} from "preman-sdk/upstream-hosting";
const preman = new PremanClient();
const capabilities = await preman.getCapabilities();
if (supportsPremanUpstreamHosting(capabilities)) {
const plan = resolveUpstreamDeployPlan({
capabilities,
preferPremanHosting: true,
upstreamBuild: { dockerfile: "Dockerfile", healthPath: "/health" },
});
const deployed = await preman.deployMcp({
name: "Spotify MCP",
upstreamMode: plan.upstreamMode,
upstreamBuild: plan.upstreamBuild,
endpoints,
});
await preman.waitForUpstreamHosting({ mcpId: deployed.mcpId });
}
Agent discovery: import AGENT_UPSTREAM_HOSTING_GUIDE from preman-sdk/upstream-hosting, or run npx preman-sdk capabilities.
CLI:
npx preman-sdk capabilities
npx preman-sdk deploy --name "Spotify MCP" --file endpoints.json \
--upstream-mode preman --dockerfile Dockerfile --wait-upstream
npx preman-sdk upstream-hosting --mcp-id mcp_123 --wait
GET /capabilities returns upstream_hosting when the API supports PreMan-hosted upstreams. Older APIs return only external mode (SDK falls back safely).
PreMan consumer tokens are scoped to a hosted MCP. The hosted MCP runtime verifies the token before forwarding a tool call to your upstream API.
A token can include:
auth:login or orders:writeCalls outside the token's scope are denied by the hosted runtime and appear in the hosted workspace audit trail. Tokens can be listed, rotated, and revoked from the SDK, CLI, or hosted workspace.
preman token list --mcp-id mcp_123
preman token revoke --mcp-id mcp_123 --token-id token_123
preman token rotate --mcp-id mcp_123 --token-id token_123 --scopes auth:login --consumer-label cursor-agent
Generate endpoint manifests from OpenAPI or Postman, then register or deploy them.
preman import openapi --file openapi.json --out endpoints.json
preman import postman --file collection.json --register --upstream https://api.company.com
preman import openapi --file openapi.json --deploy --name "Public API MCP" --upstream https://api.company.com
For CI and repeatable deploys, put the upstream, endpoints, and scopes in a manifest:
{
"name": "Auth MCP",
"upstream": "https://api.company.com",
"intent": "Auth endpoints",
"endpoints": [
{ "method": "POST", "path": "/auth/login", "scope": "auth:login" }
],
"policies": [
{ "scope": "auth:login", "rateLimitRpm": 60, "ttlSeconds": 900 }
],
"deploy": {
"name": "Auth MCP",
"initialConsumerLabel": "default-consumer"
}
}
Preview before writing anything:
preman apply --file preman.config.json --dry-run
preman apply --file preman.config.json --deploy
Create TypeScript request/response types from your endpoint manifest:
preman typegen --file endpoints.json --out preman-endpoints.ts
Create typed wrappers from the actual hosted MCP catalog agents will call:
preman typegen --mcp-id mcp_123 --client --out preman-tools.ts
The hosted catalog typegen reads the stored tools/list schema, including nested
objects, arrays, enums, nullable fields, anyOf / oneOf, and
additionalProperties. Use --client when you want a thin typed wrapper around
your own callTool(name, args) implementation for tests or internal automations.
Pin the approved hosted MCP catalog to disk:
preman snapshot --mcp-id mcp_123 --out preman-catalog.snapshot.json
Then fail CI if production drifts from the approved catalog:
preman diff --approved preman-catalog.snapshot.json --mcp-id mcp_123
diff exits non-zero for removed tools, likely renames, broader input schemas,
or new write-capable tools (POST, PUT, PATCH, DELETE) unless you pass the
matching approval flag:
preman diff \
--approved preman-catalog.snapshot.json \
--mcp-id mcp_123 \
--allow-new-write-tools
GitHub Actions example:
name: MCP catalog drift
on:
pull_request:
push:
branches: [main]
jobs:
drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install -g preman-sdk
- run: preman diff --approved preman-catalog.snapshot.json --mcp-id ${{ vars.PREMAN_MCP_ID }}
env:
PREMAN_API_KEY: ${{ secrets.PREMAN_API_KEY }}
After minting a hosted MCP consumer token, generate or write client config:
preman install-snippet \
--target cursor \
--server-name auth-mcp \
--url https://api.preman.live/h/mcp_123/mcp \
--token-env PREMAN_CONSUMER_TOKEN
preman install-snippet \
--target cursor \
--server-name auth-mcp \
--url https://api.preman.live/h/mcp_123/mcp \
--token-env PREMAN_CONSUMER_TOKEN \
--write
The SDK also exports hostedMcpJson(), installCommand(), and writeMcpInstall() for product flows that need to generate Cursor, Claude, or VS Code instructions.
PremanClient supports request timeouts, retries, idempotency keys, and hooks for logging.
const preman = new PremanClient({
apiKey: process.env.PREMAN_API_KEY,
timeoutMs: 15_000,
retry: { retries: 2, initialDelayMs: 250 },
hooks: {
onRequest: (event) => console.log("preman request", event.requestId, event.path),
onResponse: (event) => console.log("preman response", event.status, event.durationMs),
onError: (event) => console.error("preman error", event.status, event.error),
},
});
await preman.deployMcp({
name: "Auth MCP",
upstreamBaseUrl: "https://api.company.com",
endpoints,
request: { idempotencyKey: crypto.randomUUID() },
});
For write operations that may be retried, pass an idempotency key. The client includes X-Request-Id on every request so API logs, CI logs, and hosted audit events can be correlated.
When runtime responses report a different commit from the selected candidate, the SDK can identify every commit actually serving traffic. More than one entry means the checked environment is serving a rolling or split deployment.
import { getGithubActiveRuntimeCommits, PremanClient } from "preman-sdk";
const preman = new PremanClient({ apiKey: process.env.PREMAN_API_KEY });
const { runs } = await preman.listGithubSimulations({
integrationId: "github-integration-id",
limit: 1,
});
for (const active of getGithubActiveRuntimeCommits(runs[0].summary)) {
console.log(active.commitSha, active.responseCount);
}
Hand a completed API-contract simulation to the coding agent connected to that repository. The request contains no repair prompt: PreMan builds the task from the stored simulation evidence and verifies the repository binding.
const handoff = await preman.handoffGithubSimulation({
integrationId: "github-integration-id",
runId: "completed-simulation-run-id",
workspaceId: "workspace-id", // optional
request: { idempotencyKey: crypto.randomUUID() },
});
console.log(handoff.fixTask, handoff.dispatch);
console.log(handoff.conversation?.id, handoff.conversation?.messages);
console.log(handoff.conversation?.taskInProgress);
The returned conversation is the persisted workbench chat for the repair. It
appears in the dashboard's Recent list and can be continued in either the
agent side panel or the full chat view. Retrying an active handoff returns the
same task and conversation rather than creating another chat. Auto-PR may open
a review pull request, but the handoff never merges or deploys it.
While the repair is running, getFixTask() exposes up to six short activity
lines from dispatch_result.progress.activity as a camel-cased
dispatchActivity view. The typed wire shape remains available through
dispatchProgress.activity with elapsed_ms intact:
const task = await preman.getFixTask(handoff.fixTask.id);
for (const item of task.dispatchActivity ?? []) {
console.log(item.state, item.label, item.elapsedMs);
}
console.log(task.dispatchProgress?.activity?.[0]?.elapsed_ms);
Each item has an id, a safe display label, an active or complete state,
and optional elapsedMs. The dashboard may place a temporary, collapsible
excerpt beneath a status update when the selected coding agent emits commentary
through its visible-output channel. For Codex, that source is its visible
commentary/transcript event, not hidden reasoning. An admitted excerpt is newly
shared into the user’s PreMan workspace; it should not be described as text the
user had already seen in PreMan.
Admission is fail-closed. A conservative safe-commentary allowlist accepts only short, status-like excerpts. Arbitrary prose is rejected, while reasoning events, prompt echoes, code, raw commands and output, absolute paths, and recognized credential patterns are excluded. Semantic activity such as “Running tests” or “Editing a file” remains the fallback when no excerpt is admitted. This narrow filter is a data-minimization boundary, not permission to put secrets into agent commentary.
If a failed step has no specific admitted detail, the UI suppresses the generic
no-detail failure note instead of inventing an excerpt. A terminal record is
presented as completed rather than failed only when the agent exited with code
0, returned a summary, and returned no error. The wire shape is unchanged:
consumers should continue treating label as display-ready status text. The SDK
retains the original dispatchResult for older integrations and returns an empty
activity list for legacy scalar progress.
Avoid putting upstream or consumer secrets in shell history. Use environment-backed secret providers:
export API_BEARER_TOKEN=prod_token
preman deploy \
--name "Auth MCP" \
--file endpoints.json \
--upstream https://api.company.com \
--upstream-secret-env API_BEARER_TOKEN \
--upstream-secret-type bearer
Programmatic helpers:
import { resolveSecret, secretFromEnv } from "preman-sdk";
const upstreamSecret = await resolveSecret(secretFromEnv("API_BEARER_TOKEN"));
Use the bundled action to register endpoints from CI:
name: Register endpoints
on: [push]
jobs:
preman:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: PreMan-Inc/PreMan-Sdk@main
with:
api-key: ${{ secrets.PREMAN_API_KEY }}
endpoint-file: endpoints.json
upstream: https://api.company.com
npx preman-sdk init --api-key pm_live_...
npx preman-sdk status
npx preman-sdk register --file endpoints.json --upstream https://api.company.com
npx preman-sdk deploy --name "Auth MCP" --file endpoints.json --upstream https://api.company.com
npx preman-sdk tunnel --name "Local Files MCP" --command npx --arg -y --arg @modelcontextprotocol/server-filesystem --arg .
npx preman-sdk token --mcp-id mcp_123 --consumer-label cursor-agent --scopes auth:login --rate-limit-rpm 60
npx preman-sdk token list --mcp-id mcp_123
npx preman-sdk token revoke --mcp-id mcp_123 --token-id token_123
npx preman-sdk import openapi --file openapi.json --out endpoints.json
npx preman-sdk apply --file preman.config.json --dry-run
npx preman-sdk snapshot --mcp-id mcp_123 --out preman-catalog.snapshot.json
npx preman-sdk diff --approved preman-catalog.snapshot.json --mcp-id mcp_123
npx preman-sdk assert --file preman.assert.json
npx preman-sdk typegen --file endpoints.json --out preman-endpoints.ts
npx preman-sdk typegen --mcp-id mcp_123 --client --out preman-tools.ts
--upstream Means--upstream is the base URL for your real backend API:
--upstream + endpoint path = full URL PreMan calls
Examples:
https://api.company.com + /auth/login = https://api.company.com/auth/login
https://staging.company.com/api + /orders = https://staging.company.com/api/orders
Do not use https://preman.live unless your actual API is hosted there. For local APIs, use a public tunnel before deploying a hosted MCP.
The CLI stores local config at:
~/.preman/config.json
Environment variables override local config:
PREMAN_API_KEY=pm_live_your_key
PREMAN_API_URL=https://api.preman.live
PREMAN_APP_URL=https://app.preman.live
Self-healing endpoint workflow:
listEndpointHealth() -> lists project-scoped endpoint health aggregates and observationsgetEndpointHealthMetrics() -> reads health totals, latency percentiles, and sparkline bucketsgetEndpointDependencies() -> reads evidence-backed directed dependencies for blast-radius analysisconfigureEndpointProbe() / listEndpointProbes() -> continuously exercise saved API endpointslistEndpointProbeResults() -> inspect status, latency, and failure detailscreateHealingRule() -> trigger incidents and native autofix after consecutive failures or an error-rate thresholdlistEndpointIncidents() -> inspect fired and resolved endpoint incidentslistFixTasks() / getFixTask() -> follow reproducible repair packagesstartSelfHealing() / waitForSelfHealing() -> run repair, validation, branch push, and PR creationresolveFixTask() -> close a completed repair taskEndpoint discovery and testing:
registerEndpoints() -> creates or updates a playground sessionfromOpenApi() / fromPostmanCollection() -> converts API docs into endpoint definitionsgenerateEndpointTypes() -> generates TypeScript types from endpoint schemasSecondary hosted MCP and agent-security capabilities:
deployMcp() -> creates a hosted MCP from endpoint definitionscreateToken() -> mints a scoped hosted MCP consumer tokenlistTokens() / revokeToken() / rotateToken() -> manage hosted MCP token lifecycleverifyToken() / verifyBearerToken() -> verifies hosted MCP consumer tokens and scopesaudit() -> writes custom non-MCP agent events into PreMan audit logspreviewManifest() / readManifest() -> validate policy-as-code manifests and dry runsgenerateHostedMcpToolTypes() -> generate TypeScript types from hosted MCP tool catalogscreateCatalogSnapshot() / diffCatalogSnapshots() -> pin approved tool catalogs and detect CI drifthostedMcpJson() / writeMcpInstall() -> generate or write MCP install snippetsresolveSecret() / secretFromEnv() -> keep secrets out of command text and configexamples/frameworkspreman CLI -> monitoring, healing, setup, register, import, deploy, tokens, and type generationHosted MCP calls are already authenticated, scoped, and audited by PreMan.
npm install
npm test
npm run build
Live staging checks are opt-in so unit tests stay offline and fast:
PREMAN_API_KEY=pm_live_... npm run integration
Optional integration fixtures:
PREMAN_API_URL=https://api.preman.live
PREMAN_TEST_OPENAPI_URL=https://petstore3.swagger.io/api/v3/openapi.json
PREMAN_TEST_REMOTE_MCP_URL=https://mcp.example.com/mcp
Use of PreMan is governed by our Terms of Service. We process account, workspace, and runtime data as described in our Privacy Policy.
MIT
Please log in to share your review and rating for this MCP.
Explore related MCPs that share similar capabilities and solve comparable challenges
by modelcontextprotocol
A Model Context Protocol server for Git repository interaction and automation.
by zed-industries
A high‑performance, multiplayer code editor designed for speed and collaboration.
by modelcontextprotocol
Model Context Protocol Servers
by modelcontextprotocol
A Model Context Protocol server that provides time and timezone conversion capabilities.
by cline
An autonomous coding assistant that can create and edit files, execute terminal commands, and interact with a browser directly from your IDE, operating step‑by‑step with explicit user permission.
by upstash
Provides up-to-date, version‑specific library documentation and code examples directly inside LLM prompts, eliminating outdated information and hallucinated APIs.
by daytonaio
Provides a secure, elastic infrastructure that creates isolated sandboxes for running AI‑generated code with sub‑90 ms startup, unlimited persistence, and OCI/Docker compatibility.
by continuedev
Enables faster shipping of code by integrating continuous AI agents across IDEs, terminals, and CI pipelines, offering chat, edit, autocomplete, and customizable agent workflows.
by github
Connects AI tools directly to GitHub, enabling natural‑language interactions for repository browsing, issue and pull‑request management, CI/CD monitoring, code‑security analysis, and team collaboration.
{
"mcpServers": {
"preman-sdk-tunnel": {
"command": "npx",
"args": [
"preman-sdk",
"tunnel",
"--name",
"Local Files MCP",
"--command",
"npx",
"--arg",
"-y",
"--arg",
"@modelcontextprotocol/server-filesystem",
"--arg",
"."
],
"env": {
"PREMAN_API_KEY": "<YOUR_API_KEY>"
}
}
}
}claude mcp add preman-sdk-tunnel npx preman-sdk tunnel --name Local Files MCP --command npx --arg -y --arg @modelcontextprotocol/server-filesystem --arg .