Skip to content
Draft
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ Once connected, you can ask Claude things like:
- "What are the spending rules for card 12345?"
- "Show me pending payments"

## Privacy Policy

The PEX MCP Server acts as a pass-through to the PEX Card API. It does not independently collect, store, or transmit user data beyond what is required to fulfill API requests. All data handling is governed by the [PEX Privacy Policy](https://www.pexcard.com/legal/privacy-policy/).

## License

MIT
48 changes: 48 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"manifest_version": "0.3",
"name": "pex-mcp-server",
"display_name": "PEX Card",
"version": "1.0.3",
"description": "Access PEX business accounts, cards, transactions, and more",
"author": {
"name": "PEX Card",
"url": "https://github.com/pexcard"
},
"repository": {
"type": "git",
"url": "https://github.com/pexcard/mcp.git"
},
"homepage": "https://github.com/pexcard/mcp",
"server": {
"type": "node",
"entry_point": "dist/index.js",
"mcp_config": {
"command": "node",
"args": ["${__dirname}/dist/index.js"],
"env": {
"PEX_API_URL": "${user_config.pex_api_url}",
"PEX_API_TOKEN": "${user_config.pex_api_token}"
}
}
},
"tools_generated": true,
"keywords": ["pex", "expense-management", "corporate-cards", "finance"],
"license": "MIT",
"privacy_policies": ["https://www.pexcard.com/legal/privacy-policy/"],
"user_config": {
"pex_api_url": {
"type": "string",
"title": "PEX API URL",
"description": "PEX API base URL",
"required": true,
"default": "https://coreapi.pexcard.com/v4"
},
"pex_api_token": {
"type": "string",
"title": "PEX API Token",
"description": "Your PEX API authentication token",
"sensitive": true,
"required": true
}
}
}
8 changes: 8 additions & 0 deletions src/tools/bill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_bill",
{
title: "Get Bill",
description: "Get bill payment details by bill ID",
annotations: { readOnlyHint: true },
inputSchema: {
billId: z.number().describe("Bill ID"),
},
Expand All @@ -25,7 +27,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_bill_payments",
{
title: "Get Bill Payments",
description: "Get payments for a specific bill",
annotations: { readOnlyHint: true },
inputSchema: {
billId: z.number().describe("Bill ID"),
},
Expand All @@ -43,7 +47,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_bill_payment_request",
{
title: "Get Bill Payment Request",
description: "Get a specific bill payment request by ID",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Bill payment request ID"),
},
Expand All @@ -61,7 +67,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_search_bills",
{
title: "Search Bills",
description: "Search bills with optional filters",
annotations: { readOnlyHint: true },
inputSchema: {
createdDateFrom: z.string().optional().describe("Created date from (ISO 8601)"),
createdDateTo: z.string().optional().describe("Created date to (ISO 8601)"),
Expand Down
60 changes: 51 additions & 9 deletions src/tools/business.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { toolResponse, toolError } from "./utils.js";
export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_business_profile",
{ description: "Get business profile details including name, address, phone, and status" },
{
title: "Get Business Profile",
description: "Get business profile details including name, address, phone, and status",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/Business/Profile");
Expand All @@ -19,7 +23,11 @@ export function register(server: McpServer, client: PexClient): void {

server.registerTool(
"pex_get_business_balance",
{ description: "Get business account balance" },
{
title: "Get Business Balance",
description: "Get business account balance",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/Business/Balance");
Expand All @@ -32,7 +40,11 @@ export function register(server: McpServer, client: PexClient): void {

server.registerTool(
"pex_get_business_admins",
{ description: "Get list of all business administrators" },
{
title: "Get Business Admins",
description: "Get list of all business administrators",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/Business/Admin");
Expand All @@ -46,7 +58,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_business_admin",
{
title: "Get Business Admin",
description: "Get a specific business administrator by ID",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Administrator ID"),
},
Expand All @@ -63,7 +77,11 @@ export function register(server: McpServer, client: PexClient): void {

server.registerTool(
"pex_get_business_tags",
{ description: "Get all business tags" },
{
title: "Get Business Tags",
description: "Get all business tags",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/Business/Configuration/Tags");
Expand All @@ -77,7 +95,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_business_tag",
{
title: "Get Business Tag",
description: "Get a specific business tag by ID",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Tag ID"),
},
Expand All @@ -94,7 +114,11 @@ export function register(server: McpServer, client: PexClient): void {

server.registerTool(
"pex_get_business_linked",
{ description: "Get linked businesses" },
{
title: "Get Linked Businesses",
description: "Get linked businesses",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/Business/Linked");
Expand All @@ -107,7 +131,11 @@ export function register(server: McpServer, client: PexClient): void {

server.registerTool(
"pex_get_business_bank_account",
{ description: "Get business bank account details" },
{
title: "Get Business Bank Account",
description: "Get business bank account details",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/Business/BankAccount");
Expand All @@ -120,7 +148,11 @@ export function register(server: McpServer, client: PexClient): void {

server.registerTool(
"pex_get_business_one_time_transfer",
{ description: "Get business one-time transfer details" },
{
title: "Get Business One-Time Transfer",
description: "Get business one-time transfer details",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/Business/OneTimeTransfer");
Expand All @@ -133,7 +165,11 @@ export function register(server: McpServer, client: PexClient): void {

server.registerTool(
"pex_get_business_my_profile",
{ description: "Get the current user's business profile" },
{
title: "Get My Business Profile",
description: "Get the current user's business profile",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/Business/MyProfile");
Expand All @@ -147,8 +183,10 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_business_billing",
{
title: "Get Business Billing",
description:
"Get business billing information for a specific month. Current month values are estimates; finalized after billing cycle ends.",
annotations: { readOnlyHint: true },
inputSchema: {
month: z.number().describe("Month (1–12)"),
year: z.number().describe("Year (e.g. 2025)"),
Expand All @@ -166,7 +204,11 @@ export function register(server: McpServer, client: PexClient): void {

server.registerTool(
"pex_get_business_settings",
{ description: "Get business settings" },
{
title: "Get Business Settings",
description: "Get business settings",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/Business/Settings");
Expand Down
10 changes: 9 additions & 1 deletion src/tools/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { toolResponse, toolError } from "./utils.js";
export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_callback_types",
{ description: "Get available callback subscription types" },
{
title: "Get Callback Types",
description: "Get available callback subscription types",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/callback-subscription/types");
Expand All @@ -20,7 +24,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_list_callback_subscriptions",
{
title: "List Callback Subscriptions",
description: "Get all callback subscriptions for the business, optionally filtered by type",
annotations: { readOnlyHint: true },
inputSchema: {
type: z
.string()
Expand All @@ -43,7 +49,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_callback_subscription",
{
title: "Get Callback Subscription",
description: "Get a specific callback subscription by ID",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Subscription ID"),
},
Expand Down
14 changes: 14 additions & 0 deletions src/tools/card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_card",
{
title: "Get Card",
description: "Get card profile/details by card account ID",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Card account ID"),
},
Expand All @@ -25,7 +27,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_card_spend_rules",
{
title: "Get Card Spend Rules",
description: "Get spending rules for a specific card",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Card account ID"),
},
Expand All @@ -43,7 +47,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_card_advanced_spend_rules",
{
title: "Get Card Advanced Spend Rules",
description: "Get advanced spending rules for a specific card",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Card account ID"),
},
Expand All @@ -61,7 +67,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_card_load_limit_remaining",
{
title: "Get Card Load Limit Remaining",
description: "Get remaining card load limit for a specific card",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Card account ID"),
},
Expand All @@ -79,7 +87,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_card_order",
{
title: "Get Card Order",
description: "Get a specific card order by ID",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Card order ID"),
},
Expand All @@ -97,7 +107,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_card_scheduled_funding_rules",
{
title: "Get Card Scheduled Funding Rules",
description: "Get scheduled funding rules for a specific card",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Card account ID"),
},
Expand All @@ -115,7 +127,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_card_orders",
{
title: "Get Card Orders",
description: "Get card orders within an optional date range",
annotations: { readOnlyHint: true },
inputSchema: {
startDate: z.string().optional().describe("Start date (ISO 8601)"),
endDate: z.string().optional().describe("End date (ISO 8601)"),
Expand Down
12 changes: 11 additions & 1 deletion src/tools/credit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { toolResponse, toolError } from "./utils.js";
export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_credit_lines",
{ description: "Get credit line information for the business" },
{
title: "Get Credit Lines",
description: "Get credit line information for the business",
annotations: { readOnlyHint: true },
},
async () => {
try {
const result = await client.get("/CreditLinesInfo");
Expand All @@ -20,7 +24,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_invoices",
{
title: "Get Invoices",
description: "Get business invoices starting from a given date",
annotations: { readOnlyHint: true },
inputSchema: {
startDate: z.string().describe("Start date (ISO 8601 date-time)"),
},
Expand All @@ -38,7 +44,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_invoice_allocations",
{
title: "Get Invoice Allocations",
description: "Get allocations for a specific invoice",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Invoice ID"),
},
Expand All @@ -56,7 +64,9 @@ export function register(server: McpServer, client: PexClient): void {
server.registerTool(
"pex_get_invoice_payments",
{
title: "Get Invoice Payments",
description: "Get payments for a specific invoice",
annotations: { readOnlyHint: true },
inputSchema: {
id: z.number().describe("Invoice ID"),
},
Expand Down
Loading