Tools API
Discover and execute organization tools from one unified registry.
Every organization tool is declared once in convex/tools/definitions/ and exposed through three surfaces: this REST API, the MCP server, and the pnpm tools CLI. Adding a tool to the registry publishes it everywhere at once.
Endpoints
GET /api/v1/tools
GET /api/v1/tools/:name
POST /api/v1/tools/:name| Endpoint | Description |
|---|---|
GET /api/v1/tools | List every tool with its JSON Schema |
GET /api/v1/tools/:name | JSON Schema of a single tool |
POST /api/v1/tools/:name | Execute a tool with a JSON body as its input |
Authentication
Create an organization API key from the organization settings page:
/orgs/{orgSlug}/settings/api-keysSend it with x-api-key or as a bearer token:
x-api-key: YOUR_API_KEY
Authorization: Bearer YOUR_API_KEYThe key resolves the organization, so no organization id is ever passed in a tool input.
An OAuth access token issued to an MCP client is sent the same way, as a bearer
token. API keys are recognized by their nsk_ prefix, everything else is
verified as an OAuth token, so both credentials reach the same handlers.
Available tools
| Tool | Category | Access | Input | Returns |
|---|---|---|---|---|
get_organization | organization | read | none | Organization id, name, slug |
list_members | members | read | { cursor?, limit? } | { members, count, nextCursor, hasMore } |
get_member | members | read | { memberId } | One member |
get_subscription | billing | read | none | Plan, status, seats and plan limits |
Discovery response
GET /api/v1/tools returns a JSON Schema per tool, ready to feed an LLM or a client generator:
{
"total": 4,
"tools": [
{
"name": "get_member",
"description": "Get a single member of the organization by member id.",
"category": "members",
"access": "read",
"inputSchema": {
"type": "object",
"properties": {
"memberId": { "type": "string", "minLength": 1 }
},
"required": ["memberId"]
},
"endpoint": "/api/v1/tools/get_member",
"method": "POST",
"route": { "method": "GET", "path": "/api/v1/members/:memberId" }
}
]
}route is the tool's REST alias, or null when it only answers on /api/v1/tools/<name>. Both paths run the same tool; the alias returns the payload without the data envelope. See Unified Tools for how to declare one.
Execution response
Successful executions return the tool payload under data:
{
"data": {
"members": [{ "id": "mem_123", "role": "owner" }],
"count": 1,
"nextCursor": null,
"hasMore": false
}
}CLI
export NOWSTACK_API_KEY="YOUR_API_KEY"pnpm tools list