@findtime/mcp-server 3.25.7 → 3.25.8

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +78 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@findtime/mcp-server",
3
- "version": "3.25.7",
3
+ "version": "3.25.8",
4
4
  "mcpName": "io.github.hkchao/findtime-mcp-server",
5
5
  "description": "Production-parity MCP server for the findtime.io Time API",
6
6
  "bin": {
package/server.js CHANGED
@@ -19,6 +19,10 @@ loadEnvironmentFiles();
19
19
 
20
20
  const PACKAGE_METADATA = safeReadJson(LOCAL_PACKAGE_PATH) || safeReadJson(REPO_PACKAGE_PATH) || {};
21
21
  const SERVER_VERSION = PACKAGE_METADATA.version || '0.0.0';
22
+ const MCP_PACKAGE_NAME = PACKAGE_METADATA.name || '@findtime/mcp-server';
23
+ const MCP_NPM_REGISTRY_LATEST_URL = `https://registry.npmjs.org/${encodeURIComponent(MCP_PACKAGE_NAME)}/latest`;
24
+ const MCP_NPM_URL = `https://www.npmjs.com/package/${MCP_PACKAGE_NAME}`;
25
+ const MCP_REGISTRY_URL = 'https://registry.modelcontextprotocol.io/?q=io.github.hkchao%2Ffindtime-mcp-server';
22
26
  const DEFAULT_API_BASE_URL = firstNonEmpty(
23
27
  process.env.TIME_API_BASE_URL,
24
28
  process.env.FINDTIME_TIME_API_BASE_URL
@@ -35,7 +39,7 @@ const TIMEZONE_HELPERS_PATH = path.join(REPO_ROOT, 'slack-bot', 'timezone-helper
35
39
  const TOOL_DEFINITIONS = [
36
40
  {
37
41
  name: 'get_api_diagnostics',
38
- description: 'Return MCP and findtime Time API diagnostics, including package version, API base URL, auth configuration, and a live health check.',
42
+ description: 'Return MCP and findtime Time API diagnostics, including the running MCP version, latest published MCP version, API base URL, auth configuration, and a live health check.',
39
43
  inputSchema: {
40
44
  type: 'object',
41
45
  properties: {},
@@ -818,6 +822,61 @@ function createFindtimeMcpServer(options = {}) {
818
822
  }
819
823
  }
820
824
 
825
+ async function fetchLatestMcpVersion() {
826
+ const controller = new AbortController();
827
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
828
+
829
+ try {
830
+ const response = await fetchImpl(MCP_NPM_REGISTRY_LATEST_URL, {
831
+ method: 'GET',
832
+ headers: {
833
+ Accept: 'application/json'
834
+ },
835
+ signal: controller.signal
836
+ });
837
+
838
+ const rawBody = await response.text();
839
+ const parsedBody = tryParseJson(rawBody);
840
+
841
+ if (!response.ok) {
842
+ return {
843
+ ok: false,
844
+ status: response.status,
845
+ latestVersion: null
846
+ };
847
+ }
848
+
849
+ const latestVersion = parsedBody && typeof parsedBody.version === 'string'
850
+ ? parsedBody.version.trim()
851
+ : '';
852
+
853
+ if (!latestVersion) {
854
+ return {
855
+ ok: false,
856
+ status: response.status,
857
+ latestVersion: null
858
+ };
859
+ }
860
+
861
+ return {
862
+ ok: true,
863
+ status: response.status,
864
+ latestVersion
865
+ };
866
+ } catch (error) {
867
+ return {
868
+ ok: false,
869
+ status: null,
870
+ latestVersion: null,
871
+ networkError: error && error.name === 'AbortError'
872
+ ? `Request timed out after ${timeoutMs}ms`
873
+ : String(error && error.message ? error.message : error)
874
+ };
875
+ } finally {
876
+ clearTimeout(timeout);
877
+ }
878
+ }
879
+
821
880
  async function callTool(name, args = {}) {
822
881
  const tool = TOOL_DEFINITIONS_BY_NAME.get(name);
823
882
  if (!tool) {
@@ -826,13 +885,26 @@ function createFindtimeMcpServer(options = {}) {
826
885
 
827
886
  if (name === 'get_api_diagnostics') {
828
887
  const request = tool.buildRequest(args || {});
829
- const apiResponse = await fetchJson(name, request);
888
+ const [apiResponse, latestMcpVersionCheck] = await Promise.all([
889
+ fetchJson(name, request),
890
+ fetchLatestMcpVersion()
891
+ ]);
830
892
  const checkedAt = new Date().toISOString();
893
+ const latestVersion = latestMcpVersionCheck.latestVersion || null;
831
894
  const diagnostics = {
832
895
  ok: apiResponse.ok,
833
896
  tool: name,
834
897
  checkedAt,
835
898
  mcpVersion: SERVER_VERSION,
899
+ mcpLatestVersion: latestVersion,
900
+ mcpUpToDate: latestVersion ? latestVersion === SERVER_VERSION : null,
901
+ mcpLatestVersionCheck: latestVersion ? 'ok' : 'failed',
902
+ mcpLatestVersionSource: latestVersion ? 'npm' : 'unavailable',
903
+ mcpLatestVersionHint: latestVersion
904
+ ? null
905
+ : 'Could not verify the latest published MCP version automatically. Check the npm package page or Official MCP Registry listing directly.',
906
+ mcpRegistryUrl: MCP_REGISTRY_URL,
907
+ mcpNpmUrl: MCP_NPM_URL,
836
908
  apiBaseUrl,
837
909
  apiConfigured: Boolean(apiBaseUrl),
838
910
  apiAuthConfigured: Boolean(typeof apiKey === 'string' && apiKey.trim()),
@@ -854,6 +926,10 @@ function createFindtimeMcpServer(options = {}) {
854
926
  }
855
927
  }
856
928
 
929
+ if (!latestVersion && latestMcpVersionCheck.networkError) {
930
+ diagnostics.mcpLatestVersionNetworkError = latestMcpVersionCheck.networkError;
931
+ }
932
+
857
933
  return buildToolSuccessResult(name, diagnostics, {
858
934
  endpoint: request.path,
859
935
  url: apiResponse.url