@findtime/mcp-server 3.25.7 → 3.25.9
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 +1 -1
- package/server.js +104 -3
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -17,8 +17,19 @@ const SUPPORTED_PROTOCOL_VERSIONS = new Set([
|
|
|
17
17
|
|
|
18
18
|
loadEnvironmentFiles();
|
|
19
19
|
|
|
20
|
-
const
|
|
20
|
+
const LOCAL_PACKAGE_METADATA = safeReadJson(LOCAL_PACKAGE_PATH) || null;
|
|
21
|
+
const REPO_PACKAGE_METADATA = safeReadJson(REPO_PACKAGE_PATH) || null;
|
|
22
|
+
const PACKAGE_METADATA = LOCAL_PACKAGE_METADATA || REPO_PACKAGE_METADATA || {};
|
|
21
23
|
const SERVER_VERSION = PACKAGE_METADATA.version || '0.0.0';
|
|
24
|
+
const MCP_PACKAGE_NAME = PACKAGE_METADATA.name || '@findtime/mcp-server';
|
|
25
|
+
const MCP_NPM_REGISTRY_LATEST_URL = `https://registry.npmjs.org/${encodeURIComponent(MCP_PACKAGE_NAME)}/latest`;
|
|
26
|
+
const MCP_NPM_URL = `https://www.npmjs.com/package/${MCP_PACKAGE_NAME}`;
|
|
27
|
+
const MCP_REGISTRY_URL = 'https://registry.modelcontextprotocol.io/?q=io.github.hkchao%2Ffindtime-mcp-server';
|
|
28
|
+
const MCP_INSTALL_MODE = determineInstallMode({
|
|
29
|
+
packageRoot: PACKAGE_ROOT,
|
|
30
|
+
localPackageMetadata: LOCAL_PACKAGE_METADATA,
|
|
31
|
+
repoPackageMetadata: REPO_PACKAGE_METADATA
|
|
32
|
+
});
|
|
22
33
|
const DEFAULT_API_BASE_URL = firstNonEmpty(
|
|
23
34
|
process.env.TIME_API_BASE_URL,
|
|
24
35
|
process.env.FINDTIME_TIME_API_BASE_URL
|
|
@@ -35,7 +46,7 @@ const TIMEZONE_HELPERS_PATH = path.join(REPO_ROOT, 'slack-bot', 'timezone-helper
|
|
|
35
46
|
const TOOL_DEFINITIONS = [
|
|
36
47
|
{
|
|
37
48
|
name: 'get_api_diagnostics',
|
|
38
|
-
description: 'Return MCP and findtime Time API diagnostics, including
|
|
49
|
+
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
50
|
inputSchema: {
|
|
40
51
|
type: 'object',
|
|
41
52
|
properties: {},
|
|
@@ -818,6 +829,61 @@ function createFindtimeMcpServer(options = {}) {
|
|
|
818
829
|
}
|
|
819
830
|
}
|
|
820
831
|
|
|
832
|
+
async function fetchLatestMcpVersion() {
|
|
833
|
+
const controller = new AbortController();
|
|
834
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
835
|
+
|
|
836
|
+
try {
|
|
837
|
+
const response = await fetchImpl(MCP_NPM_REGISTRY_LATEST_URL, {
|
|
838
|
+
method: 'GET',
|
|
839
|
+
headers: {
|
|
840
|
+
Accept: 'application/json'
|
|
841
|
+
},
|
|
842
|
+
signal: controller.signal
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
const rawBody = await response.text();
|
|
846
|
+
const parsedBody = tryParseJson(rawBody);
|
|
847
|
+
|
|
848
|
+
if (!response.ok) {
|
|
849
|
+
return {
|
|
850
|
+
ok: false,
|
|
851
|
+
status: response.status,
|
|
852
|
+
latestVersion: null
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
const latestVersion = parsedBody && typeof parsedBody.version === 'string'
|
|
857
|
+
? parsedBody.version.trim()
|
|
858
|
+
: '';
|
|
859
|
+
|
|
860
|
+
if (!latestVersion) {
|
|
861
|
+
return {
|
|
862
|
+
ok: false,
|
|
863
|
+
status: response.status,
|
|
864
|
+
latestVersion: null
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
return {
|
|
869
|
+
ok: true,
|
|
870
|
+
status: response.status,
|
|
871
|
+
latestVersion
|
|
872
|
+
};
|
|
873
|
+
} catch (error) {
|
|
874
|
+
return {
|
|
875
|
+
ok: false,
|
|
876
|
+
status: null,
|
|
877
|
+
latestVersion: null,
|
|
878
|
+
networkError: error && error.name === 'AbortError'
|
|
879
|
+
? `Request timed out after ${timeoutMs}ms`
|
|
880
|
+
: String(error && error.message ? error.message : error)
|
|
881
|
+
};
|
|
882
|
+
} finally {
|
|
883
|
+
clearTimeout(timeout);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
|
|
821
887
|
async function callTool(name, args = {}) {
|
|
822
888
|
const tool = TOOL_DEFINITIONS_BY_NAME.get(name);
|
|
823
889
|
if (!tool) {
|
|
@@ -826,13 +892,28 @@ function createFindtimeMcpServer(options = {}) {
|
|
|
826
892
|
|
|
827
893
|
if (name === 'get_api_diagnostics') {
|
|
828
894
|
const request = tool.buildRequest(args || {});
|
|
829
|
-
const apiResponse = await
|
|
895
|
+
const [apiResponse, latestMcpVersionCheck] = await Promise.all([
|
|
896
|
+
fetchJson(name, request),
|
|
897
|
+
fetchLatestMcpVersion()
|
|
898
|
+
]);
|
|
830
899
|
const checkedAt = new Date().toISOString();
|
|
900
|
+
const latestVersion = latestMcpVersionCheck.latestVersion || null;
|
|
831
901
|
const diagnostics = {
|
|
832
902
|
ok: apiResponse.ok,
|
|
833
903
|
tool: name,
|
|
834
904
|
checkedAt,
|
|
835
905
|
mcpVersion: SERVER_VERSION,
|
|
906
|
+
mcpLatestVersion: latestVersion,
|
|
907
|
+
mcpUpToDate: latestVersion ? latestVersion === SERVER_VERSION : null,
|
|
908
|
+
mcpLatestVersionCheck: latestVersion ? 'ok' : 'failed',
|
|
909
|
+
mcpLatestVersionSource: latestVersion ? 'npm' : 'unavailable',
|
|
910
|
+
mcpLatestVersionHint: latestVersion
|
|
911
|
+
? null
|
|
912
|
+
: 'Could not verify the latest published MCP version automatically. Check the npm package page or Official MCP Registry listing directly.',
|
|
913
|
+
mcpInstallMode: MCP_INSTALL_MODE,
|
|
914
|
+
mcpExecutablePath: path.join(PACKAGE_ROOT, 'server.js'),
|
|
915
|
+
mcpRegistryUrl: MCP_REGISTRY_URL,
|
|
916
|
+
mcpNpmUrl: MCP_NPM_URL,
|
|
836
917
|
apiBaseUrl,
|
|
837
918
|
apiConfigured: Boolean(apiBaseUrl),
|
|
838
919
|
apiAuthConfigured: Boolean(typeof apiKey === 'string' && apiKey.trim()),
|
|
@@ -854,6 +935,10 @@ function createFindtimeMcpServer(options = {}) {
|
|
|
854
935
|
}
|
|
855
936
|
}
|
|
856
937
|
|
|
938
|
+
if (!latestVersion && latestMcpVersionCheck.networkError) {
|
|
939
|
+
diagnostics.mcpLatestVersionNetworkError = latestMcpVersionCheck.networkError;
|
|
940
|
+
}
|
|
941
|
+
|
|
857
942
|
return buildToolSuccessResult(name, diagnostics, {
|
|
858
943
|
endpoint: request.path,
|
|
859
944
|
url: apiResponse.url
|
|
@@ -1005,6 +1090,22 @@ function tryParseJson(value) {
|
|
|
1005
1090
|
}
|
|
1006
1091
|
}
|
|
1007
1092
|
|
|
1093
|
+
function determineInstallMode({ packageRoot, localPackageMetadata, repoPackageMetadata }) {
|
|
1094
|
+
if (repoPackageMetadata && repoPackageMetadata.name === 'world-time-ai') {
|
|
1095
|
+
return 'repo_checkout';
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
if (localPackageMetadata && localPackageMetadata.name === '@findtime/mcp-server') {
|
|
1099
|
+
return 'npm_package';
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
if (typeof packageRoot === 'string' && packageRoot.includes(`${path.sep}world-time-ai${path.sep}services${path.sep}mcp-server`)) {
|
|
1103
|
+
return 'repo_checkout';
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
return 'package_install';
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1008
1109
|
function startStdioServer(options = {}) {
|
|
1009
1110
|
const server = createFindtimeMcpServer(options);
|
|
1010
1111
|
const messageBuffer = new ContentLengthMessageBuffer();
|