ProWorkflow ProWorkflow

ProWorkflow MCP Server

Model Context Protocol server exposing ProWorkflow resources as tools for AI assistants.

–
Tools
–
API operations reachable
–
Groups

What is MCP?

The Model Context Protocol (MCP) is an open standard for connecting AI assistants to external tools and data. This server lets an assistant such as Claude work in ProWorkflow as the signed-in user, with their permissions.

What it covers

Named tools cover the everyday work: projects, tasks, time, invoices, quotes, requests, files and more. Their arguments are built from the REST API's own documentation, so they always match it. Four generic tools reach every other REST operation (see Any API Operation), so anything the API can do, the assistant can do.

    Tool badges

    Each tool shows the kind of operation (LIST, GET, CREATE, UPDATE, DELETE) and what it does to data: Read-only, Changes data or Deletes data. Clients get the same information from the tools' annotations, so they can allow reads freely and ask before deleting.

    REST API

    The MCP server calls the ProWorkflow REST API, with the same permissions. For every operation in detail, see the REST API Documentation.

    Using Claude?

    Follow Connect Claude to add ProWorkflow as a Claude connector: create an OAuth client, add the server URL in Claude and sign in. No code needed.

    Server URL
    URL
    https://api.proworkflow.com/api/v4/mcp
    Quick Example — List Projects
    JSON-RPC Request
    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "list_projects",
        "arguments": {
          "status": "active",
          "pagesize": 10
        }
      }
    }
    Response
    JSON-RPC Result
    {
      "jsonrpc": "2.0",
      "id": 1,
      "result": {
        "content": [{
          "type": "text",
          "text": "{\"status\":\"success\",\"data\":[...]}"
        }]
      }
    }

    Authentication

    Every MCP request needs one of two credentials, the same as the REST API:

    • OAuth access token — the request acts as the signed-in staff user, with their permissions. This is how Claude and other AI assistants connect.
    • API key — account-level access with no permission checks. For your own scripts and servers.

    Connect Claude

    A super user creates an OAuth client in ProWorkflow under Settings → Automation → OAuth Clients, keeping the prefilled redirect URI https://claude.ai/api/mcp/auth_callback. Add a custom connector in Claude with the server URL above and the client's ID and secret, then each person connects with their own ProWorkflow login. See Connect Claude for every step, including Team and Enterprise plans and Claude Code.

    OAuth for other MCP clients

    MCP clients find the sign-in server automatically. A request without valid credentials gets a 401 whose WWW-Authenticate header points to /.well-known/oauth-protected-resource, which names https://identity.proworkflow.com as the authorization server. Clients can't register themselves, so use the account's OAuth client: add your client's callback to its redirect URIs and enter its Client ID and Client Secret in your MCP client. The OAuth 2.0 guide covers the flow, scopes and token lifetimes.

    API Key

    Pass your ProWorkflow API key in the apikey header.

    Authentication Scope

    The server keeps no session state: every request is authenticated on its own, so a client can refresh its access token between calls. The same permission and division rules as the REST API apply.

    Redirect URI for Claude
    URL
    https://claude.ai/api/mcp/auth_callback
    Bearer Token
    cURL
    curl -X POST 'https://api.proworkflow.com/api/v4/mcp' \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer eyJhbG...' \
      -d '{"jsonrpc":"2.0","id":1,"method":"initialize",...}'
    API Key
    cURL
    curl -X POST 'https://api.proworkflow.com/api/v4/mcp' \
      -H 'Content-Type: application/json' \
      -H 'apikey: xxxx-xxxx-xxxx-xxxx-PWFxxxx' \
      -d '{"jsonrpc":"2.0","id":1,"method":"initialize",...}'
    Unauthenticated Response
    HTTP
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: Bearer resource_metadata="https://api.proworkflow.com/.well-known/oauth-protected-resource", scope="openid email"

    Conventions

    The server sends these instructions to the client when it connects, so the assistant knows the conventions every tool shares:

    Loading...
    IDs and lists
    Arguments
    {
      "contacts": "me",
      "companyid": "!3",
      "duedateto": "+7d",
      "fields": "name,duedate,project",
      "pagesize": 50,
      "pagenumber": 2
    }

    Any API Operation

    The named tools cover the everyday work. For anything else, four generic tools reach every operation in the REST API reference, with the same permissions:

    ToolUse it to
    find_api_operationsSearch every operation by keyword (“invoice phases”, “approve request”). Results name the matching named tool when there is one.
    describe_api_operationSee one operation's path, query and body parameters, with types, required flags and allowed values.
    api_readCall any GET operation. Read-only.
    api_writeCall any POST, PUT or DELETE operation. The body is an object, or an array where the operation takes one (time allocations).

    Paths take IDs filled in (/projects/12/items); /api/v4 is optional. Calls are checked against the API's documentation first: an unknown path or query parameter is refused with a pointer to the right tool, rather than sent. File uploads use upload_file.

    1. Find the operation
    find_api_operations
    { "query": "invoice phases" }
    
    POST /invoices/{invoiceid}/phases: Create Invoice Phases
    GET /invoices/{invoiceid}/phases: Get Invoice Phases
    ...
    2. Check its parameters
    describe_api_operation
    { "method": "POST", "path": "/invoices/5/phases" }
    3. Call it
    api_write
    {
      "method": "POST",
      "path": "/invoices/5/phases",
      "body": { "name": "Design" }
    }

    Examples

    How an assistant strings the tools together for common requests. Each step is one tool call.

    “What's due this week?”

    1. list_projectitems with contacts: "me", status: "active" and duedateto: "+7d".

    “Log 90 minutes on the homepage task”

    1. get_me for the user's contact ID.
    2. list_projectitems with q: "homepage" to find the item.
    3. create_time with the itemid, contactid, timespent: 90 (minutes) and a starttime.

    “Invoice the Acme quote”

    1. list_quotes with q: "Acme" to find the quote.
    2. list_lookup with kind: "invoice_terms" to choose a payment term.
    3. create_invoice_from_quote with the quoteid and invoicetermid.

    “Add Sam to the Website project and give them the design tasks”

    1. list_contacts with q: "Sam", and list_projects with q: "Website".
    2. add_project_contacts with the project and Sam's contact ID.
    3. list_projectitems with the projectid and q: "design".
    4. add_contacts_to_projectitems with the item IDs and Sam's contact ID.

    “Attach this brief to the project”

    1. upload_file with path: "/projects/12/files", a filename, and the file as content (text) or content_base64.
    Log time
    create_time
    {
      "itemid": 73675,
      "contactid": 12,
      "timespent": 90,
      "starttime": "2026-10-30T09:00:00Z",
      "notes": "Homepage layout review"
    }

    How It Works

    The MCP server uses JSON-RPC 2.0 over Streamable HTTP. All communication happens via POST /api/v4/mcp.

    1
    Initialize
    Agree a protocol version
    →
    2
    List Tools
    Discover available tools
    →
    3
    Call Tools
    Execute operations

    Step 1: Initialize

    Send an initialize request. The server responds with its capabilities, protocol version and instructions (see Conventions).

    Step 2: List Tools

    Send tools/list to discover all available tools and their input schemas. Each tool has a name, description, and JSON Schema for its parameters.

    Step 3: Call Tools

    Send tools/call with the tool name and arguments. The server executes the operation against the ProWorkflow REST API and returns the result.

    No sessions

    The server is stateless: it issues no mcp-session-id, and every request is authenticated and handled on its own, so clients can refresh their access token between calls. Responses are plain JSON, not an event stream.

    1. Initialize
    Request
    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "initialize",
      "params": {
        "protocolVersion": "2025-03-26",
        "capabilities": {},
        "clientInfo": {
          "name": "my-client",
          "version": "1.0.0"
        }
      }
    }
    2. List Tools
    Request
    {
      "jsonrpc": "2.0",
      "id": 2,
      "method": "tools/list"
    }
    3. Call Tool
    Request
    {
      "jsonrpc": "2.0",
      "id": 3,
      "method": "tools/call",
      "params": {
        "name": "get_company",
        "arguments": {
          "companyid": 42
        }
      }
    }

    Errors

    Tool errors are returned inside the CallToolResult with isError: true. The error message is in the content array as a text block.

    Common Error Scenarios

    Scenario Error Message
    Missing required argument missing required argument(s): projectid
    Unknown argument (a typo, or a filter the operation doesn't have) unknown argument(s): search. Valid arguments: fields, q, status, ...
    Generic tool path that isn't an API operation no API operation GET /nowhere. Use find_api_operations to search for one.
    Invalid credentials API error (HTTP 401): ...
    Permission denied API error (HTTP 403): ...
    Record not found API error (HTTP 404): ...
    Validation error API error (HTTP 400): ...
    Rate limited API error (HTTP 429): ...

    JSON-RPC Errors

    Protocol-level errors (invalid JSON-RPC, unknown method) return standard JSON-RPC error responses with negative error codes.

    Tool Error Response
    Error Result
    {
      "jsonrpc": "2.0",
      "id": 3,
      "result": {
        "content": [{
          "type": "text",
          "text": "API error (HTTP 403): {\"status\":\"error\",\"data\":[\"Permission denied\"]}"
        }],
        "isError": true
      }
    }
    JSON-RPC Protocol Error
    Error
    {
      "jsonrpc": "2.0",
      "id": 1,
      "error": {
        "code": -32601,
        "message": "Method not found"
      }
    }