spm-mcp 0.2.0 → 0.3.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/dist/src/client/cloud-functions.d.ts +1 -0
- package/dist/src/client/cloud-functions.js +4 -0
- package/dist/src/client/spm-api.d.ts +1 -0
- package/dist/src/client/spm-api.js +4 -0
- package/dist/src/index.js +4 -0
- package/dist/src/tools/clarify.d.ts +10 -0
- package/dist/src/tools/clarify.js +14 -1
- package/dist/src/tools/evaluate.d.ts +2 -0
- package/dist/src/tools/evaluate.js +3 -1
- package/package.json +1 -1
- package/src/client/cloud-functions.ts +5 -0
- package/src/client/spm-api.ts +5 -0
- package/src/index.ts +12 -0
- package/src/tools/clarify.ts +19 -0
- package/src/tools/evaluate.ts +6 -0
|
@@ -2,4 +2,5 @@
|
|
|
2
2
|
* Helper to call Cloud Functions that return plain JSON (not SSE).
|
|
3
3
|
* Used for nano app CRUD and discovery endpoints.
|
|
4
4
|
*/
|
|
5
|
+
export declare function setChannel(ch: string): void;
|
|
5
6
|
export declare function callJsonEndpoint(endpoint: string, body?: Record<string, unknown>, apiKey?: string): Promise<unknown>;
|
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
* Used for nano app CRUD and discovery endpoints.
|
|
4
4
|
*/
|
|
5
5
|
import { config } from '../config.js';
|
|
6
|
+
// Channel identifier — overridden by hosted/cloud-run.ts
|
|
7
|
+
let _channel = 'mcp-npm';
|
|
8
|
+
export function setChannel(ch) { _channel = ch; }
|
|
6
9
|
export async function callJsonEndpoint(endpoint, body = {}, apiKey) {
|
|
7
10
|
const url = `${config.cloudFunctionsBase}/${endpoint}`;
|
|
8
11
|
const headers = {
|
|
9
12
|
'Content-Type': 'application/json',
|
|
10
13
|
'Origin': 'https://mcp.superproductmanager.ai',
|
|
14
|
+
'X-SPM-Channel': _channel,
|
|
11
15
|
};
|
|
12
16
|
if (apiKey) {
|
|
13
17
|
headers['X-SPM-API-Key'] = apiKey;
|
|
@@ -13,6 +13,7 @@ declare const ENDPOINTS: {
|
|
|
13
13
|
readonly classifyIntent: "/classifyIntent";
|
|
14
14
|
};
|
|
15
15
|
type EndpointName = keyof typeof ENDPOINTS;
|
|
16
|
+
export declare function setChannel(ch: string): void;
|
|
16
17
|
/**
|
|
17
18
|
* Call an SPM Cloud Function endpoint.
|
|
18
19
|
* Handles SSE stream parsing automatically.
|
|
@@ -14,12 +14,16 @@ const ENDPOINTS = {
|
|
|
14
14
|
extensionReviewAgainAgentV3: '/extensionReviewAgainAgentV3',
|
|
15
15
|
classifyIntent: '/classifyIntent',
|
|
16
16
|
};
|
|
17
|
+
// Channel identifier — shared with cloud-functions.ts
|
|
18
|
+
let _channel = 'mcp-npm';
|
|
19
|
+
export function setChannel(ch) { _channel = ch; }
|
|
17
20
|
function getHeaders(apiKey) {
|
|
18
21
|
const key = apiKey || config.apiKey;
|
|
19
22
|
const headers = {
|
|
20
23
|
'Content-Type': 'application/json',
|
|
21
24
|
'Accept': 'text/event-stream, application/json',
|
|
22
25
|
'Origin': 'https://mcp.superproductmanager.ai',
|
|
26
|
+
'X-SPM-Channel': _channel,
|
|
23
27
|
};
|
|
24
28
|
if (key) {
|
|
25
29
|
headers['X-SPM-API-Key'] = key;
|
package/dist/src/index.js
CHANGED
|
@@ -71,6 +71,8 @@ export function createSpmMcpServer(options) {
|
|
|
71
71
|
question: z.string(),
|
|
72
72
|
answer: z.string(),
|
|
73
73
|
})).optional().describe('Array of previous Q&A pairs from this clarification session. Empty for first question.'),
|
|
74
|
+
user_context: z.string().optional().describe('Context about the PM: role, experience level, company stage, research done, decisions made. Helps generate tailored questions.'),
|
|
75
|
+
about_company: z.string().optional().describe('Context about the company/product: stage, team size, market, existing users, business model.'),
|
|
74
76
|
}, async (input) => {
|
|
75
77
|
try {
|
|
76
78
|
const result = await handleClarify(input, apiKey);
|
|
@@ -95,6 +97,8 @@ export function createSpmMcpServer(options) {
|
|
|
95
97
|
question: z.string(),
|
|
96
98
|
answer: z.string(),
|
|
97
99
|
})).describe('All Q&A pairs accumulated from spm_clarify rounds. The evaluator uses these as evidence.'),
|
|
100
|
+
user_context: z.string().optional().describe('Context about the PM: role, experience level, company stage, research done, decisions made.'),
|
|
101
|
+
about_company: z.string().optional().describe('Context about the company/product: stage, team size, market, existing users, business model.'),
|
|
98
102
|
}, async (input) => {
|
|
99
103
|
try {
|
|
100
104
|
const result = await handleEvaluate(input, apiKey);
|
|
@@ -47,6 +47,14 @@ export declare const clarifyDefinition: {
|
|
|
47
47
|
};
|
|
48
48
|
description: string;
|
|
49
49
|
};
|
|
50
|
+
user_context: {
|
|
51
|
+
type: string;
|
|
52
|
+
description: string;
|
|
53
|
+
};
|
|
54
|
+
about_company: {
|
|
55
|
+
type: string;
|
|
56
|
+
description: string;
|
|
57
|
+
};
|
|
50
58
|
};
|
|
51
59
|
required: string[];
|
|
52
60
|
};
|
|
@@ -61,5 +69,7 @@ export interface ClarifyInput {
|
|
|
61
69
|
question: string;
|
|
62
70
|
answer: string;
|
|
63
71
|
}>;
|
|
72
|
+
user_context?: string;
|
|
73
|
+
about_company?: string;
|
|
64
74
|
}
|
|
65
75
|
export declare function handleClarify(input: ClarifyInput, apiKey?: string): Promise<unknown>;
|
|
@@ -52,12 +52,23 @@ export const clarifyDefinition = {
|
|
|
52
52
|
description: 'Array of previous Q&A pairs from this clarification session. ' +
|
|
53
53
|
'Pass as [{question, answer}, ...]. Empty array for first question.',
|
|
54
54
|
},
|
|
55
|
+
user_context: {
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: 'Context about the PM: their role, experience level, company stage, ' +
|
|
58
|
+
'what research they have done, what decisions they have already made. ' +
|
|
59
|
+
'This helps generate questions tailored to the specific user rather than generic ones.',
|
|
60
|
+
},
|
|
61
|
+
about_company: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
description: 'Context about the company/product: stage, team size, market, ' +
|
|
64
|
+
'existing users, business model. Helps ground questions in reality.',
|
|
65
|
+
},
|
|
55
66
|
},
|
|
56
67
|
required: ['document', 'nano_app_id', 'main_expectation', 'all_sub_expectations', 'target_sub_expectation'],
|
|
57
68
|
},
|
|
58
69
|
};
|
|
59
70
|
export async function handleClarify(input, apiKey) {
|
|
60
|
-
const { document, nano_app_id, main_expectation, all_sub_expectations, target_sub_expectation, previous_answers = [], } = input;
|
|
71
|
+
const { document, nano_app_id, main_expectation, all_sub_expectations, target_sub_expectation, previous_answers = [], user_context = '', about_company = '', } = input;
|
|
61
72
|
if (!document?.trim()) {
|
|
62
73
|
throw new SpmApiError('Document text is required', 'INVALID_INPUT');
|
|
63
74
|
}
|
|
@@ -88,6 +99,8 @@ export async function handleClarify(input, apiKey) {
|
|
|
88
99
|
recent_recommendation: '',
|
|
89
100
|
latest_review: '',
|
|
90
101
|
gap_coverage: '',
|
|
102
|
+
user_context,
|
|
103
|
+
about_company,
|
|
91
104
|
nano_app_id,
|
|
92
105
|
};
|
|
93
106
|
const result = await callClarificationAgent(payload, apiKey);
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { callEndpoint, SpmApiError } from '../client/spm-api.js';
|
|
12
12
|
export async function handleEvaluate(input, apiKey) {
|
|
13
|
-
const { document, nano_app_id, main_expectation, all_sub_expectations, prior_clarifications = [], } = input;
|
|
13
|
+
const { document, nano_app_id, main_expectation, all_sub_expectations, prior_clarifications = [], user_context = '', about_company = '', } = input;
|
|
14
14
|
if (!document?.trim()) {
|
|
15
15
|
throw new SpmApiError('Document text is required', 'INVALID_INPUT');
|
|
16
16
|
}
|
|
@@ -51,6 +51,8 @@ export async function handleEvaluate(input, apiKey) {
|
|
|
51
51
|
all_sub_expectations: parsedSubExps,
|
|
52
52
|
requirement_document: document,
|
|
53
53
|
prior_clarifications: formattedClarifications,
|
|
54
|
+
user_context,
|
|
55
|
+
about_company,
|
|
54
56
|
nano_app_id,
|
|
55
57
|
};
|
|
56
58
|
const result = await callEndpoint('extensionGapEvaluatorV3', payload, apiKey);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spm-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Super Product Manager MCP Server - AI-powered product document analysis for PRDs, roadmaps, and 30 PM document types",
|
|
5
5
|
"author": "Super Product Manager <chiranjeevi.gunturi@superproductmanager.ai>",
|
|
6
6
|
"homepage": "https://superproductmanager.ai",
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
import { config } from '../config.js';
|
|
7
7
|
|
|
8
|
+
// Channel identifier — overridden by hosted/cloud-run.ts
|
|
9
|
+
let _channel = 'mcp-npm';
|
|
10
|
+
export function setChannel(ch: string) { _channel = ch; }
|
|
11
|
+
|
|
8
12
|
export async function callJsonEndpoint(
|
|
9
13
|
endpoint: string,
|
|
10
14
|
body: Record<string, unknown> = {},
|
|
@@ -14,6 +18,7 @@ export async function callJsonEndpoint(
|
|
|
14
18
|
const headers: Record<string, string> = {
|
|
15
19
|
'Content-Type': 'application/json',
|
|
16
20
|
'Origin': 'https://mcp.superproductmanager.ai',
|
|
21
|
+
'X-SPM-Channel': _channel,
|
|
17
22
|
};
|
|
18
23
|
if (apiKey) {
|
|
19
24
|
headers['X-SPM-API-Key'] = apiKey;
|
package/src/client/spm-api.ts
CHANGED
|
@@ -19,12 +19,17 @@ const ENDPOINTS = {
|
|
|
19
19
|
|
|
20
20
|
type EndpointName = keyof typeof ENDPOINTS;
|
|
21
21
|
|
|
22
|
+
// Channel identifier — shared with cloud-functions.ts
|
|
23
|
+
let _channel = 'mcp-npm';
|
|
24
|
+
export function setChannel(ch: string) { _channel = ch; }
|
|
25
|
+
|
|
22
26
|
function getHeaders(apiKey?: string): Record<string, string> {
|
|
23
27
|
const key = apiKey || config.apiKey;
|
|
24
28
|
const headers: Record<string, string> = {
|
|
25
29
|
'Content-Type': 'application/json',
|
|
26
30
|
'Accept': 'text/event-stream, application/json',
|
|
27
31
|
'Origin': 'https://mcp.superproductmanager.ai',
|
|
32
|
+
'X-SPM-Channel': _channel,
|
|
28
33
|
};
|
|
29
34
|
if (key) {
|
|
30
35
|
headers['X-SPM-API-Key'] = key;
|
package/src/index.ts
CHANGED
|
@@ -96,6 +96,12 @@ export function createSpmMcpServer(options?: { apiKey?: string }): McpServer {
|
|
|
96
96
|
})).optional().describe(
|
|
97
97
|
'Array of previous Q&A pairs from this clarification session. Empty for first question.',
|
|
98
98
|
),
|
|
99
|
+
user_context: z.string().optional().describe(
|
|
100
|
+
'Context about the PM: role, experience level, company stage, research done, decisions made. Helps generate tailored questions.',
|
|
101
|
+
),
|
|
102
|
+
about_company: z.string().optional().describe(
|
|
103
|
+
'Context about the company/product: stage, team size, market, existing users, business model.',
|
|
104
|
+
),
|
|
99
105
|
},
|
|
100
106
|
async (input) => {
|
|
101
107
|
try {
|
|
@@ -129,6 +135,12 @@ export function createSpmMcpServer(options?: { apiKey?: string }): McpServer {
|
|
|
129
135
|
})).describe(
|
|
130
136
|
'All Q&A pairs accumulated from spm_clarify rounds. The evaluator uses these as evidence.',
|
|
131
137
|
),
|
|
138
|
+
user_context: z.string().optional().describe(
|
|
139
|
+
'Context about the PM: role, experience level, company stage, research done, decisions made.',
|
|
140
|
+
),
|
|
141
|
+
about_company: z.string().optional().describe(
|
|
142
|
+
'Context about the company/product: stage, team size, market, existing users, business model.',
|
|
143
|
+
),
|
|
132
144
|
},
|
|
133
145
|
async (input) => {
|
|
134
146
|
try {
|
package/src/tools/clarify.ts
CHANGED
|
@@ -58,6 +58,19 @@ export const clarifyDefinition = {
|
|
|
58
58
|
'Array of previous Q&A pairs from this clarification session. ' +
|
|
59
59
|
'Pass as [{question, answer}, ...]. Empty array for first question.',
|
|
60
60
|
},
|
|
61
|
+
user_context: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
description:
|
|
64
|
+
'Context about the PM: their role, experience level, company stage, ' +
|
|
65
|
+
'what research they have done, what decisions they have already made. ' +
|
|
66
|
+
'This helps generate questions tailored to the specific user rather than generic ones.',
|
|
67
|
+
},
|
|
68
|
+
about_company: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
description:
|
|
71
|
+
'Context about the company/product: stage, team size, market, ' +
|
|
72
|
+
'existing users, business model. Helps ground questions in reality.',
|
|
73
|
+
},
|
|
61
74
|
},
|
|
62
75
|
required: ['document', 'nano_app_id', 'main_expectation', 'all_sub_expectations', 'target_sub_expectation'],
|
|
63
76
|
},
|
|
@@ -70,6 +83,8 @@ export interface ClarifyInput {
|
|
|
70
83
|
all_sub_expectations: string;
|
|
71
84
|
target_sub_expectation: string;
|
|
72
85
|
previous_answers?: Array<{ question: string; answer: string }>;
|
|
86
|
+
user_context?: string;
|
|
87
|
+
about_company?: string;
|
|
73
88
|
}
|
|
74
89
|
|
|
75
90
|
export async function handleClarify(input: ClarifyInput, apiKey?: string): Promise<unknown> {
|
|
@@ -80,6 +95,8 @@ export async function handleClarify(input: ClarifyInput, apiKey?: string): Promi
|
|
|
80
95
|
all_sub_expectations,
|
|
81
96
|
target_sub_expectation,
|
|
82
97
|
previous_answers = [],
|
|
98
|
+
user_context = '',
|
|
99
|
+
about_company = '',
|
|
83
100
|
} = input;
|
|
84
101
|
|
|
85
102
|
if (!document?.trim()) {
|
|
@@ -117,6 +134,8 @@ export async function handleClarify(input: ClarifyInput, apiKey?: string): Promi
|
|
|
117
134
|
recent_recommendation: '',
|
|
118
135
|
latest_review: '',
|
|
119
136
|
gap_coverage: '',
|
|
137
|
+
user_context,
|
|
138
|
+
about_company,
|
|
120
139
|
nano_app_id,
|
|
121
140
|
};
|
|
122
141
|
|
package/src/tools/evaluate.ts
CHANGED
|
@@ -17,6 +17,8 @@ export interface EvaluateInput {
|
|
|
17
17
|
main_expectation: string;
|
|
18
18
|
all_sub_expectations: string;
|
|
19
19
|
prior_clarifications: Array<{ question: string; answer: string }>;
|
|
20
|
+
user_context?: string;
|
|
21
|
+
about_company?: string;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
export async function handleEvaluate(input: EvaluateInput, apiKey?: string): Promise<unknown> {
|
|
@@ -26,6 +28,8 @@ export async function handleEvaluate(input: EvaluateInput, apiKey?: string): Pro
|
|
|
26
28
|
main_expectation,
|
|
27
29
|
all_sub_expectations,
|
|
28
30
|
prior_clarifications = [],
|
|
31
|
+
user_context = '',
|
|
32
|
+
about_company = '',
|
|
29
33
|
} = input;
|
|
30
34
|
|
|
31
35
|
if (!document?.trim()) {
|
|
@@ -71,6 +75,8 @@ export async function handleEvaluate(input: EvaluateInput, apiKey?: string): Pro
|
|
|
71
75
|
all_sub_expectations: parsedSubExps,
|
|
72
76
|
requirement_document: document,
|
|
73
77
|
prior_clarifications: formattedClarifications,
|
|
78
|
+
user_context,
|
|
79
|
+
about_company,
|
|
74
80
|
nano_app_id,
|
|
75
81
|
};
|
|
76
82
|
|