@commonlyai/mcp 0.3.28 → 0.3.30

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@commonlyai/mcp",
3
3
  "mcpName": "io.github.Team-Commonly/commonly",
4
- "version": "0.3.28",
4
+ "version": "0.3.30",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
package/src/client.js CHANGED
@@ -132,7 +132,9 @@ export const loadConfig = (env = process.env, opts = {}) => {
132
132
  * `query` is a flat object — all values stringified and URL-encoded.
133
133
  * `_fetchImpl` is a test seam (same convention as `cli/src/lib/adapters/*.js`).
134
134
  */
135
- export const request = async (config, { method, path, query, body, _fetchImpl = fetch } = {}) => {
135
+ export const request = async (config, {
136
+ method, path, query, body, signal, _fetchImpl = fetch,
137
+ } = {}) => {
136
138
  let url = `${config.baseUrl}${path}`;
137
139
  if (query) {
138
140
  const params = new URLSearchParams();
@@ -154,6 +156,7 @@ export const request = async (config, { method, path, query, body, _fetchImpl =
154
156
  method,
155
157
  headers,
156
158
  body: body !== undefined ? JSON.stringify(body) : undefined,
159
+ signal,
157
160
  });
158
161
 
159
162
  // Read body once. Prefer JSON; fall back to text for non-JSON error pages
package/src/index.js CHANGED
@@ -25,11 +25,12 @@ import {
25
25
  CallToolRequestSchema,
26
26
  } from '@modelcontextprotocol/sdk/types.js';
27
27
 
28
- import { loadConfig } from './client.js';
28
+ import { loadConfig, request } from './client.js';
29
29
  import { buildTools } from './tools.js';
30
30
  import { PACKAGE_VERSION } from './version.js';
31
31
 
32
32
  const PACKAGE_NAME = '@commonlyai/mcp';
33
+ const CHECK_IN_WAIT_MS = 1000;
33
34
 
34
35
  const main = async () => {
35
36
  // Fail fast on missing env. The MCP host (codex/claude) will surface this
@@ -64,8 +65,34 @@ const main = async () => {
64
65
  return tool.call(req.params.arguments || {});
65
66
  });
66
67
 
68
+ // One authenticated call at start (TASK-345). Until a tool ran, nothing
69
+ // reached Commonly, so a working install and a broken one looked the same and
70
+ // the agent never showed as connected. A failure goes to stderr and never
71
+ // ends the server: stdout belongs to the MCP transport.
72
+ // Bounded, so a server that never answers cannot keep the process alive
73
+ // after the host has gone. Started before the transport, so it is already
74
+ // on its way when the client's initialize arrives.
75
+ const checkIn = request(config, {
76
+ method: 'GET', path: '/api/agents/runtime/installations', signal: AbortSignal.timeout(10000),
77
+ }).catch((e) => {
78
+ // The status says which kind of failure this is; see docs/MCP_INTEGRATION.md.
79
+ const status = e.status ? `HTTP ${e.status}: ` : '';
80
+ process.stderr.write(`[commonly-mcp] could not reach Commonly at start: ${status}${e.message}\n`);
81
+ });
82
+
67
83
  const transport = new StdioServerTransport();
68
84
  await server.connect(transport);
85
+
86
+ // `claude mcp list` initializes, prints "Connected" and closes the server,
87
+ // which once came before the check-in landed (Growth's walk, 11-04): the
88
+ // person who added it looked like one who never had. So initialize waits for
89
+ // the check-in, for at most a second, so a slow API never holds startup.
90
+ const deliver = transport.onmessage;
91
+ transport.onmessage = (message, extra) => {
92
+ if (message?.method !== 'initialize') return deliver(message, extra);
93
+ const cap = new Promise((resolve) => { setTimeout(resolve, CHECK_IN_WAIT_MS).unref(); });
94
+ return Promise.race([checkIn, cap]).then(() => deliver(message, extra));
95
+ };
69
96
  };
70
97
 
71
98
  main().catch((e) => {