prospectapis-mcp 0.2.2 → 0.2.4
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/CHANGELOG.md +22 -0
- package/README.md +15 -5
- package/package.json +5 -2
- package/src/server.js +3 -2
- package/src/tools.js +43 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,28 @@ All notable changes to `prospectapis-mcp` are documented here. The format follow
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.2.4] - unreleased
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Every tool has a human title ("Search Funding Rounds", "Delete Watchlist"), sent as both the tool's `title` and `annotations.title`; before, the title was the raw tool name.
|
|
14
|
+
- `watchlist_delete` now says `destructiveHint: true` (it removes the watchlist and its delivery history), so a client asks before running it; it said `false`, like every other tool. The other writes stay non-destructive: they only add a research job, a watchlist, a test event or a report.
|
|
15
|
+
- `idempotentHint` is set where it is true: the free reads and `watchlist_delete`. `funding_search` and `funding_get` stay `false`, because every call that returns records is billed again. `openWorldHint` stays `true` on every tool.
|
|
16
|
+
- One factory, `annotationsFor()` in `src/tools.js`, builds these annotations for the npm server and the hosted MCP door alike. `test/annotations.test.js` checks every served tool (a title that is not the raw name and has no underscore, every `*_delete` tool destructive and not read-only) and plants each regression to prove the check fails on it.
|
|
17
|
+
|
|
18
|
+
- README opening rewritten for the listings that copy it word for word (Glama, mcpservers.org, the MCP Registry, npm): one paragraph on what the server does and costs, then the install lines and the website, plus a three-question FAQ. No tool or behaviour change; 14 tools.
|
|
19
|
+
- `package-lock.json` carries the package version again (it still said 0.2.2).
|
|
20
|
+
- `test/readme-opening.test.js` checks the opening against the package name, its Website line against `server.json` `websiteUrl`, every tool count the README states against `src/tools.js`, the stated Node floor against `engines`, and one version across `package.json`, `server.json` and `package-lock.json`.
|
|
21
|
+
- The README no longer says every funding record carries its announcement URL: some records come back without one, so the opening and the FAQ now say records carry the public announcement URL when there is one, and `test/readme-opening.test.js` fails on any sentence that promises a URL on every record.
|
|
22
|
+
- `test/package-scripts.test.js` checks that every file an npm script runs exists in the checkout.
|
|
23
|
+
|
|
24
|
+
## [0.2.3] - 2026-10-11
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- `server.json` (the Official MCP Registry manifest) and the matching `mcpName` field in `package.json`, both `io.github.ProspectAPIs/prospectapis-mcp`, so the server can be listed on registry.modelcontextprotocol.io (which PulseMCP ingests). No tool or behaviour change.
|
|
29
|
+
- `scripts/registry-drift.mjs` with `npm run check:registry-drift` and a `postpublish` hook, so every npm release also updates the registry entry and a drift between npm, `server.json` and the registry fails the check.
|
|
30
|
+
|
|
9
31
|
## [0.2.2] - 2026-10-03
|
|
10
32
|
|
|
11
33
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# prospectapis-mcp
|
|
2
2
|
|
|
3
|
-
MCP server for the ProspectAPIs funding
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
`
|
|
3
|
+
prospectapis-mcp is the MCP server for ProspectAPIs, built for sales teams and their AI agents in Claude Code, Claude Desktop, Cursor and other MCP clients. It gives your agent fourteen tools over the ProspectAPIs API: search funding rounds by date, round, amount, company, investor and country, get new matching rounds pushed to your webhook, and order a cited research brief on any company or person. Funding records carry the public announcement URL when there is one. Records cost $0.02 each after 100 free a month, a completed brief costs $0.15, and there are no seats, no subscription and no card to sign up. It needs Node.js 22 or later.
|
|
4
|
+
|
|
5
|
+
Install (Claude Code): `claude mcp add prospectapis -e PROSPECTAPIS_API_KEY=pa_live_... -- npx -y prospectapis-mcp`
|
|
6
|
+
|
|
7
|
+
Other clients: run `npx -y prospectapis-mcp` with `PROSPECTAPIS_API_KEY` from https://prospectapis.com
|
|
8
|
+
|
|
9
|
+
Website: https://prospectapis.com/mcp
|
|
8
10
|
|
|
9
11
|
| Tool | Endpoint | Cost |
|
|
10
12
|
|---|---|---|
|
|
@@ -50,6 +52,14 @@ Client config (for example `claude_desktop_config.json`):
|
|
|
50
52
|
|
|
51
53
|
Claude Code: `claude mcp add prospectapis -e PROSPECTAPIS_API_KEY=pa_live_... -- npx -y prospectapis-mcp`.
|
|
52
54
|
|
|
55
|
+
## FAQ
|
|
56
|
+
|
|
57
|
+
**Where does the funding data come from?** Records carry the public announcement URL when there is one.
|
|
58
|
+
|
|
59
|
+
**What is free?** 100 funding records a month, any search that matches nothing, watchlist management, and the balance, pricing and version tools.
|
|
60
|
+
|
|
61
|
+
**Which clients work?** Claude Code, Claude Desktop, Cursor and any client that reads an mcpServers config, through `npx -y prospectapis-mcp`.
|
|
62
|
+
|
|
53
63
|
## Develop
|
|
54
64
|
|
|
55
65
|
```bash
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prospectapis-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
|
+
"mcpName": "io.github.ProspectAPIs/prospectapis-mcp",
|
|
4
5
|
"description": "MCP server for ProspectAPIs: search funding rounds, run paid prospect research briefs, manage funding watchlists, read your balance and the live price list.",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"bin": {
|
|
@@ -25,7 +26,9 @@
|
|
|
25
26
|
"start": "node src/index.js",
|
|
26
27
|
"check": "node --check src/index.js && node --check src/server.js && node --check src/tools.js",
|
|
27
28
|
"test": "node --test \"test/**/*.test.js\"",
|
|
28
|
-
"prepublishOnly": "npm test"
|
|
29
|
+
"prepublishOnly": "npm test && node scripts/prepublish-tenant-check.mjs",
|
|
30
|
+
"check:registry-drift": "node scripts/registry-drift.mjs",
|
|
31
|
+
"postpublish": "node scripts/registry-drift.mjs --publish"
|
|
29
32
|
},
|
|
30
33
|
"dependencies": {
|
|
31
34
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
package/src/server.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
7
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
|
-
import { TOOLS, buildUrl, buildPath, buildBody } from "./tools.js";
|
|
8
|
+
import { TOOLS, buildUrl, buildPath, buildBody, annotationsFor } from "./tools.js";
|
|
9
9
|
|
|
10
10
|
export const { version: VERSION } = createRequire(import.meta.url)("../package.json");
|
|
11
11
|
|
|
@@ -95,9 +95,10 @@ export function createServer({
|
|
|
95
95
|
server.registerTool(
|
|
96
96
|
tool.name,
|
|
97
97
|
{
|
|
98
|
+
title: tool.title,
|
|
98
99
|
description: tool.description,
|
|
99
100
|
inputSchema: tool.shape,
|
|
100
|
-
annotations:
|
|
101
|
+
annotations: annotationsFor(tool),
|
|
101
102
|
},
|
|
102
103
|
(args) => callEndpoint(tool, args),
|
|
103
104
|
);
|
package/src/tools.js
CHANGED
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
// - `write: true` marks a tool that changes state or spends credits
|
|
11
11
|
// (research_submit starts a paid job); the server turns `write` into MCP's
|
|
12
12
|
// readOnlyHint, so every other tool is read-only;
|
|
13
|
-
// - `auth: false` marks the tools the API serves without a key (pricing_get, api_version)
|
|
13
|
+
// - `auth: false` marks the tools the API serves without a key (pricing_get, api_version);
|
|
14
|
+
// - `title` is the human name a client shows instead of the raw tool name;
|
|
15
|
+
// - `idempotent: true` marks a tool whose repeat call with the same arguments changes nothing more: the free
|
|
16
|
+
// reads, and watchlist_delete (a second delete finds nothing to delete). funding_search and funding_get are
|
|
17
|
+
// read-only but NOT idempotent, because every call that returns records is billed again.
|
|
18
|
+
// annotationsFor() below turns these fields into MCP tool annotations; the npm server and the hosted door
|
|
19
|
+
// (apps/api/src/lib/mcp-door.js, through createServer) both register every tool with it, so they cannot drift.
|
|
14
20
|
|
|
15
21
|
import { z } from "zod";
|
|
16
22
|
|
|
@@ -38,6 +44,7 @@ export const TOOLS = [
|
|
|
38
44
|
name: "funding_search",
|
|
39
45
|
method: "GET",
|
|
40
46
|
path: "/v1/funding",
|
|
47
|
+
title: "Search Funding Rounds",
|
|
41
48
|
write: false,
|
|
42
49
|
format: { min_amount_usd: formatAmount, max_amount_usd: formatAmount },
|
|
43
50
|
description:
|
|
@@ -64,6 +71,7 @@ export const TOOLS = [
|
|
|
64
71
|
name: "funding_get",
|
|
65
72
|
method: "GET",
|
|
66
73
|
path: "/v1/funding/{id}",
|
|
74
|
+
title: "Get Funding Round",
|
|
67
75
|
write: false,
|
|
68
76
|
description: "Read one funding record by id. Costs $0.02 when found (free records are used first); a missing id is free.",
|
|
69
77
|
shape: {
|
|
@@ -74,6 +82,7 @@ export const TOOLS = [
|
|
|
74
82
|
name: "research_submit",
|
|
75
83
|
method: "POST",
|
|
76
84
|
path: "/v1/research",
|
|
85
|
+
title: "Start Prospect Research",
|
|
77
86
|
write: true,
|
|
78
87
|
body: true,
|
|
79
88
|
description:
|
|
@@ -103,6 +112,8 @@ export const TOOLS = [
|
|
|
103
112
|
name: "research_get",
|
|
104
113
|
method: "GET",
|
|
105
114
|
path: "/v1/research/{id}",
|
|
115
|
+
title: "Get Research Brief",
|
|
116
|
+
idempotent: true,
|
|
106
117
|
write: false,
|
|
107
118
|
description:
|
|
108
119
|
"Read a research job by the `research_id` research_submit returned: `status` (queued, running, completed, failed), `input`, " +
|
|
@@ -118,6 +129,7 @@ export const TOOLS = [
|
|
|
118
129
|
name: "watchlist_create",
|
|
119
130
|
method: "POST",
|
|
120
131
|
path: "/v1/watchlists",
|
|
132
|
+
title: "Create Funding Watchlist",
|
|
121
133
|
body: true,
|
|
122
134
|
write: true,
|
|
123
135
|
description:
|
|
@@ -145,6 +157,8 @@ export const TOOLS = [
|
|
|
145
157
|
name: "watchlist_list",
|
|
146
158
|
method: "GET",
|
|
147
159
|
path: "/v1/watchlists",
|
|
160
|
+
title: "List Watchlists",
|
|
161
|
+
idempotent: true,
|
|
148
162
|
write: false,
|
|
149
163
|
description: "Your funding-signal alerts (without their secrets). Free.",
|
|
150
164
|
shape: {},
|
|
@@ -153,6 +167,8 @@ export const TOOLS = [
|
|
|
153
167
|
name: "watchlist_get",
|
|
154
168
|
method: "GET",
|
|
155
169
|
path: "/v1/watchlists/{id}",
|
|
170
|
+
title: "Get Watchlist",
|
|
171
|
+
idempotent: true,
|
|
156
172
|
write: false,
|
|
157
173
|
description: "One funding-signal alert: its name, filters, webhook URL, whether it is active and why it was paused (never its secret). Free.",
|
|
158
174
|
shape: { id: z.string().uuid().describe("The watchlist id.") },
|
|
@@ -161,6 +177,8 @@ export const TOOLS = [
|
|
|
161
177
|
name: "watchlist_deliveries",
|
|
162
178
|
method: "GET",
|
|
163
179
|
path: "/v1/watchlists/{id}/deliveries",
|
|
180
|
+
title: "List Watchlist Deliveries",
|
|
181
|
+
idempotent: true,
|
|
164
182
|
write: false,
|
|
165
183
|
description: "The last 50 deliveries of one alert and their outcome (delivered, retry, failed, no_credit). Free.",
|
|
166
184
|
shape: { id: z.string().uuid().describe("The watchlist id.") },
|
|
@@ -169,6 +187,7 @@ export const TOOLS = [
|
|
|
169
187
|
name: "watchlist_test",
|
|
170
188
|
method: "POST",
|
|
171
189
|
path: "/v1/watchlists/{id}/test",
|
|
190
|
+
title: "Send Watchlist Test Event",
|
|
172
191
|
body: true,
|
|
173
192
|
write: true,
|
|
174
193
|
description: "Send a signed sample event to the alert's webhook now, to build and verify the receiver. Free; 5 a minute.",
|
|
@@ -178,6 +197,8 @@ export const TOOLS = [
|
|
|
178
197
|
name: "watchlist_delete",
|
|
179
198
|
method: "DELETE",
|
|
180
199
|
path: "/v1/watchlists/{id}",
|
|
200
|
+
title: "Delete Watchlist",
|
|
201
|
+
idempotent: true,
|
|
181
202
|
write: true,
|
|
182
203
|
description: "Delete a funding-signal alert and its delivery history. Free.",
|
|
183
204
|
shape: { id: z.string().uuid().describe("The watchlist id.") },
|
|
@@ -186,6 +207,8 @@ export const TOOLS = [
|
|
|
186
207
|
name: "account_balance",
|
|
187
208
|
method: "GET",
|
|
188
209
|
path: "/v1/account",
|
|
210
|
+
title: "Get Account Balance",
|
|
211
|
+
idempotent: true,
|
|
189
212
|
write: false,
|
|
190
213
|
description: "Your credit balance and the free records left this month. Free. Check it before a large paged search.",
|
|
191
214
|
shape: {},
|
|
@@ -194,6 +217,7 @@ export const TOOLS = [
|
|
|
194
217
|
name: "feedback_send",
|
|
195
218
|
method: "POST",
|
|
196
219
|
path: "/v1/feedback",
|
|
220
|
+
title: "Send Feedback",
|
|
197
221
|
body: true,
|
|
198
222
|
write: true,
|
|
199
223
|
description:
|
|
@@ -212,6 +236,8 @@ export const TOOLS = [
|
|
|
212
236
|
name: "pricing_get",
|
|
213
237
|
method: "GET",
|
|
214
238
|
path: "/pricing",
|
|
239
|
+
title: "Get Pricing",
|
|
240
|
+
idempotent: true,
|
|
215
241
|
write: false,
|
|
216
242
|
auth: false,
|
|
217
243
|
description:
|
|
@@ -223,6 +249,8 @@ export const TOOLS = [
|
|
|
223
249
|
name: "api_version",
|
|
224
250
|
method: "GET",
|
|
225
251
|
path: "/v1/version",
|
|
252
|
+
title: "Get API Version",
|
|
253
|
+
idempotent: true,
|
|
226
254
|
write: false,
|
|
227
255
|
auth: false,
|
|
228
256
|
description: "The API's version and deployed build. Free, needs no key.",
|
|
@@ -270,3 +298,17 @@ export function buildBody(tool, args) {
|
|
|
270
298
|
}
|
|
271
299
|
return JSON.stringify(out);
|
|
272
300
|
}
|
|
301
|
+
|
|
302
|
+
// The one place a catalog entry becomes MCP tool annotations. A tool is destructive when it is a write whose
|
|
303
|
+
// method is DELETE (watchlist_delete removes the watchlist and its delivery history); every other write only adds
|
|
304
|
+
// (a research job, a watchlist, a test event, a report), so it is a write that is not destructive.
|
|
305
|
+
export function annotationsFor(tool) {
|
|
306
|
+
const write = !!tool.write;
|
|
307
|
+
return {
|
|
308
|
+
title: tool.title,
|
|
309
|
+
readOnlyHint: !write,
|
|
310
|
+
destructiveHint: write && tool.method === "DELETE",
|
|
311
|
+
idempotentHint: !!tool.idempotent,
|
|
312
|
+
openWorldHint: true,
|
|
313
|
+
};
|
|
314
|
+
}
|