spm-mcp 0.3.1 → 0.3.2

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/index.js CHANGED
@@ -20,10 +20,25 @@ import { handleEvaluate } from './tools/evaluate.js';
20
20
  import { handleImprove } from './tools/improve.js';
21
21
  import { handleCreateCustomNanoApp } from './tools/create-custom-nano-app.js';
22
22
  import { SpmApiError } from './client/spm-api.js';
23
+ function logToolCall(tool, input) {
24
+ const summary = {};
25
+ for (const [k, v] of Object.entries(input)) {
26
+ if (typeof v === 'string' && v.length > 100) {
27
+ summary[k] = `[${v.length} chars]`;
28
+ }
29
+ else if (Array.isArray(v)) {
30
+ summary[k] = `[${v.length} items]`;
31
+ }
32
+ else {
33
+ summary[k] = v ?? '(empty)';
34
+ }
35
+ }
36
+ console.log(`[MCP] ${tool}:`, JSON.stringify(summary));
37
+ }
23
38
  export function createSpmMcpServer(options) {
24
39
  const server = new McpServer({
25
40
  name: 'Super Product Manager',
26
- version: '0.1.0',
41
+ version: '0.3.1',
27
42
  });
28
43
  const apiKey = options?.apiKey;
29
44
  // Tool: spm_list_nano_apps
@@ -31,6 +46,7 @@ export function createSpmMcpServer(options) {
31
46
  'Returns template keys, names, descriptions, and categories. ' +
32
47
  'Use this to discover which analysis types are available before calling spm_analyze.', {}, async () => {
33
48
  try {
49
+ logToolCall('spm_list_nano_apps', {});
34
50
  const result = await handleListNanoApps(apiKey);
35
51
  return {
36
52
  content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
@@ -51,6 +67,7 @@ export function createSpmMcpServer(options) {
51
67
  nano_app_id: z.string().describe('The nano app template key (e.g., "prd_critique"). Call spm_list_nano_apps to see available options.'),
52
68
  }, async (input) => {
53
69
  try {
70
+ logToolCall('spm_analyze', input);
54
71
  const result = await handleAnalyze(input, apiKey);
55
72
  return {
56
73
  content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
@@ -82,6 +99,7 @@ export function createSpmMcpServer(options) {
82
99
  about_company: z.string().optional().describe('Context about the company/product: stage, team size, market, existing users, business model.'),
83
100
  }, async (input) => {
84
101
  try {
102
+ logToolCall('spm_clarify', input);
85
103
  const result = await handleClarify(input, apiKey);
86
104
  return {
87
105
  content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
@@ -108,6 +126,7 @@ export function createSpmMcpServer(options) {
108
126
  about_company: z.string().optional().describe('Context about the company/product: stage, team size, market, existing users, business model.'),
109
127
  }, async (input) => {
110
128
  try {
129
+ logToolCall('spm_evaluate', input);
111
130
  const result = await handleEvaluate(input, apiKey);
112
131
  return {
113
132
  content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
@@ -136,6 +155,7 @@ export function createSpmMcpServer(options) {
136
155
  current_content: z.string().optional().describe('The current generated content (live_artifact) to improve upon. Empty for first generation.'),
137
156
  }, async (input) => {
138
157
  try {
158
+ logToolCall('spm_improve', input);
139
159
  const result = await handleImprove(input, apiKey);
140
160
  return {
141
161
  content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
@@ -167,6 +187,7 @@ export function createSpmMcpServer(options) {
167
187
  }).optional().describe('Optional preferences to customize the nano app behavior'),
168
188
  }, async (input) => {
169
189
  try {
190
+ logToolCall('spm_create_custom_nano_app', input);
170
191
  const result = await handleCreateCustomNanoApp(input, apiKey);
171
192
  return {
172
193
  content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
package/dist/src/stdio.js CHANGED
@@ -94,13 +94,12 @@ if (wantsSetup || (isInteractive() && !hasApiKey())) {
94
94
  const ok = await runSetup();
95
95
  process.exit(ok ? 0 : 1);
96
96
  }
97
- else if (!hasApiKey() && isInteractive()) {
98
- // No key and interactive — guide the user
99
- process.stderr.write('\n No SPM_API_KEY found. Run: npx spm-mcp --setup\n\n');
100
- process.exit(1);
101
- }
102
97
  else {
103
98
  // MCP server mode (non-interactive, started by AI tool)
99
+ if (!hasApiKey()) {
100
+ process.stderr.write('[spm-mcp] Warning: No API key found. Tool calls will fail with 401.\n' +
101
+ ' Fix: run "npx spm-mcp --setup" or set SPM_API_KEY env var.\n');
102
+ }
104
103
  const server = createSpmMcpServer({ apiKey: config.apiKey });
105
104
  const transport = new StdioServerTransport();
106
105
  await server.connect(transport);
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "spm-mcp",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
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",
7
7
  "type": "module",
8
- "main": "dist/index.js",
8
+ "main": "dist/src/index.js",
9
9
  "bin": {
10
10
  "spm-mcp": "dist/src/stdio.js"
11
11
  },
package/src/index.ts CHANGED
@@ -22,10 +22,24 @@ import { handleImprove } from './tools/improve.js';
22
22
  import { handleCreateCustomNanoApp } from './tools/create-custom-nano-app.js';
23
23
  import { SpmApiError } from './client/spm-api.js';
24
24
 
25
+ function logToolCall(tool: string, input: Record<string, unknown>) {
26
+ const summary: Record<string, unknown> = {};
27
+ for (const [k, v] of Object.entries(input)) {
28
+ if (typeof v === 'string' && v.length > 100) {
29
+ summary[k] = `[${v.length} chars]`;
30
+ } else if (Array.isArray(v)) {
31
+ summary[k] = `[${v.length} items]`;
32
+ } else {
33
+ summary[k] = v ?? '(empty)';
34
+ }
35
+ }
36
+ console.log(`[MCP] ${tool}:`, JSON.stringify(summary));
37
+ }
38
+
25
39
  export function createSpmMcpServer(options?: { apiKey?: string }): McpServer {
26
40
  const server = new McpServer({
27
41
  name: 'Super Product Manager',
28
- version: '0.1.0',
42
+ version: '0.3.1',
29
43
  });
30
44
 
31
45
  const apiKey = options?.apiKey;
@@ -39,6 +53,7 @@ export function createSpmMcpServer(options?: { apiKey?: string }): McpServer {
39
53
  {},
40
54
  async () => {
41
55
  try {
56
+ logToolCall('spm_list_nano_apps', {});
42
57
  const result = await handleListNanoApps(apiKey);
43
58
  return {
44
59
  content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
@@ -66,6 +81,7 @@ export function createSpmMcpServer(options?: { apiKey?: string }): McpServer {
66
81
  },
67
82
  async (input) => {
68
83
  try {
84
+ logToolCall('spm_analyze', input);
69
85
  const result = await handleAnalyze(input, apiKey);
70
86
  return {
71
87
  content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
@@ -112,6 +128,7 @@ export function createSpmMcpServer(options?: { apiKey?: string }): McpServer {
112
128
  },
113
129
  async (input) => {
114
130
  try {
131
+ logToolCall('spm_clarify', input);
115
132
  const result = await handleClarify(input, apiKey);
116
133
  return {
117
134
  content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
@@ -151,6 +168,7 @@ export function createSpmMcpServer(options?: { apiKey?: string }): McpServer {
151
168
  },
152
169
  async (input) => {
153
170
  try {
171
+ logToolCall('spm_evaluate', input);
154
172
  const result = await handleEvaluate(input, apiKey);
155
173
  return {
156
174
  content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
@@ -190,6 +208,7 @@ export function createSpmMcpServer(options?: { apiKey?: string }): McpServer {
190
208
  },
191
209
  async (input) => {
192
210
  try {
211
+ logToolCall('spm_improve', input);
193
212
  const result = await handleImprove(input, apiKey);
194
213
  return {
195
214
  content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
@@ -230,6 +249,7 @@ export function createSpmMcpServer(options?: { apiKey?: string }): McpServer {
230
249
  },
231
250
  async (input) => {
232
251
  try {
252
+ logToolCall('spm_create_custom_nano_app', input);
233
253
  const result = await handleCreateCustomNanoApp(input, apiKey);
234
254
  return {
235
255
  content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
package/src/stdio.ts CHANGED
@@ -107,12 +107,14 @@ if (wantsSetup || (isInteractive() && !hasApiKey())) {
107
107
  // Interactive setup mode
108
108
  const ok = await runSetup();
109
109
  process.exit(ok ? 0 : 1);
110
- } else if (!hasApiKey() && isInteractive()) {
111
- // No key and interactive — guide the user
112
- process.stderr.write('\n No SPM_API_KEY found. Run: npx spm-mcp --setup\n\n');
113
- process.exit(1);
114
110
  } else {
115
111
  // MCP server mode (non-interactive, started by AI tool)
112
+ if (!hasApiKey()) {
113
+ process.stderr.write(
114
+ '[spm-mcp] Warning: No API key found. Tool calls will fail with 401.\n' +
115
+ ' Fix: run "npx spm-mcp --setup" or set SPM_API_KEY env var.\n'
116
+ );
117
+ }
116
118
  const server = createSpmMcpServer({ apiKey: config.apiKey });
117
119
  const transport = new StdioServerTransport();
118
120
  await server.connect(transport);
package/spm-mcp-0.1.0.tgz DELETED
Binary file