NDNCI Docs
API v1

Connect with MCP

Give an MCP client explicit access to the NDNCI workspaces and operations you choose.

NDNCI exposes its public MCP resource at https://api.ndnci.com/mcp using Streamable HTTP. It shares the same authorized operations, monetary budgets and usage points as REST. A Tool call made through MCP appears with the mcp execution origin in jobs, queues and credit transactions.

Choose an access method

For a server or a client that supports authorization headers, create an access key in Account → API, enable the MCP transport and select its scopes and workspaces. Send the key as Authorization: Bearer <key> when connecting to the public MCP resource. A key may enable REST, MCP, or both; transport access is checked separately from its operation scopes.

For an interactive MCP client, use its OAuth connection flow. Sign in to NDNCI, review the client and the requested permissions, and explicitly select authorized workspaces before granting access. OAuth access tokens are bound to the public MCP resource and carry the approved scopes. They do not grant a website session to the client.

Keep keys and refresh tokens in the client's secure credential storage. Never put a credential in the MCP URL or a shared prompt.

Connect a script

Use your client's native Streamable HTTP connector or the current official TypeScript client. The client handles protocol discovery and per-request metadata. Public MCP uses protocol revision 2026-07-28; earlier revisions receive an unsupported-protocol response.

Install @modelcontextprotocol/client, then keep the token in an environment variable or secret store:

import {
  Client,
  StreamableHTTPClientTransport,
} from "@modelcontextprotocol/client";

const token = process.env.NDNCI_AUTOMATION_TOKEN;
const workspaceId = process.env.NDNCI_WORKSPACE;
if (!token || !workspaceId) throw new Error("Configure a token and workspace.");

const client = new Client(
  { name: "workspace-automation", version: "1.0.0" },
  { versionNegotiation: { mode: "auto" } },
);
await client.connect(
  new StreamableHTTPClientTransport(new URL("https://api.ndnci.com/mcp"), {
    authProvider: { token: async () => token },
  }),
);

try {
  const result = await client.callTool({
    name: "ndnci_tools_run",
    arguments: {
      workspaceId,
      idempotencyKey: crypto.randomUUID(),
      operationId: "link.preview",
      input: { url: "https://example.org" },
    },
  });
  console.log(result);
} finally {
  await client.close();
}

The public MCP resource does not offer a persistent subscriptions listener. Follow business job progress with the Pro REST event stream, webhooks, or job reads.

Select the workspace for each Tool call

Each public Tool input includes a workspaceId. Select one of the workspaces explicitly included in the access grant. Permissions are checked against current organization membership; an owner or administrator losing that role cannot continue using the old grant.

Tool inputs follow the REST reference. To start work, use the operation identifier and input returned by Tool discovery. Upload media to the selected workspace first and pass its media identifiers.

Accounting and recovery

MCP is available with Free, Starter and Pro. The workspace's plan determines usage points, key limits and queue capacity. Pro additionally enables the REST job event stream; all plans can read jobs and use webhooks.

A repeated paid operation needs the same idempotency identifier to recover its original result. A changed input with the same identifier is rejected. An estimate gives the maximum reservation and usage-point cost before execution; it does not start the operation.

Use job status, webhooks, and error handling to recover from interrupted connections. The client must ask for new consent if it needs additional scopes or workspaces.

MCP ToolOperationScope
ndnci_workspaces_listworkspaces.listworkspaces:read
ndnci_tools_listtools.listtools:read
ndnci_tools_estimatetools.estimatetools:run
ndnci_tools_runtools.runtools:run
ndnci_jobs_listjobs.listjobs:read
ndnci_jobs_getjobs.getjobs:read
ndnci_jobs_outputjobs.outputjobs:read
ndnci_jobs_canceljobs.canceljobs:write
ndnci_jobs_retryjobs.retryjobs:write
ndnci_queue_getqueue.getqueue:read
ndnci_balance_getbalance.getbilling:read
ndnci_transactions_listtransactions.listbilling:read
ndnci_media_listmedia.listmedia:read
ndnci_media_getmedia.getmedia:read
ndnci_media_uploadmedia.uploadmedia:write
ndnci_media_downloadmedia.downloadmedia:read
ndnci_usage_getusage.getusage:read
ndnci_events_listevents.listevents:read
ndnci_webhooks_listwebhooks.listwebhooks:read
ndnci_webhooks_createwebhooks.createwebhooks:write
ndnci_webhooks_updatewebhooks.updatewebhooks:write
ndnci_webhooks_revokewebhooks.revokewebhooks:write
ndnci_webhooks_rotatewebhooks.rotatewebhooks:write
ndnci_webhooks_deliverieswebhooks.deliverieswebhooks:read
ndnci_webhooks_replaywebhooks.replaywebhooks:write

For complete result retrieval, call ndnci_jobs_output with workspaceId, jobId and the previous page's optional cursor. Its bounded JSON fragments follow the same reconstruction and integrity checks as REST.

On this page