Skip to content

Commit 41754f5

Browse files
Merge pull request #7 from PaystackOSS/chore/mcp-logging-updates
Chore/mcp logging updates
2 parents e821226 + 0bd03ad commit 41754f5

3 files changed

Lines changed: 152 additions & 30 deletions

File tree

readme.md

Lines changed: 143 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,163 @@
11
# Paystack MCP Server
22

3-
This project implements a server for Paystack's [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server.
3+
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that enables AI assistants to interact with the full range of [Paystack APIs](https://paystack.com/docs/api/).
44

5+
## Quick Start
6+
7+
<!-- TODO: Update once published to npm -->
8+
```bash
9+
# Via npx (coming soon)
10+
npx paystack-mcp start
11+
12+
# With environment configuration
13+
PAYSTACK_SECRET_KEY_TEST=sk_test_... npx paystack-mcp start
14+
```
15+
16+
For now, clone and build locally:
17+
18+
```bash
19+
git clone https://github.com/PaystackOSS/paystack-mcp-server.git
20+
cd paystack-mcp-server
21+
npm install
22+
npm run build
23+
```
24+
25+
Then configure your MCP client to use the built server (see [Client Integration](#client-integration)).
526

627
## Requirements
728

8-
- Node.js (v14+ recommended)
29+
- Node.js v18+
930
- npm or yarn
31+
- A Paystack test secret key (starts with `sk_test_`)
32+
33+
## Configuration Options
34+
35+
| Environment Variable | Purpose | Default |
36+
| --- | --- | --- |
37+
| `PAYSTACK_SECRET_KEY_TEST` | Your Paystack test secret key **(required)** ||
38+
| `NODE_ENV` | Environment mode (`development`, `production`, `test`) | `development` |
39+
| `LOG_LEVEL` | Logging verbosity (`debug`, `info`, `warn`, `error`) | `info` |
40+
41+
> **Security note:** Only test keys (`sk_test_*`) are allowed. The server validates this at startup and will reject live keys.
42+
43+
## Client Integration
44+
45+
The Paystack MCP Server works with any MCP-compatible client. Below is the standard configuration schema used by most clients (Claude Desktop, ChatGPT Desktop, Cursor, Windsurf, etc.).
46+
47+
### Using a local build
48+
49+
If you've cloned and built the server locally:
50+
51+
```json
52+
{
53+
"mcpServers": {
54+
"paystack": {
55+
"command": "node",
56+
"args": ["/path/to/paystack-mcp-server/build/index.js"],
57+
"env": {
58+
"PAYSTACK_SECRET_KEY_TEST": "sk_test_..."
59+
}
60+
}
61+
}
62+
}
63+
```
64+
65+
### Using npm (coming soon)
66+
67+
<!-- TODO: Update once published -->
68+
```json
69+
{
70+
"mcpServers": {
71+
"paystack": {
72+
"command": "npx",
73+
"args": ["paystack-mcp", "start"],
74+
"env": {
75+
"PAYSTACK_SECRET_KEY_TEST": "sk_test_..."
76+
}
77+
}
78+
}
79+
}
80+
```
81+
82+
### Where to add this configuration
83+
84+
| Client | Config file location |
85+
| --- | --- |
86+
| Claude Desktop | `claude_desktop_config.json` |
87+
| ChatGPT Desktop | MCP settings in app preferences |
88+
| Cursor | `.cursor/mcp.json` or global MCP settings |
89+
| Windsurf | MCP configuration in settings |
90+
| Claude Code | `~/.claude/mcp.json` or project-level `.mcp.json` |
1091

11-
## Setup
92+
## How It Works
1293

13-
1. Clone the repository:
14-
```
15-
git clone https://github.com/yourusername/paystack-mcp-server.git
16-
cd paystack-mcp
17-
```
94+
The Paystack MCP Server exposes the **entire Paystack API** to AI assistants by parsing Paystack's OpenAPI specification at runtime. Instead of hardcoding individual endpoints, the server dynamically discovers all available operations and makes them accessible through a small set of tools.
1895

19-
2. Install dependencies:
20-
```
21-
npm install
22-
```
96+
### Available Tools
2397

24-
3. Configure environment variables:
25-
- Copy `.env.example` to `.env` and update with your Paystack credentials and server settings.
98+
| Tool | Description |
99+
| --- | --- |
100+
| `get_paystack_operation` | Fetch operation details (method, path, parameters) by operation ID |
101+
| `make_paystack_request` | Execute a Paystack API request |
26102

27-
4. Start the server:
28-
```
29-
npm start
30-
```
103+
### Available Resources
104+
105+
| Resource | Description |
106+
| --- | --- |
107+
| `openapi://operations/list` | List all available Paystack operation IDs |
108+
109+
### Example
110+
111+
When you ask your AI assistant something like *"Get me the last 5 transactions"*, here's what happens behind the scenes:
112+
113+
1. The assistant calls `get_paystack_operation("transaction_list")` to look up the endpoint details
114+
2. It gets back the method (`GET`), path (`/transaction`), and available query parameters
115+
3. It then calls `make_paystack_request` with `{ method: "GET", path: "/transaction", data: { perPage: 5 } }`
116+
4. You get your transactions
117+
118+
## Development
119+
120+
### Run locally (without building)
121+
122+
For local development and testing, you can run the TypeScript source directly:
123+
124+
```bash
125+
PAYSTACK_SECRET_KEY_TEST=sk_test_... npm run dev
126+
```
127+
128+
### Run with MCP Inspector
129+
130+
```bash
131+
npm run inspect
132+
```
133+
134+
### Build
135+
136+
```bash
137+
npm run build
138+
```
139+
140+
### Run tests
141+
142+
```bash
143+
npm test
144+
```
145+
146+
## Troubleshooting
147+
148+
| Issue | Solution |
149+
| --- | --- |
150+
| Server exits silently at startup | Check that `PAYSTACK_SECRET_KEY_TEST` is set (not `PAYSTACK_TEST_SECRET_KEY`) |
151+
| "Invalid key" error | Key must start with `sk_test_` — live keys are not allowed |
152+
| Tools not appearing in client | Ensure the server is running and the client config path is correct |
153+
| Request timeouts | Check network connectivity to `api.paystack.co` |
31154

32155
## Contributing
33156

34157
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
35158

159+
See [contributing.md](contributing.md) for more details.
160+
36161
## License
37162

38163
MIT

src/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ async function initializeServer() {
3939

4040
try {
4141
const operation = openapi.getOperationById(operation_id.trim());
42-
console.log("Operation: ", operation)
42+
console.error("Operation: ", operation)
4343

4444
if (!operation) {
4545
return {
@@ -93,16 +93,16 @@ async function initializeServer() {
9393
},
9494
async ({ request }) => {
9595
try {
96-
console.log("Request received:", request.method);
97-
console.log("Request received:", request.path);
98-
console.log("Request received:", request.data);
96+
console.error("Request received:", request.method);
97+
console.error("Request received:", request.path);
98+
console.error("Request received:", request.data);
9999

100100
const response = await paystackClient.makeRequest(
101101
request.method,
102102
request.path,
103103
request.data
104104
)
105-
console.log("response: ", response)
105+
console.error("response: ", response)
106106

107107
return {
108108
content: [

src/paystack-client.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import { PaystackResponse, PaystackError } from "./types";
2-
import dotenv from 'dotenv';
2+
import { paystackConfig } from "./config";
33

4-
// Load environment variables
5-
dotenv.config();
6-
7-
const PAYSTACK_BASE_URL = process.env.PAYSTACK_BASE_URL || 'https://api.paystack.co';
4+
const PAYSTACK_BASE_URL = paystackConfig.baseURL;
85
const USER_AGENT = process.env.USER_AGENT || 'Paystack-MCP-Client';
96

107
class PaystackClient {
@@ -87,5 +84,5 @@ class PaystackClient {
8784
}
8885
}
8986
export const paystackClient = new PaystackClient(
90-
process.env.PAYSTACK_TEST_SECRET_KEY!
91-
);
87+
paystackConfig.secretKey
88+
);

0 commit comments

Comments
 (0)