MCP Servers
Create and manage Model Context Protocol (MCP) servers.
MCP Servers
MCP servers expose workspace integrations as tools for AI agents via the Model Context Protocol. New servers use MCP OAuth by default, so each MCP client signs in as the actual end user and receives a token scoped to the server, workspace, and end user.
Bearer-enabled MCP servers also support API-created mcp_ bearer tokens scoped to one end user. Use these when you provision MCP clients for known users and the client cannot complete OAuth. Static bearer tokens are still available for service-style clients, but they are shared server credentials and should not be used when each client needs its own end-user identity.
Servers operate in two modes:
- TOOLS — each integration action is exposed as an individual tool
- CODE — meta-tools let AI agents write code to orchestrate multiple actions
List MCP Servers
/api/v1/mcp/serversList all MCP servers in your organization.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
workspaceId | string (uuid) | No | Filter servers to one workspace |
limit | integer | No | Number of servers to return, default 50, max 100 |
offset | integer | No | Number of servers to skip for pagination |
includeSuspended | boolean | No | Include suspended servers. Defaults to false |
Response
{
"servers": [
{
"id": "abc123def456",
"orgId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Sales Tools",
"description": "CRM and email integrations",
"mode": "TOOLS",
"authMode": "oauth",
"endUserAccess": "restricted",
"auth": {
"oauthEnabled": true,
"bearerEnabled": false,
"staticBearerEnabled": false,
"endUserBearerTokensEnabled": false,
"accessTokensEnabled": false
},
"endUserId": null,
"createdBy": "user123",
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2025-01-15T10:30:00.000Z",
"mcpEndpoint": "https://api.weavz.io/mcp/srv_abc123def456"
}
],
"total": 1
}Example
curl https://api.weavz.io/api/v1/mcp/servers \
-H "Authorization: Bearer wvz_your_api_key"Create MCP Server
/api/v1/mcp/serversCreate a new MCP server. The response always includes mcpEndpoint. It includes bearerToken only when authMode enables static bearer auth and the workspace can safely use a shared static token. End-user bearer tokens are created separately with the bearer-token endpoint.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Server name |
description | string | No | Server description |
workspaceId | string (uuid) | Yes | Associate with a workspace |
mode | string | No | Server mode: TOOLS or CODE (default: TOOLS) |
settings | object | No | Server settings. For CODE servers, set settings.codeMode.approvalWaitSeconds from 0 to 60. |
authMode | string | No | oauth, bearer, or oauth_and_bearer (default: oauth) |
endUserAccess | string | No | restricted or open (default: restricted). Controls who can complete MCP OAuth |
createdBy | string | No | Optional customer attribution label for audit and setup surfaces |
endUserId | string | No | The end user's externalId. Connections resolve to this user's accounts. |
endUserAccess controls MCP OAuth sign-in:
restricted— only pre-existing workspace end users can authorize. Weavz matches the signed-in user by linked account or email and links the record when needed.open— any signed-in user can authorize this server; Weavz creates or links their workspace end-user record during OAuth.
authMode: "bearer" and authMode: "oauth_and_bearer" allow API-created end-user bearer tokens. A shared static bearer token is returned only when the workspace does not require strict per-user resolution, or when the MCP server itself is scoped to one endUserId.
For Code Mode Human Gates, settings.codeMode.approvalWaitSeconds controls how long Weavz keeps an approvalId continuation call open while approval is still pending. The default is 0, which returns approval_pending immediately.
Response (201)
{
"server": {
"id": "abc123def456",
"orgId": "550e8400-e29b-41d4-a716-446655440000",
"name": "AI Agent Workspace",
"description": "Agent tools and approvals",
"mode": "CODE",
"settings": {
"codeMode": {
"approvalWaitSeconds": 30
}
},
"authMode": "oauth",
"endUserAccess": "restricted",
"auth": {
"oauthEnabled": true,
"bearerEnabled": false,
"staticBearerEnabled": false,
"endUserBearerTokensEnabled": false,
"accessTokensEnabled": false
},
"endUserId": null,
"createdBy": "user123",
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2025-01-15T10:30:00.000Z",
"mcpEndpoint": "https://api.weavz.io/mcp/srv_abc123def456"
},
"mcpEndpoint": "https://api.weavz.io/mcp/srv_abc123def456"
}Example
curl -X POST https://api.weavz.io/api/v1/mcp/servers \
-H "Authorization: Bearer wvz_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "AI Agent Workspace",
"description": "Agent tools and approvals",
"workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"mode": "CODE",
"settings": { "codeMode": { "approvalWaitSeconds": 30 } },
"authMode": "oauth",
"endUserAccess": "restricted"
}'Errors
| Status | Code | Description |
|---|---|---|
400 | VALIDATION_ERROR | Missing server name |
403 | QUOTA_EXCEEDED | MCP server limit reached |
404 | END_USER_NOT_FOUND | endUserId was provided but no matching end user exists in the workspace |
Get MCP Server
/api/v1/mcp/servers/:idGet server details including its configured tools.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
Response
{
"server": {
"id": "abc123def456",
"orgId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Sales Tools",
"mode": "TOOLS",
"endUserId": null,
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2025-01-15T10:30:00.000Z",
"mcpEndpoint": "https://api.weavz.io/mcp/srv_abc123def456"
},
"tools": [
{
"id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"mcpServerId": "abc123def456",
"integrationName": "slack",
"integrationAlias": "slack",
"actionName": "send_channel_message",
"toolType": "ACTION",
"connectionId": "c1d2e3f4-5678-90ab-cdef-1234567890ab",
"displayName": null,
"description": null,
"inputDefaults": null,
"sortOrder": 0
}
]
}Example
curl https://api.weavz.io/api/v1/mcp/servers/abc123def456 \
-H "Authorization: Bearer wvz_your_api_key"Errors
| Status | Code | Description |
|---|---|---|
404 | NOT_FOUND | MCP server not found |
Update MCP Server
/api/v1/mcp/servers/:idUpdate server properties.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Server name |
description | string | No | Server description |
mode | string | No | TOOLS or CODE |
settings | object | No | Server settings. For CODE servers, set settings.codeMode.approvalWaitSeconds from 0 to 60. |
authMode | string | No | oauth, bearer, or oauth_and_bearer |
endUserAccess | string | No | restricted or open |
endUserId | string | null | No | The end user's externalId, or null to remove server-level end-user scoping |
Response
{
"server": {
"id": "abc123def456",
"name": "Updated Name",
"mode": "CODE",
"authMode": "oauth",
"endUserAccess": "open",
"updatedAt": "2025-01-16T14:00:00.000Z"
}
}Example
curl -X PATCH https://api.weavz.io/api/v1/mcp/servers/abc123def456 \
-H "Authorization: Bearer wvz_your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "Updated Name", "mode": "CODE", "endUserAccess": "open"}'Errors
| Status | Code | Description |
|---|---|---|
404 | NOT_FOUND | MCP server not found |
Delete MCP Server
/api/v1/mcp/servers/:idDelete an MCP server and all its tools.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
Response
{
"deleted": true,
"id": "abc123def456"
}Example
curl -X DELETE https://api.weavz.io/api/v1/mcp/servers/abc123def456 \
-H "Authorization: Bearer wvz_your_api_key"Errors
| Status | Code | Description |
|---|---|---|
404 | NOT_FOUND | MCP server not found |
Regenerate Token
/api/v1/mcp/servers/:id/regenerate-tokenRegenerate the MCP bearer token. The old token is immediately invalidated. This endpoint is available only when the server's authMode enables static bearer auth.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
Response
{
"bearerToken": "mcp_new_token_here...",
"mcpEndpoint": "https://api.weavz.io/mcp/srv_abc123def456"
}Example
curl -X POST https://api.weavz.io/api/v1/mcp/servers/abc123def456/regenerate-token \
-H "Authorization: Bearer wvz_your_api_key"Errors
| Status | Code | Description |
|---|---|---|
404 | NOT_FOUND | MCP server not found |
409 | MCP_BEARER_DISABLED | Static bearer auth is not enabled for this server |
409 | MCP_STATIC_BEARER_INCOMPATIBLE | The workspace has strict per-user integrations and this server is not scoped to one endUserId; create end-user bearer tokens instead |
Create MCP Bearer Token
/api/v1/mcp/servers/:id/access-tokensIssue an mcp_ bearer token scoped to one existing end user. The token is shown only once and can be used as Authorization: Bearer mcp_... until it expires.
The server must be workspace-scoped and use authMode: "bearer" or authMode: "oauth_and_bearer". Each token is scoped to the MCP server, workspace, and selected end user, so multiple clients can use the same bearer-enabled server while resolving actions against different users.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
endUserId | string | Yes | End-user external ID, or internal UUID |
scopes | string[] | No | Defaults to ["mcp:tools"], or ["mcp:tools", "mcp:code"] for CODE mode servers |
expiresIn | number | No | Token lifetime in seconds, from 300 seconds to 90 days. Default: 30 days |
Response (201)
{
"accessToken": "mcp_abc123...",
"bearerToken": "mcp_abc123...",
"token": {
"id": "0c53f814-8dc6-4e98-a680-32bf0a7e4d65",
"tokenPrefix": "mcp_abc123",
"scopes": ["mcp:tools"],
"endUserId": "user_123",
"authMethod": "bearer",
"tokenType": "mcp_bearer",
"expiresAt": "2025-02-14T10:30:00.000Z",
"createdAt": "2025-01-15T10:30:00.000Z"
},
"mcpEndpoint": "https://api.weavz.io/mcp/srv_abc123def456"
}Example
curl -X POST https://api.weavz.io/api/v1/mcp/servers/abc123def456/access-tokens \
-H "Authorization: Bearer wvz_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"endUserId": "user_123",
"scopes": ["mcp:tools"],
"expiresIn": 2592000
}'Errors
| Status | Code | Description |
|---|---|---|
400 | WORKSPACE_REQUIRED | Server is not workspace-scoped |
400 | INVALID_MCP_SCOPES | Requested scopes are not supported by the server mode |
404 | END_USER_NOT_FOUND | End user does not exist in the server workspace |
404 | NOT_FOUND | MCP server not found |
409 | MCP_BEARER_DISABLED | End-user bearer tokens are not enabled for this server |
Create MCP OAuth Token
/api/v1/mcp/servers/:id/oauth-tokensIssue an MCP OAuth access token for an existing end user. The token is shown only once and can be used as Authorization: Bearer mcpo_... until it expires. This is useful when you are provisioning MCP clients programmatically and already know which end user should own the client session.
The server must be workspace-scoped and OAuth-enabled. The token is scoped to the MCP server, workspace, and selected end user.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
endUserId | string | Yes | End-user external ID, or internal UUID |
scopes | string[] | No | Defaults to ["mcp:tools"], or ["mcp:tools", "mcp:code"] for CODE mode servers |
expiresIn | number | No | Token lifetime in seconds, from 300 seconds to 90 days. Default: 30 days |
Response (201)
{
"accessToken": "mcpo_abc123...",
"token": {
"id": "0c53f814-8dc6-4e98-a680-32bf0a7e4d65",
"tokenPrefix": "mcpo_abc123",
"scopes": ["mcp:tools"],
"endUserId": "user_123",
"expiresAt": "2025-02-14T10:30:00.000Z",
"createdAt": "2025-01-15T10:30:00.000Z"
},
"mcpEndpoint": "https://api.weavz.io/mcp/srv_abc123def456"
}Example
curl -X POST https://api.weavz.io/api/v1/mcp/servers/abc123def456/oauth-tokens \
-H "Authorization: Bearer wvz_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"endUserId": "user_123",
"expiresIn": 2592000
}'Errors
| Status | Code | Description |
|---|---|---|
400 | WORKSPACE_REQUIRED | Server is not workspace-scoped |
404 | END_USER_NOT_FOUND | End user does not exist in the server workspace |
404 | NOT_FOUND | MCP server not found |
409 | MCP_OAUTH_DISABLED | MCP OAuth is not enabled for this server |
Add Tool
/api/v1/mcp/servers/:id/toolsAdd an integration action as a tool to the server.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
integrationName | string | Yes | Integration name |
actionName | string | Yes | Action name |
integrationAlias | string | No | Alias for the integration (defaults to integrationName). Must match ^[a-z][a-z0-9_-]*$, max 64 chars |
toolType | string | No | ACTION or TRIGGER (default: ACTION) |
connectionId | string (uuid) | No | Connection to use for this tool. Omit for actions that do not require external authentication |
displayName | string | No | Custom display name |
description | string | No | Custom description |
inputDefaults | object | No | Default input values |
partialIds | string[] | No | Partial IDs or names to assign to this tool. Partials must match the tool integration alias. If omitted, matching default partials can still apply. |
sortOrder | number | No | Sort position (default: 0) |
Integration aliases allow the same integration to appear multiple times on a server under different names (e.g., slack_bot and slack_user), each with its own connection.
Some integrations do not need a connection. Utility and built-in integrations such as datetime, hash-encode, data-transformer, storage, and kv-store can be added without connectionId. Use a connection only when the action needs authenticated access to an external account or when you want to pin a specific shared account.
Response (201)
{
"tool": {
"id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"mcpServerId": "abc123def456",
"integrationName": "slack",
"integrationAlias": "slack_bot",
"actionName": "send_channel_message",
"toolType": "ACTION",
"connectionId": "c1d2e3f4-5678-90ab-cdef-1234567890ab",
"sortOrder": 0
}
}Example
curl -X POST https://api.weavz.io/api/v1/mcp/servers/abc123def456/tools \
-H "Authorization: Bearer wvz_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"integrationName": "slack",
"actionName": "send_channel_message",
"integrationAlias": "slack_bot",
"connectionId": "c1d2e3f4-5678-90ab-cdef-1234567890ab"
}'Errors
| Status | Code | Description |
|---|---|---|
400 | VALIDATION_ERROR | Missing required fields or invalid alias format |
404 | NOT_FOUND | MCP server not found |
409 | DUPLICATE | Tool already exists on this server |
409 | ALIAS_CONFLICT | Alias is already mapped to a different integration |
Update Tool
/api/v1/mcp/servers/:id/tools/:toolIdUpdate a tool's configuration.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
toolId | string (uuid) | Tool ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
displayName | string | No | Custom display name |
description | string or null | No | Custom description. Set to null to clear it. |
inputDefaults | object | No | Default input values |
connectionId | string (uuid) or null | No | Connection to use. Set to null to clear it. |
sortOrder | number | No | Sort position |
integrationAlias | string | No | Updated alias |
partialIds | string[] | No | Partial IDs or names to assign to this tool. Partials must match the tool integration alias. Send an empty array to clear assigned partials; matching default partials can still apply. |
Response
{
"tool": {
"id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"integrationAlias": "slack_bot",
"displayName": "Send Bot Message",
"sortOrder": 1
}
}Example
curl -X PATCH https://api.weavz.io/api/v1/mcp/servers/abc123def456/tools/f1e2d3c4-b5a6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer wvz_your_api_key" \
-H "Content-Type: application/json" \
-d '{"displayName": "Send Bot Message", "sortOrder": 1}'Errors
| Status | Code | Description |
|---|---|---|
400 | VALIDATION_ERROR | Invalid fields |
404 | NOT_FOUND | Server or tool not found |
Remove Tool
/api/v1/mcp/servers/:id/tools/:toolIdRemove a tool from the server.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
toolId | string (uuid) | Tool ID |
Response
{
"deleted": true,
"id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890"
}Example
curl -X DELETE https://api.weavz.io/api/v1/mcp/servers/abc123def456/tools/f1e2d3c4-b5a6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer wvz_your_api_key"Errors
| Status | Code | Description |
|---|---|---|
404 | NOT_FOUND | Server or tool not found |
Execute Code
/api/v1/mcp/servers/:id/execute-codeExecute code against a Code Mode MCP server, or fetch the result of a previously approved Code Mode Human Gate. This endpoint is useful for playgrounds, custom harnesses, and SaaS builders that want to test or run Code Mode programmatically.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
code | string | Conditional | JavaScript Code Mode source to execute |
approvalId | string | Conditional | apr_... ID returned by an approval-required Code Mode result. Pass this alone after approval. |
waitForApprovalSeconds | integer | No | Optional override from 0 to 60 seconds for how long an approvalId continuation call waits while approval is still pending. Defaults to the server setting. |
Pass exactly one of code or approvalId.
Response
{
"content": [
{
"type": "text",
"text": "Execution result..."
}
],
"isError": false
}When Human Gates pauses the run, the response text contains structured JSON like:
{
"status": "approval_required",
"approval": {
"id": "apr_9b36d3f761d84bb2b6f9a0c4b9d1f7e0",
"approvalUrl": "https://platform.weavz.io/approve/apr_...?token=apr_link_v1_...",
"hostedApprovalUrl": "https://platform.weavz.io/approve/apr_...?token=apr_link_v1_...",
"expiresAt": "2026-05-14T13:00:00.000Z"
},
"approvals": [
{
"id": "apr_9b36d3f761d84bb2b6f9a0c4b9d1f7e0",
"hostedApprovalUrl": "https://platform.weavz.io/approve/apr_...?token=apr_link_v1_..."
},
{
"id": "apr_1c7f9d2a0b6e4e219fd9a879f0e8b123",
"hostedApprovalUrl": null
}
],
"continuation": {
"tool": "weavz_execute",
"arguments": { "approvalId": "apr_9b36d3f761d84bb2b6f9a0c4b9d1f7e0" }
}
}For Code Mode, approvals is present when a single run matches multiple approval policies. Retry with any approval ID from the group after a decision; if another policy is still pending, the MCP server returns approval_pending with the next required approval.
After the reviewer approves it, call the same endpoint with { "approvalId": "apr_..." }. Do not submit the original code again; Weavz resumes the stored run and caches the result.
If settings.codeMode.approvalWaitSeconds is enabled, or waitForApprovalSeconds is passed with the approvalId, Weavz waits briefly for the pending Human Gate before returning approval_pending. This does not push into an already completed MCP call; it only holds the active continuation request.
Example
curl -X POST https://api.weavz.io/api/v1/mcp/servers/abc123def456/execute-code \
-H "Authorization: Bearer wvz_your_api_key" \
-H "Content-Type: application/json" \
-d '{"code": "const result = await weavz.slack.send_channel_message({ channel: \"C123\", text: \"Hello\" }); return result;"}'Errors
| Status | Code | Description |
|---|---|---|
400 | INVALID_CODE_EXECUTE_REQUEST | Pass exactly one of code or approvalId, or fix an invalid waitForApprovalSeconds value |
403 | QUOTA_EXCEEDED | Sandbox quota exceeded |
404 | NOT_FOUND | MCP server not found |
Input validation failures inside weavz_execute are returned in the response body as a tool error (isError: true) with a precise message, such as Invalid input for datetime.parse_date: unknown key "date"; missing required key "dateString" or Allowed: "sha256", "sha1" for invalid enum values.
Get TypeScript Declarations
/api/v1/mcp/servers/:id/declarations/:integrationOrAliasGet TypeScript declarations for an integration on a CODE mode server. Returns type definitions for the weavz.* API surface, with hidden/defaulted inputs omitted for that server's tool configuration.
Path Parameters
| Field | Type | Description |
|---|---|---|
id | string | Server ID |
integrationOrAlias | string | Integration name or alias |
Response
{
"declarations": "declare namespace weavz {\n namespace hash {\n function generate_uuid(input: { count?: number }): Promise<{ success: true; uuid: string } | { success: true; uuids: string[]; count: number } | { success: false; error: string }>;\n }\n}"
}Example
curl https://api.weavz.io/api/v1/mcp/servers/abc123def456/declarations/hash \
-H "Authorization: Bearer wvz_your_api_key"Errors
| Status | Code | Description |
|---|---|---|
404 | NOT_FOUND | Server or integration not found |