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.
@@ -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);
@@ -17,5 +17,7 @@ export interface EvaluateInput {
17
17
  question: string;
18
18
  answer: string;
19
19
  }>;
20
+ user_context?: string;
21
+ about_company?: string;
20
22
  }
21
23
  export declare function handleEvaluate(input: EvaluateInput, apiKey?: string): Promise<unknown>;
@@ -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.2.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;
@@ -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 {
@@ -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
 
@@ -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