Skip to main content
Was this helpful?

Agent API

AI Agents and MCP

Create agents, scope their permissions, issue agent keys, and call the MCP runtime

PrimeCal exposes a dedicated agent-management surface under /api/agents and a separate MCP runtime under /api/mcp. The management routes use user auth; the runtime uses agent keys only.

JWT for managementAgent key for MCPScoped permissionsRemote execution

Source

  • Agent management controller: backend-nestjs/src/agents/agents.controller.ts
  • MCP controller: backend-nestjs/src/agents/agent-mcp.controller.ts
  • MCP stream controller: backend-nestjs/src/agents/agent-mcp-stream.controller.ts
  • DTOs: backend-nestjs/src/agents/dto/agent.dto.ts, backend-nestjs/src/agents/dto/agent-stream.dto.ts
  • Action registry: backend-nestjs/src/agents/agent-actions.registry.ts
  • Agent auth guard: backend-nestjs/src/agents/guards/agent-api-key.guard.ts
  • Status enum: backend-nestjs/src/entities/agent-profile.entity.ts

Authentication and Permissions

SurfaceAuth modelNotes
/api/agents/*JWT or user API keyCurrent user manages their own agents
/api/mcp/*Agent key onlyBearer tokens are explicitly rejected

Accepted agent-key headers:

  • x-agent-key
  • x-agent-token
  • Authorization: Agent <token>

Endpoint Reference

Agent Management

MethodPathPurposeRequest or queryAuthSource
GET/api/agentsList current-user agents.NoneJWT or user API keyagents/agents.controller.ts
POST/api/agentsCreate an agent.Body: name,descriptionJWT or user API keyagents/agents.controller.ts
GET/api/agents/catalogGet the agent action catalog plus scoping resources.NoneJWT or user API keyagents/agents.controller.ts
GET/api/agents/:idGet one agent.Path: idJWT or user API keyagents/agents.controller.ts
PUT/api/agents/:idUpdate name, description, or status.Path: id, body: name,description,statusJWT or user API keyagents/agents.controller.ts
DELETE/api/agents/:idDisable an agent.Path: idJWT or user API keyagents/agents.controller.ts
PUT/api/agents/:id/permissionsReplace the agent permission set.Path: id, body: permissions[]JWT or user API keyagents/agents.controller.ts
GET/api/agents/:id/keysList keys for one agent.Path: idJWT or user API keyagents/agents.controller.ts
POST/api/agents/:id/keysCreate an agent key.Path: id, body: labelJWT or user API keyagents/agents.controller.ts
DELETE/api/agents/:id/keys/:keyIdRevoke an agent key.Path: id,keyIdJWT or user API keyagents/agents.controller.ts

MCP Runtime

MethodPathPurposeRequest or queryAuthSource
GET/api/mcp/metadataReturn agent and owner metadata for the issued key.NoneAgent keyagents/agent-mcp.controller.ts
GET/api/mcp/actionsList actions allowed for the authenticated agent.NoneAgent keyagents/agent-mcp.controller.ts
POST/api/mcp/executeExecute one agent action.Body: action,parametersAgent keyagents/agent-mcp.controller.ts
ALL/api/mcp/streamHTTP streaming transport for MCP clients.Body: payloadAgent keyagents/agent-mcp-stream.controller.ts

Request Shapes

Agent definition

CreateAgentDto and UpdateAgentDto in backend-nestjs/src/agents/dto/agent.dto.ts

  • name: required on create, max 80 chars
  • description: optional, max 255 chars
  • status: update-only enum active|disabled

Permissions

UpdateAgentPermissionsDto

  • permissions: required array
  • permissions[].actionKey: required action enum value from the registry
  • permissions[].scope: optional object

Current registry keys from backend-nestjs/src/agents/agent-actions.registry.ts:

  • calendar.list
  • calendar.events.read
  • calendar.events.create
  • calendar.events.update
  • calendar.events.delete
  • automation.rules.list
  • automation.rules.trigger
  • user.profile.read
  • tasks.list
  • tasks.create
  • tasks.update
  • tasks.delete
  • task-labels.list
  • task-labels.create
  • task-labels.update
  • task-labels.delete

Keys and execution

  • CreateAgentKeyDto.label: required, max 80 chars
  • ExecuteAgentActionDto.action: required action key
  • ExecuteAgentActionDto.parameters: optional object
  • AgentStreamPayloadDto.payload: request wrapper used by /api/mcp/stream

Catalog and Scope Model

GET /api/agents/catalog returns:

  • actions: the action catalog
  • resources.calendars: current-user calendars for calendar-scoped permissions
  • resources.automationRules: current-user automation rules for automation-scoped permissions

That makes the catalog route the source of truth for permission editors.

Example Calls

Create an agent

curl -X POST "$PRIMECAL_API/api/agents" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Family Planner",
"description": "Reads family calendars and creates tasks"
}'

Replace agent permissions

curl -X PUT "$PRIMECAL_API/api/agents/9/permissions" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"permissions": [
{ "actionKey": "calendar.list" },
{
"actionKey": "calendar.events.create",
"scope": { "calendarIds": [5, 7] }
},
{ "actionKey": "tasks.create" }
]
}'

Call the MCP runtime

curl "$PRIMECAL_API/api/mcp/metadata" \
-H "Authorization: Agent $AGENT_KEY"
curl -X POST "$PRIMECAL_API/api/mcp/execute" \
-H "Authorization: Agent $AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "calendar.events.create",
"parameters": {
"calendarId": 5,
"title": "Parent-teacher meeting",
"startDate": "2026-04-02",
"startTime": "16:00"
}
}'

Response and Behavior Notes

  • The catalog response is enriched with the user's actual calendars and automation rules.
  • DELETE /api/agents/:id disables the agent and returns { success: true }.
  • POST /api/agents/:id/keys returns a plaintext key only at creation time.
  • GET /api/mcp/metadata returns agent, owner, and protocol blocks.

Best Practices

  • Keep agent scopes narrow. Grant only the actions and resource scopes the agent actually needs.
  • Treat agent keys like secrets. They are separate from user JWTs and should never be embedded in browser code.
  • Use GET /api/agents/catalog before rendering a permission editor so you do not drift from the live action registry.
  • Prefer /api/mcp/metadata as the first smoke test when wiring an external MCP client.
  • Disable agents when they are no longer needed instead of leaving active keys in place.