Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions src/servers/peakflo/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
# Peakflo Server

pfMCP server implementation for interacting with Peakflo.
pfMCP server implementation for interacting with the Peakflo API (invoices, vendors, bills, actions, and more).

### Prerequisites

- Python 3.11+
- Signed up in peakflo
- Have access token set up

- Signed up in Peakflo
- API access token set up

To set up and verify authentication, run:

```bash
python src/servers/peakflo/main.py auth
```

### Tools

| Tool | Description |
|------|-------------|
| **read_vendor** | Fetch vendor details by external ID. |
| **create_vendor** | Create a new vendor with company info, addresses, contacts, bank details, and custom fields. |
| **create_invoice** | Create an invoice with line items, customer info, and financial breakdown. |
| **update_invoice** | Update an existing invoice. |
| **raise_invoice_dispute** | Raise a dispute for an invoice. |
| **soa_email** | Send an SOA (statement of account) email to the vendor. |
| **create_task** | Add an action to a vendor or customer (e.g. create a pay task). |
| **add_action_log** | Add an action log entry (e.g. save transcripts). |
| **run_bill_po_matching** | Run Purchase Order (PO) matching on an existing bill. Updates line-level PO links and 3-way matching details. Use when re-running matching after a bill was created without POs or when POs/bill data changed. Tenant is taken from the auth token; provide at least one of `billId`, `externalId`, or `sourceId` to identify the bill. |

### Run

#### Local Development

```bash
python src/servers/local.py --server slack --user-id local
python src/servers/local.py --server peakflo --user-id local
```
6 changes: 5 additions & 1 deletion src/servers/peakflo/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ async def make_peakflo_request(name, arguments, token):
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
tenantId = arguments["tenantId"]
tenantId = arguments.get("tenantId")
# remove tenantId from arguments if present, as it may appear in the payload (to handle vendor portal cases) but not expected by API
if "tenantId" in arguments:
arguments.pop("tenantId")
Expand Down Expand Up @@ -102,6 +102,10 @@ async def make_peakflo_request(name, arguments, token):
method = "POST"
url = f"{PEAKFLO_V1_BASE_URL}/addActionLog"
message = "Action log added successfully"
elif name == "run_bill_po_matching":
method = "POST"
url = f"{PEAKFLO_V1_BASE_URL}/runBillPoMatching"
message = "Bill PO matching completed successfully"
else:
raise ValueError(f"Unknown tool call: {name}")

Expand Down
23 changes: 23 additions & 0 deletions src/servers/peakflo/schemas/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,29 @@
"required": ["actionName", "note", "objectType", "objectId", "entityId"],
}

run_bill_po_matching_input_schema = {
"type": "object",
"properties": {
"tenantId": {
"type": "string",
"description": "Optional. Normally derived from the auth token; only set when calling in a context where tenant is not from the token (e.g. admin).",
},
"billId": {
"type": "string",
"description": "Peakflo internal bill ID. Use when you have the bill's ID from Peakflo; takes precedence over externalId/sourceId if provided.",
},
"externalId": {
"type": "string",
"description": "ID from your external system that was stored as sourceId on the bill. Use to look up the bill when you don't have the Peakflo billId.",
},
"sourceId": {
"type": "string",
"description": "Alias for externalId; same lookup as externalId (bill is found by sourceId).",
},
},
"required": [],
}

create_task_input_schema = {
"type": "object",
"properties": {
Expand Down
6 changes: 6 additions & 0 deletions src/servers/peakflo/tools/peakflo_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
soa_email_input_schema,
create_task_input_schema,
add_action_log_input_schema,
run_bill_po_matching_input_schema,
)
from servers.peakflo.schemas.invoice import (
create_invoice_schema,
Expand Down Expand Up @@ -74,4 +75,9 @@
description="Add an action log to the vendor or customer, can be used for saving transcripts in action log",
inputSchema=add_action_log_input_schema,
),
Tool(
name="run_bill_po_matching",
description="Run Purchase Order (PO) matching on an existing bill. Updates line-level PO links and matching details (3-way matching). Use when re-running PO matching after a bill was created without POs, or when POs/bill data changed. Tenant is taken from the auth token. Provide at least one of billId, externalId, or sourceId to identify the bill.",
inputSchema=run_bill_po_matching_input_schema,
),
]