Skip to Content

API

The Newnadoon API is the runtime surface your frontend, internal tools, and services use to run agents and stream execution events.

This page explains:

  1. how to expose the API in a Next.js App Router app
  2. what each endpoint does
  3. request and response examples
  4. how to run a standalone production API server

Two ways to expose the API

Option 1: Next.js App Router integration

Use this when your frontend app and agent runtime live in the same Next.js project.

Create:

app/api/newnadoon/[...path]/route.ts

import { createNewnadoonApiRoute } from '@newnadoon/ai-framework/next/app-router' export const runtime = 'nodejs' export const { GET, POST } = createNewnadoonApiRoute()

This gives you runtime endpoints under /api/newnadoon/*.

Option 2: Standalone production API server

Use this when you want a dedicated backend process.

Terminal
$ npx newnadoon-api

Optional flags:

npx newnadoon-api --port 8080 --base-path /api --project-dir ./

By default, this serves endpoints under /api/* and includes health + MCP routes.

Required project config

The API loads agents from newnadoon.json. If this file is missing or invalid, agent endpoints cannot run.

Minimal example:

{ "agents": { "general-department-agent": { "name": "General Department Agent", "path": "./agent.ts" } } }

Core runtime endpoints

The same runtime concepts are used in both integration modes.

When using the Next.js helper, the base path is /api/newnadoon. When using newnadoon-api, the default base path is /api.

POST /run

Starts an agent execution.

Next.js path:

  • /api/newnadoon/run

Standalone server path:

  • /api/run

Example request:

{ "agentId": "general-department-agent", "initialState": { "task": "Summarize today's shipping issues" }, "checkpoint": true }

Example response:

{ "success": true, "runId": "run-1742451111-abc123", "workflowId": "workflow-1742451111-def456", "message": "Agent execution started" }

GET /events (SSE)

Streams runtime events using Server-Sent Events (SSE).

Next.js path:

  • /api/newnadoon/events

Standalone server path:

  • /api/events

Optional query params:

  • runId
  • workflowId

Example browser client:

const source = new EventSource('/api/newnadoon/events?runId=run-123') source.onmessage = (event) => { const data = JSON.parse(event.data) console.log(data.type, data) }

You will receive events such as connection, token streaming, step/run updates, and final completion events.

GET /agents

Returns registered agents loaded from newnadoon.json.

Next.js path:

  • /api/newnadoon/agents

Standalone server path:

  • /api/agents

Example response:

{ "agents": [ { "id": "general-department-agent", "name": "General Department Agent", "description": "", "path": "./agent.ts" } ], "defaultAgent": "general-department-agent" }

GET /graph

Returns workflow/agent structure for visualization.

Next.js path:

  • /api/newnadoon/graph?agentId=general-department-agent

Standalone server path:

  • /api/graph?agentId=general-department-agent

Use this for topology views, step maps, and runtime UI graph rendering.

Additional standalone server endpoints

When running npx newnadoon-api, you also get:

GET /

Landing page for browsers (@newnadoon/[email protected]+). HTML GET / serves the project’s public/index.html when that file exists; otherwise the framework default page with MCP client snippets (Cursor, Claude Code, Codex, GitHub Copilot, Gemini CLI, Grok). Other files in public/ are served at / (for example public/favicon.ico). JSON Accept: application/json still returns the framework payload. This process is the API + MCP server, not a product UI. Any MCP client should use POST /api/mcp.

GET /health

Health status for readiness/liveness checks.

MCP endpoints

  • GET /api/mcp (SSE session setup; default --base-path /api)
  • POST /api/mcp (Streamable HTTP JSON-RPC; Cursor, Claude Code, Codex, VS Code, Windsurf, and other MCP clients) — shipped in @newnadoon/[email protected]. /api/health is reliable in 1.0.23 (1.0.22 could 503 on a normal heap).
  • POST /api/mcp/messages?sessionId=... (legacy SSE JSON-RPC messages)

The SSE endpoint event data is the message path as a raw string (/api/mcp/messages?sessionId=...), not JSON. Cursor and other MCP clients treat that string as a URL. A JSON payload such as {"messageEndpoint":"..."} is resolved as a relative path and returns Cannot POST /api/{...}.

These endpoints allow external MCP clients to discover and call registered agents as tools. tools/list also includes each agent’s exported agentTools / tools as {agentId}.{toolName} (for example kanban-workitem-agent.create_work_item). tools/call runs the agent when name is an agent id, or executes that tool directly when name is a dotted {agentId}.{toolName}.

Generic agents work with no headers. There is no KANBAN_ORGANIZATION_ID fallback. If a client sends Authorization: Bearer <org-api-key>, the server validates it against KANBAN_API_URL/api/integrations/api-keys/validate and injects that key’s organizationId. Client-supplied organizationId arguments are stripped. Without a valid key, Kanban tools fail rather than acting on a default org. Set MCP_REQUIRE_API_KEY=true when you want every tools/call (including generic agents) to require a key.

Connect an MCP client

The running API (GET /) shows the same snippets with the live MCP URL filled in. Replace ndk_... with an org API key when the agent talks to Kanban. Generic agents can omit the header. Stdio-only clients: npx -y mcp-remote http://localhost:8080/api/mcp.

Cursor — .cursor/mcp.json

{ "mcpServers": { "newnadoon": { "url": "http://localhost:8080/api/mcp", "headers": { "Authorization": "Bearer ndk_..." } } } }

Claude Code — .mcp.json (type is required)

{ "mcpServers": { "newnadoon": { "type": "http", "url": "http://localhost:8080/api/mcp", "headers": { "Authorization": "Bearer ndk_..." } } } }
claude mcp add --transport http --scope project newnadoon http://localhost:8080/api/mcp --header "Authorization: Bearer ndk_..."

Codex — ~/.codex/config.toml

[mcp_servers.newnadoon] url = "http://localhost:8080/api/mcp" bearer_token_env_var = "NEWNADOON_MCP_KEY"

GitHub Copilot — .vscode/mcp.json (servers, not mcpServers)

{ "servers": { "newnadoon": { "type": "http", "url": "http://localhost:8080/api/mcp", "headers": { "Authorization": "Bearer ndk_..." } } } }

Gemini CLI — ~/.gemini/settings.json

{ "mcpServers": { "newnadoon": { "httpUrl": "http://localhost:8080/api/mcp", "headers": { "Authorization": "Bearer ndk_..." } } } }

Grok — ~/.grok/config.toml

[mcp_servers.newnadoon] url = "http://localhost:8080/api/mcp" headers = { Authorization = "Bearer ${NEWNADOON_MCP_KEY}" }

Start the server with npx newnadoon-api --port 8080. After connect, the client should list the agent plus each exported CRUD tool.

Validate without an IDE:

npx newnadoon-mcp --baseUrl http://localhost:8080 --tool kanban-workitem-agent --input {"task":"list work items"}

Typical frontend flow

In a browser app using useNewnadoonAgent():

  1. call /run to start execution
  2. subscribe to /events for live updates
  3. render streamed tokens while running
  4. read final state on completion

This is the same flow used by the prebuilt chat hooks and components.

Common errors

If API calls fail, check:

  • newnadoon.json exists and has a valid agents object
  • agentId in requests matches a registered agent key
  • route file is exactly at app/api/newnadoon/[...path]/route.ts (for App Router mode)
  • Node runtime is enabled in the route (export const runtime = 'nodejs')
  • your frontend runUrl and eventsUrl match the deployed base path

Next step

Use the frontend integration guide to connect these endpoints to UI patterns: Bring agent to Frontend apps.