@cognilead/mcp-server 0.1.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/LICENSE +21 -0
- package/README.md +138 -0
- package/dist/api-client.d.ts +7 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +50 -0
- package/dist/api-client.js.map +1 -0
- package/dist/auth.d.ts +25 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +62 -0
- package/dist/auth.js.map +1 -0
- package/dist/config.d.ts +14 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +21 -0
- package/dist/config.js.map +1 -0
- package/dist/http.d.ts +5 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +169 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +153 -0
- package/dist/index.js.map +1 -0
- package/dist/rate-limit.d.ts +17 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +80 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/schemas.d.ts +384 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +206 -0
- package/dist/schemas.js.map +1 -0
- package/dist/tools/check-registry-flags.d.ts +2 -0
- package/dist/tools/check-registry-flags.d.ts.map +1 -0
- package/dist/tools/check-registry-flags.js +31 -0
- package/dist/tools/check-registry-flags.js.map +1 -0
- package/dist/tools/draft-pitch.d.ts +15 -0
- package/dist/tools/draft-pitch.d.ts.map +1 -0
- package/dist/tools/draft-pitch.js +69 -0
- package/dist/tools/draft-pitch.js.map +1 -0
- package/dist/tools/evidence-export.d.ts +7 -0
- package/dist/tools/evidence-export.d.ts.map +1 -0
- package/dist/tools/evidence-export.js +42 -0
- package/dist/tools/evidence-export.js.map +1 -0
- package/dist/tools/find-companies-with-triggers.d.ts +2 -0
- package/dist/tools/find-companies-with-triggers.d.ts.map +1 -0
- package/dist/tools/find-companies-with-triggers.js +29 -0
- package/dist/tools/find-companies-with-triggers.js.map +1 -0
- package/dist/tools/generate-seo-content.d.ts +2 -0
- package/dist/tools/generate-seo-content.d.ts.map +1 -0
- package/dist/tools/generate-seo-content.js +14 -0
- package/dist/tools/generate-seo-content.js.map +1 -0
- package/dist/tools/get-business-sheet.d.ts +2 -0
- package/dist/tools/get-business-sheet.d.ts.map +1 -0
- package/dist/tools/get-business-sheet.js +24 -0
- package/dist/tools/get-business-sheet.js.map +1 -0
- package/dist/tools/ingest-lead.d.ts +2 -0
- package/dist/tools/ingest-lead.d.ts.map +1 -0
- package/dist/tools/ingest-lead.js +26 -0
- package/dist/tools/ingest-lead.js.map +1 -0
- package/dist/tools/rank-companies-in-vertical.d.ts +2 -0
- package/dist/tools/rank-companies-in-vertical.d.ts.map +1 -0
- package/dist/tools/rank-companies-in-vertical.js +33 -0
- package/dist/tools/rank-companies-in-vertical.js.map +1 -0
- package/dist/tools/run-campaign.d.ts +2 -0
- package/dist/tools/run-campaign.d.ts.map +1 -0
- package/dist/tools/run-campaign.js +15 -0
- package/dist/tools/run-campaign.js.map +1 -0
- package/dist/tools/score-dd-risk.d.ts +2 -0
- package/dist/tools/score-dd-risk.d.ts.map +1 -0
- package/dist/tools/score-dd-risk.js +22 -0
- package/dist/tools/score-dd-risk.js.map +1 -0
- package/dist/tools/score-signal.d.ts +15 -0
- package/dist/tools/score-signal.d.ts.map +1 -0
- package/dist/tools/score-signal.js +124 -0
- package/dist/tools/score-signal.js.map +1 -0
- package/dist/tools/suppress.d.ts +2 -0
- package/dist/tools/suppress.d.ts.map +1 -0
- package/dist/tools/suppress.js +13 -0
- package/dist/tools/suppress.js.map +1 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CogniLead
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# @cognilead/mcp-server
|
|
2
|
+
|
|
3
|
+
Model Context Protocol server for [CogniLead](https://cognilead.ai) —
|
|
4
|
+
the managed cold-email deliverability engine for EU/technical B2B (plus AI
|
|
5
|
+
content scaffolding). Exposes five tools to Cursor, Claude Desktop, Windsurf,
|
|
6
|
+
and any MCP-capable client so you can draft outbound copy and run campaigns
|
|
7
|
+
without leaving your IDE. All generation runs on phi-cloud as the LLM provider.
|
|
8
|
+
|
|
9
|
+
Two tools are free (no API key, daily-capped). Three are gated behind a
|
|
10
|
+
CogniLead API key — when the key is absent, the tool returns an inline
|
|
11
|
+
signup URL so you can fix it in seconds.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g @cognilead/mcp-server
|
|
17
|
+
# or run on demand without installing
|
|
18
|
+
npx -y @cognilead/mcp-server
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The binary is `cognilead-mcp` and speaks the MCP stdio transport.
|
|
22
|
+
|
|
23
|
+
## Configure your IDE
|
|
24
|
+
|
|
25
|
+
### Cursor
|
|
26
|
+
|
|
27
|
+
`~/.cursor/mcp.json` (or `.cursor/mcp.json` per-project):
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcpServers": {
|
|
32
|
+
"cognilead": {
|
|
33
|
+
"command": "npx",
|
|
34
|
+
"args": ["-y", "@cognilead/mcp-server"],
|
|
35
|
+
"env": {
|
|
36
|
+
"COGNILEAD_API_KEY": "pk_live_..."
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Claude Desktop
|
|
44
|
+
|
|
45
|
+
`~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
46
|
+
or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"cognilead": {
|
|
52
|
+
"command": "npx",
|
|
53
|
+
"args": ["-y", "@cognilead/mcp-server"],
|
|
54
|
+
"env": {
|
|
55
|
+
"COGNILEAD_API_KEY": "pk_live_..."
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Windsurf
|
|
63
|
+
|
|
64
|
+
`~/.codeium/windsurf/mcp_config.json`:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"mcpServers": {
|
|
69
|
+
"cognilead": {
|
|
70
|
+
"command": "npx",
|
|
71
|
+
"args": ["-y", "@cognilead/mcp-server"],
|
|
72
|
+
"env": {
|
|
73
|
+
"COGNILEAD_API_KEY": "pk_live_..."
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Omit `COGNILEAD_API_KEY` to run in free-tier mode (only `draft_pitch`
|
|
81
|
+
and `score_signal` are callable; the three gated tools return a 401 with
|
|
82
|
+
an inline upgrade URL).
|
|
83
|
+
|
|
84
|
+
## Tools
|
|
85
|
+
|
|
86
|
+
| Tool | Tier | Daily cap | What it does |
|
|
87
|
+
|---|---|---|---|
|
|
88
|
+
| `cognilead.draft_pitch` | free | 20/day | Draft a short, personalised outbound pitch from the insight/context you feed it (the product, topic, and target account). |
|
|
89
|
+
| `cognilead.score_signal` | free | 50/day | Score a supplied insight/context for fit against a target product (0-100, deterministic). |
|
|
90
|
+
| `cognilead.ingest_lead` | gated | — | Register a (customer-supplied) lead in the outbound pipeline. |
|
|
91
|
+
| `cognilead.run_campaign` | gated | — | Kick off an email campaign by id, optionally restricted to a set of leads. |
|
|
92
|
+
| `cognilead.suppress` | gated | — | Add an email or domain to the suppression list (honours one-click RFC 8058 unsubscribe). |
|
|
93
|
+
|
|
94
|
+
> Note: MarketPrior-fed targeting tools are **roadmap, not live**. Today you
|
|
95
|
+
> supply leads/context yourself; CogniLead runs the deliverability.
|
|
96
|
+
|
|
97
|
+
Free-tier quotas reset at UTC midnight and persist between IDE restarts
|
|
98
|
+
in `~/.cognilead/quota.json`.
|
|
99
|
+
|
|
100
|
+
## Environment
|
|
101
|
+
|
|
102
|
+
| Var | Default | Purpose |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `COGNILEAD_API_KEY` | _unset_ | Bearer token for gated tools |
|
|
105
|
+
| `COGNILEAD_API_URL` | `https://api.cognilead.ai` | Override for self-hosted |
|
|
106
|
+
| `COGNILEAD_SIGNUP_URL` | `https://cognilead.ai/signup?via=mcp` | Upgrade-hint URL |
|
|
107
|
+
| `COGNILEAD_QUOTA_DIR` | `~/.cognilead` | Free-tier quota state directory |
|
|
108
|
+
| `COGNILEAD_MCP_HTTP_PORT` | `8787` | Only used by the hosted-MCP HTTP variant |
|
|
109
|
+
|
|
110
|
+
## Get a key
|
|
111
|
+
|
|
112
|
+
[Sign up](https://cognilead.ai/signup?via=mcp) — the free tier ships with
|
|
113
|
+
100 outbound sends per month plus capped AI content scaffolding. Paid plans add
|
|
114
|
+
warmed sender pools, the reputation circuit-breaker, and reply/bounce handling.
|
|
115
|
+
(MarketPrior-fed targeting is roadmap, not yet available.)
|
|
116
|
+
|
|
117
|
+
## Local development
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
cd packages/mcp-server
|
|
121
|
+
npm install
|
|
122
|
+
npm run dev # tsx src/index.ts (stdio)
|
|
123
|
+
npm run build # tsc → dist/
|
|
124
|
+
npm run start # node dist/index.js
|
|
125
|
+
npm run start:http # node dist/http.js — hosted-MCP HTTP variant
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
To test the binary doesn't crash on startup:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
node packages/mcp-server/dist/index.js < /dev/null
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
It should exit cleanly when stdin closes.
|
|
135
|
+
|
|
136
|
+
## License
|
|
137
|
+
|
|
138
|
+
MIT
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ApiError extends Error {
|
|
2
|
+
status: number;
|
|
3
|
+
body: unknown;
|
|
4
|
+
}
|
|
5
|
+
export declare function apiPost(path: string, body: unknown): Promise<unknown>;
|
|
6
|
+
export declare function apiGet(path: string): Promise<unknown>;
|
|
7
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,QAAS,SAAQ,KAAK;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,OAAO,CAAA;CACd;AAuBD,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAY3E;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAW3D"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Minimal fetch wrapper for the hosted CogniLead API. No dependencies —
|
|
2
|
+
// uses the global `fetch` available since Node 18.
|
|
3
|
+
import { authHeaders } from './auth.js';
|
|
4
|
+
import { loadConfig } from './config.js';
|
|
5
|
+
function makeError(status, body, fallback) {
|
|
6
|
+
const message = (body && typeof body === 'object' && 'error' in body && typeof body.error === 'string'
|
|
7
|
+
? body.error
|
|
8
|
+
: fallback) || fallback;
|
|
9
|
+
const err = new Error(message);
|
|
10
|
+
err.status = status;
|
|
11
|
+
err.body = body;
|
|
12
|
+
return err;
|
|
13
|
+
}
|
|
14
|
+
async function parseBody(res) {
|
|
15
|
+
const text = await res.text();
|
|
16
|
+
if (!text)
|
|
17
|
+
return null;
|
|
18
|
+
try {
|
|
19
|
+
return JSON.parse(text);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return text;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export async function apiPost(path, body) {
|
|
26
|
+
const { apiUrl } = loadConfig();
|
|
27
|
+
const res = await fetch(`${apiUrl}${path}`, {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
headers: authHeaders(),
|
|
30
|
+
body: JSON.stringify(body ?? {}),
|
|
31
|
+
});
|
|
32
|
+
const data = await parseBody(res);
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
throw makeError(res.status, data, `POST ${path} failed (${res.status})`);
|
|
35
|
+
}
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
export async function apiGet(path) {
|
|
39
|
+
const { apiUrl } = loadConfig();
|
|
40
|
+
const res = await fetch(`${apiUrl}${path}`, {
|
|
41
|
+
method: 'GET',
|
|
42
|
+
headers: authHeaders(),
|
|
43
|
+
});
|
|
44
|
+
const data = await parseBody(res);
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
throw makeError(res.status, data, `GET ${path} failed (${res.status})`);
|
|
47
|
+
}
|
|
48
|
+
return data;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,mDAAmD;AAEnD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAOxC,SAAS,SAAS,CAAC,MAAc,EAAE,IAAa,EAAE,QAAgB;IAChE,MAAM,OAAO,GACX,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;QACpF,CAAC,CAAC,IAAI,CAAC,KAAK;QACZ,CAAC,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAA;IAC3B,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,OAAO,CAAa,CAAA;IAC1C,GAAG,CAAC,MAAM,GAAG,MAAM,CAAA;IACnB,GAAG,CAAC,IAAI,GAAG,IAAI,CAAA;IACf,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAa;IACpC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;IAC7B,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IACtB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAA;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAY,EAAE,IAAa;IACvD,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAA;IAC/B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,EAAE;QAC1C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,WAAW,EAAE;QACtB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC;KACjC,CAAC,CAAA;IACF,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAA;IACjC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,IAAI,YAAY,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;IAC1E,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAY;IACvC,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAA;IAC/B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,EAAE;QAC1C,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,WAAW,EAAE;KACvB,CAAC,CAAA;IACF,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAA;IACjC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,IAAI,YAAY,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;IACzE,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare class McpAuthError extends Error {
|
|
2
|
+
readonly code = "mcp.unauthenticated";
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
5
|
+
export declare class McpQuotaError extends Error {
|
|
6
|
+
readonly code = "mcp.quota_exceeded";
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Client-side fail-fast check. Throws when no API key is configured so
|
|
11
|
+
* gated tools surface a useful error before any network I/O. The hosted
|
|
12
|
+
* /api/v1/* surface is the authoritative gate — skipping this check
|
|
13
|
+
* just means the developer sees a generic 401 instead of the curated
|
|
14
|
+
* message below.
|
|
15
|
+
*/
|
|
16
|
+
export declare function assertGatedAccess(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Header bag for the hosted API. Every gated tool MUST route through
|
|
19
|
+
* this when it talks to the hosted /api/v1/* surface — the Bearer token
|
|
20
|
+
* is what the server's withAuth() wrapper verifies before letting the
|
|
21
|
+
* call hit the repo. Without it the server returns 401 regardless of
|
|
22
|
+
* what the client-side assertGatedAccess() said.
|
|
23
|
+
*/
|
|
24
|
+
export declare function authHeaders(): Record<string, string>;
|
|
25
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAoBA,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,yBAAwB;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,wBAAuB;gBACxB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAQ1C;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOpD"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Auth gate for the gated tools.
|
|
2
|
+
//
|
|
3
|
+
// IMPORTANT (closes strategic-review finding #3): the *real* auth gate
|
|
4
|
+
// is now server-side at /api/v1/* in the hosted CogniLead service —
|
|
5
|
+
// each route handler wraps in withAuth() and rejects requests that
|
|
6
|
+
// don't carry a valid `Authorization: Bearer pk_live_…` header.
|
|
7
|
+
//
|
|
8
|
+
// The client-side assertGatedAccess() check below is retained purely
|
|
9
|
+
// for UX: it fails fast with a curated error message + signup link
|
|
10
|
+
// BEFORE any network call so the developer experience is "you forgot
|
|
11
|
+
// to set COGNILEAD_API_KEY" instead of "401 from the server" with no
|
|
12
|
+
// next step. Skipping or spoofing this check has no security impact —
|
|
13
|
+
// every call eventually has to satisfy the server.
|
|
14
|
+
//
|
|
15
|
+
// The error message is intentionally verbatim from the strategic plan
|
|
16
|
+
// — IDEs surface this string directly to developers and it doubles as
|
|
17
|
+
// the acquisition copy.
|
|
18
|
+
import { loadConfig } from './config.js';
|
|
19
|
+
export class McpAuthError extends Error {
|
|
20
|
+
code = 'mcp.unauthenticated';
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = 'McpAuthError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class McpQuotaError extends Error {
|
|
27
|
+
code = 'mcp.quota_exceeded';
|
|
28
|
+
constructor(message) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.name = 'McpQuotaError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Client-side fail-fast check. Throws when no API key is configured so
|
|
35
|
+
* gated tools surface a useful error before any network I/O. The hosted
|
|
36
|
+
* /api/v1/* surface is the authoritative gate — skipping this check
|
|
37
|
+
* just means the developer sees a generic 401 instead of the curated
|
|
38
|
+
* message below.
|
|
39
|
+
*/
|
|
40
|
+
export function assertGatedAccess() {
|
|
41
|
+
const cfg = loadConfig();
|
|
42
|
+
if (!cfg.apiKey) {
|
|
43
|
+
throw new McpAuthError(`This tool requires a CogniLead API key. Get one at ${cfg.signupUrl} (free for 100 sends/mo).`);
|
|
44
|
+
}
|
|
45
|
+
return cfg.apiKey;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Header bag for the hosted API. Every gated tool MUST route through
|
|
49
|
+
* this when it talks to the hosted /api/v1/* surface — the Bearer token
|
|
50
|
+
* is what the server's withAuth() wrapper verifies before letting the
|
|
51
|
+
* call hit the repo. Without it the server returns 401 regardless of
|
|
52
|
+
* what the client-side assertGatedAccess() said.
|
|
53
|
+
*/
|
|
54
|
+
export function authHeaders() {
|
|
55
|
+
const apiKey = assertGatedAccess();
|
|
56
|
+
return {
|
|
57
|
+
Authorization: `Bearer ${apiKey}`,
|
|
58
|
+
'Content-Type': 'application/json',
|
|
59
|
+
'User-Agent': 'cognilead-mcp/0.1.0',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,EAAE;AACF,uEAAuE;AACvE,oEAAoE;AACpE,mEAAmE;AACnE,gEAAgE;AAChE,EAAE;AACF,qEAAqE;AACrE,mEAAmE;AACnE,qEAAqE;AACrE,qEAAqE;AACrE,sEAAsE;AACtE,mDAAmD;AACnD,EAAE;AACF,sEAAsE;AACtE,sEAAsE;AACtE,wBAAwB;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,GAAG,qBAAqB,CAAA;IACrC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,IAAI,GAAG,oBAAoB,CAAA;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;IAC7B,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,GAAG,UAAU,EAAE,CAAA;IACxB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,IAAI,YAAY,CACpB,sDAAsD,GAAG,CAAC,SAAS,2BAA2B,CAC/F,CAAA;IACH,CAAC;IACD,OAAO,GAAG,CAAC,MAAM,CAAA;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAA;IAClC,OAAO;QACL,aAAa,EAAE,UAAU,MAAM,EAAE;QACjC,cAAc,EAAE,kBAAkB;QAClC,YAAY,EAAE,qBAAqB;KACpC,CAAA;AACH,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface McpConfig {
|
|
2
|
+
apiKey: string | null;
|
|
3
|
+
apiUrl: string;
|
|
4
|
+
signupUrl: string;
|
|
5
|
+
/**
|
|
6
|
+
* Directory where best-effort quota state is persisted. Defaults to
|
|
7
|
+
* `~/.cognilead`. We fail-open if this path isn't writable.
|
|
8
|
+
*/
|
|
9
|
+
quotaDir: string;
|
|
10
|
+
/** Hosted MCP HTTP port (only used by src/http.ts). */
|
|
11
|
+
httpPort: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function loadConfig(): McpConfig;
|
|
14
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAA;CACjB;AAOD,wBAAgB,UAAU,IAAI,SAAS,CAYtC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Runtime config. Read from env so the package stays portable when it's
|
|
2
|
+
// later published as a standalone npm bin.
|
|
3
|
+
//
|
|
4
|
+
// COGNILEAD_API_KEY — required for gated tools; absent ⇒ free tier only.
|
|
5
|
+
// COGNILEAD_API_URL — defaults to production; override for self-hosted.
|
|
6
|
+
// COGNILEAD_SIGNUP_URL — the upgrade hint URL shown in 401 errors.
|
|
7
|
+
function defaultQuotaDir() {
|
|
8
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? '/tmp';
|
|
9
|
+
return `${home}/.cognilead`;
|
|
10
|
+
}
|
|
11
|
+
export function loadConfig() {
|
|
12
|
+
return {
|
|
13
|
+
apiKey: process.env.COGNILEAD_API_KEY?.trim() || null,
|
|
14
|
+
apiUrl: (process.env.COGNILEAD_API_URL ?? 'https://api.cognilead.ai').replace(/\/+$/, ''),
|
|
15
|
+
signupUrl: process.env.COGNILEAD_SIGNUP_URL ??
|
|
16
|
+
'https://cognilead.ai/signup?via=mcp',
|
|
17
|
+
quotaDir: process.env.COGNILEAD_QUOTA_DIR ?? defaultQuotaDir(),
|
|
18
|
+
httpPort: Number(process.env.COGNILEAD_MCP_HTTP_PORT ?? 8787),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,2CAA2C;AAC3C,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,mEAAmE;AAenE,SAAS,eAAe;IACtB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,MAAM,CAAA;IAClE,OAAO,GAAG,IAAI,aAAa,CAAA;AAC7B,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,IAAI;QACrD,MAAM,EAAE,CACN,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,0BAA0B,CAC5D,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACrB,SAAS,EACP,OAAO,CAAC,GAAG,CAAC,oBAAoB;YAChC,qCAAqC;QACvC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,eAAe,EAAE;QAC9D,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,IAAI,CAAC;KAC9D,CAAA;AACH,CAAC"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAmIA,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAkCpG"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// HTTP variant — Phase 2 hosted MCP at mcp.cognilead.ai.
|
|
2
|
+
//
|
|
3
|
+
// Implements two endpoints over Node's built-in http module (no Express
|
|
4
|
+
// dep):
|
|
5
|
+
// POST /mcp/v1/tools/list → { tools: ToolSpec[] }
|
|
6
|
+
// POST /mcp/v1/tools/call → { content?, isError?, error? }
|
|
7
|
+
//
|
|
8
|
+
// Gated tools require Bearer auth (COGNILEAD_API_KEY on the server side
|
|
9
|
+
// is overridden by the inbound Authorization header for the duration of
|
|
10
|
+
// the request via process.env mutation — single-process only, fine for
|
|
11
|
+
// the placeholder).
|
|
12
|
+
//
|
|
13
|
+
// This file is forward-looking. It must compile and start without
|
|
14
|
+
// crashing. Real hosted MCP gets a proper auth layer in Phase 2.
|
|
15
|
+
import { createServer as createHttpServer } from 'node:http';
|
|
16
|
+
import { TOOLS } from './index.js';
|
|
17
|
+
import { loadConfig } from './config.js';
|
|
18
|
+
import { McpAuthError, McpQuotaError } from './auth.js';
|
|
19
|
+
const FREE_TOOLS = new Set(['cognilead.draft_pitch', 'cognilead.score_signal']);
|
|
20
|
+
async function readBody(req) {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
const chunks = [];
|
|
23
|
+
req.on('data', (c) => chunks.push(c));
|
|
24
|
+
req.on('end', () => {
|
|
25
|
+
const raw = Buffer.concat(chunks).toString('utf8');
|
|
26
|
+
if (!raw)
|
|
27
|
+
return resolve(null);
|
|
28
|
+
try {
|
|
29
|
+
resolve(JSON.parse(raw));
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
reject(e);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
req.on('error', reject);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function sendJson(res, status, body) {
|
|
39
|
+
const buf = Buffer.from(JSON.stringify(body), 'utf8');
|
|
40
|
+
res.writeHead(status, {
|
|
41
|
+
'Content-Type': 'application/json; charset=utf-8',
|
|
42
|
+
'Content-Length': buf.byteLength.toString(),
|
|
43
|
+
});
|
|
44
|
+
res.end(buf);
|
|
45
|
+
}
|
|
46
|
+
function extractBearer(req) {
|
|
47
|
+
const h = req.headers.authorization ?? '';
|
|
48
|
+
const m = /^Bearer\s+(.+)$/i.exec(h);
|
|
49
|
+
return m ? m[1].trim() : null;
|
|
50
|
+
}
|
|
51
|
+
function formatError(e) {
|
|
52
|
+
if (e instanceof McpAuthError) {
|
|
53
|
+
return { code: e.code, message: e.message, upgrade_url: loadConfig().signupUrl };
|
|
54
|
+
}
|
|
55
|
+
if (e instanceof McpQuotaError) {
|
|
56
|
+
return { code: e.code, message: e.message };
|
|
57
|
+
}
|
|
58
|
+
if (e instanceof Error) {
|
|
59
|
+
return { code: 'mcp.tool_error', message: e.message };
|
|
60
|
+
}
|
|
61
|
+
return { code: 'mcp.unknown', message: String(e) };
|
|
62
|
+
}
|
|
63
|
+
async function handleListTools(_req, res) {
|
|
64
|
+
sendJson(res, 200, {
|
|
65
|
+
tools: TOOLS.map((t) => ({
|
|
66
|
+
name: t.name,
|
|
67
|
+
description: t.description,
|
|
68
|
+
inputSchema: t.inputSchema,
|
|
69
|
+
})),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async function handleCallTool(req, res) {
|
|
73
|
+
let body;
|
|
74
|
+
try {
|
|
75
|
+
body = (await readBody(req));
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
return sendJson(res, 400, { error: { code: 'mcp.bad_request', message: e.message } });
|
|
79
|
+
}
|
|
80
|
+
const name = body?.name;
|
|
81
|
+
if (!name || typeof name !== 'string') {
|
|
82
|
+
return sendJson(res, 400, {
|
|
83
|
+
error: { code: 'mcp.bad_request', message: 'missing tool name' },
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const tool = TOOLS.find((t) => t.name === name);
|
|
87
|
+
if (!tool) {
|
|
88
|
+
return sendJson(res, 404, {
|
|
89
|
+
error: { code: 'mcp.unknown_tool', message: `Unknown tool: ${name}` },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
// Auth shim: if a Bearer header is present, surface it as
|
|
93
|
+
// COGNILEAD_API_KEY for the duration of this request. This is single-
|
|
94
|
+
// process and not concurrency-safe — Phase 2 will inject via request
|
|
95
|
+
// context instead.
|
|
96
|
+
const bearer = extractBearer(req);
|
|
97
|
+
const prior = process.env.COGNILEAD_API_KEY;
|
|
98
|
+
if (bearer)
|
|
99
|
+
process.env.COGNILEAD_API_KEY = bearer;
|
|
100
|
+
if (!bearer && !FREE_TOOLS.has(name)) {
|
|
101
|
+
sendJson(res, 401, {
|
|
102
|
+
error: {
|
|
103
|
+
code: 'mcp.unauthenticated',
|
|
104
|
+
message: `This tool requires a CogniLead API key. Get one at ${loadConfig().signupUrl} (free for 100 sends/mo).`,
|
|
105
|
+
upgrade_url: loadConfig().signupUrl,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
const result = await tool.handler(body?.arguments ?? {});
|
|
112
|
+
sendJson(res, 200, { content: [{ type: 'text', text: JSON.stringify(result) }] });
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
const payload = formatError(e);
|
|
116
|
+
const status = payload.code === 'mcp.unauthenticated' ? 401 : payload.code === 'mcp.quota_exceeded' ? 429 : 500;
|
|
117
|
+
sendJson(res, status, { isError: true, error: payload });
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
if (bearer) {
|
|
121
|
+
if (prior === undefined)
|
|
122
|
+
delete process.env.COGNILEAD_API_KEY;
|
|
123
|
+
else
|
|
124
|
+
process.env.COGNILEAD_API_KEY = prior;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export function startHttpServer(port) {
|
|
129
|
+
const p = port ?? loadConfig().httpPort;
|
|
130
|
+
const srv = createHttpServer(async (req, res) => {
|
|
131
|
+
// Always respond JSON, even for unknown routes.
|
|
132
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
133
|
+
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
|
|
134
|
+
res.setHeader('Access-Control-Allow-Headers', 'Authorization, Content-Type');
|
|
135
|
+
if (req.method === 'OPTIONS') {
|
|
136
|
+
res.writeHead(204).end();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (req.method !== 'POST') {
|
|
140
|
+
return sendJson(res, 405, { error: { code: 'mcp.method_not_allowed' } });
|
|
141
|
+
}
|
|
142
|
+
const url = req.url ?? '';
|
|
143
|
+
if (url === '/mcp/v1/tools/list')
|
|
144
|
+
return handleListTools(req, res);
|
|
145
|
+
if (url === '/mcp/v1/tools/call')
|
|
146
|
+
return handleCallTool(req, res);
|
|
147
|
+
return sendJson(res, 404, { error: { code: 'mcp.not_found' } });
|
|
148
|
+
});
|
|
149
|
+
return new Promise((resolve) => {
|
|
150
|
+
srv.listen(p, () => {
|
|
151
|
+
const addr = srv.address();
|
|
152
|
+
const actualPort = typeof addr === 'object' && addr ? addr.port : p;
|
|
153
|
+
process.stderr.write(`[cognilead-mcp-http] listening on :${actualPort}\n`);
|
|
154
|
+
resolve({
|
|
155
|
+
port: actualPort,
|
|
156
|
+
close: () => new Promise((r, reject) => srv.close((e) => (e ? reject(e) : r()))),
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// Run only when invoked directly.
|
|
162
|
+
const isDirect = import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith('/http.js');
|
|
163
|
+
if (isDirect) {
|
|
164
|
+
startHttpServer().catch((err) => {
|
|
165
|
+
process.stderr.write(`[cognilead-mcp-http] fatal: ${err.message}\n`);
|
|
166
|
+
process.exit(1);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
interface ToolSpec {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
inputSchema: unknown;
|
|
7
|
+
handler: (input: unknown) => Promise<unknown>;
|
|
8
|
+
}
|
|
9
|
+
export declare const TOOLS: ToolSpec[];
|
|
10
|
+
export declare function createServer(): Server;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAaA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AA8BlE,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,OAAO,CAAA;IACpB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC9C;AAED,eAAO,MAAM,KAAK,EAAE,QAAQ,EA2C3B,CAAA;AAiCD,wBAAgB,YAAY,IAAI,MAAM,CAmDrC"}
|