faxseal-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +140 -0
- package/package.json +18 -0
package/index.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import {
|
|
5
|
+
CallToolRequestSchema,
|
|
6
|
+
ListToolsRequestSchema,
|
|
7
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
8
|
+
|
|
9
|
+
const BASE_URL = process.env.FAXSEAL_BASE_URL ?? 'https://faxseal.com';
|
|
10
|
+
const API_KEY = process.env.FAXSEAL_API_KEY ?? '';
|
|
11
|
+
|
|
12
|
+
if (!API_KEY) {
|
|
13
|
+
process.stderr.write('Error: FAXSEAL_API_KEY environment variable is required.\n');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function authHeaders() {
|
|
18
|
+
return {
|
|
19
|
+
'Authorization': `Bearer ${API_KEY}`,
|
|
20
|
+
'Content-Type': 'application/json',
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function apiFetch(path, options = {}) {
|
|
25
|
+
const res = await fetch(`${BASE_URL}${path}`, options);
|
|
26
|
+
const json = await res.json();
|
|
27
|
+
if (!res.ok) throw new Error(json.error ?? `HTTP ${res.status}`);
|
|
28
|
+
return json;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const server = new Server(
|
|
32
|
+
{ name: 'faxseal-mcp', version: '1.0.0' },
|
|
33
|
+
{ capabilities: { tools: {} } },
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
37
|
+
tools: [
|
|
38
|
+
{
|
|
39
|
+
name: 'send_fax',
|
|
40
|
+
description: 'Send a fax from a publicly accessible PDF URL. Returns a job ID for tracking.',
|
|
41
|
+
inputSchema: {
|
|
42
|
+
type: 'object',
|
|
43
|
+
required: ['to', 'file_url'],
|
|
44
|
+
properties: {
|
|
45
|
+
to: { type: 'string', description: 'Destination fax number in E.164 format, e.g. +12025551234' },
|
|
46
|
+
file_url: { type: 'string', description: 'Publicly accessible HTTPS URL to a PDF file' },
|
|
47
|
+
from_name: { type: 'string', description: 'Sender name for the cover page (optional)' },
|
|
48
|
+
from_company: { type: 'string', description: 'Sender company for the cover page (optional)' },
|
|
49
|
+
subject: { type: 'string', description: 'Fax subject line (optional)' },
|
|
50
|
+
notes: { type: 'string', description: 'Cover page notes (optional)' },
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'get_fax_status',
|
|
56
|
+
description: 'Check the delivery status of a fax. Status: queued → sending → delivered or failed.',
|
|
57
|
+
inputSchema: {
|
|
58
|
+
type: 'object',
|
|
59
|
+
required: ['job_id'],
|
|
60
|
+
properties: {
|
|
61
|
+
job_id: { type: 'string', description: 'Fax job ID returned by send_fax' },
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'get_credits',
|
|
67
|
+
description: 'Check the current FaxSeal credit balance for this API token.',
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
}));
|
|
75
|
+
|
|
76
|
+
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
77
|
+
const { name, arguments: args } = req.params;
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
if (name === 'send_fax') {
|
|
81
|
+
const data = await apiFetch('/api/zapier/send', {
|
|
82
|
+
method: 'POST',
|
|
83
|
+
headers: authHeaders(),
|
|
84
|
+
body: JSON.stringify({
|
|
85
|
+
to: args.to,
|
|
86
|
+
file_url: args.file_url,
|
|
87
|
+
from_name: args.from_name,
|
|
88
|
+
from_company: args.from_company,
|
|
89
|
+
subject: args.subject,
|
|
90
|
+
notes: args.notes,
|
|
91
|
+
}),
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
content: [{
|
|
95
|
+
type: 'text',
|
|
96
|
+
text: [
|
|
97
|
+
`✅ Fax queued successfully.`,
|
|
98
|
+
`Job ID: ${data.id}`,
|
|
99
|
+
`To: ${data.to_number}`,
|
|
100
|
+
`Pages: ${data.pages}`,
|
|
101
|
+
`Credits used: ${data.credits_used} (${data.credits_remaining} remaining)`,
|
|
102
|
+
`Track: ${data.track_url}`,
|
|
103
|
+
].join('\n'),
|
|
104
|
+
}],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (name === 'get_fax_status') {
|
|
109
|
+
const data = await apiFetch(`/api/v1/fax/${args.job_id}`, {
|
|
110
|
+
headers: authHeaders(),
|
|
111
|
+
});
|
|
112
|
+
const lines = [
|
|
113
|
+
`Status: ${data.status}`,
|
|
114
|
+
`To: ${data.toNumber}`,
|
|
115
|
+
`Pages: ${data.pages}`,
|
|
116
|
+
];
|
|
117
|
+
if (data.creditsUsed) lines.push(`Credits used: ${data.creditsUsed}`);
|
|
118
|
+
if (data.failureReason) lines.push(`Failure reason: ${data.failureReason}`);
|
|
119
|
+
if (data.certReceiptUrl) lines.push(`Receipt: ${data.certReceiptUrl}`);
|
|
120
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (name === 'get_credits') {
|
|
124
|
+
const data = await apiFetch('/api/user/credits', { headers: authHeaders() });
|
|
125
|
+
return {
|
|
126
|
+
content: [{ type: 'text', text: `Credit balance: ${data.credits}` }],
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
131
|
+
} catch (err) {
|
|
132
|
+
return {
|
|
133
|
+
content: [{ type: 'text', text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
134
|
+
isError: true,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const transport = new StdioServerTransport();
|
|
140
|
+
await server.connect(transport);
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "faxseal-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for FaxSeal — send faxes from Claude",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"faxseal-mcp": "./index.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node index.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": ["mcp", "fax", "faxseal", "claude"],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
17
|
+
}
|
|
18
|
+
}
|