@expandai/mcp-server 0.1.1 → 0.1.3

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/main.cjs CHANGED
@@ -39,7 +39,7 @@ var S__namespace = /*#__PURE__*/_interopNamespace(S);
39
39
 
40
40
  // package.json
41
41
  var package_default = {
42
- version: "0.1.1"};
42
+ version: "0.1.3"};
43
43
  var ExpandDocs = ai.McpServer.resource({
44
44
  uri: "expand://about",
45
45
  name: "About expand.ai",
@@ -698,6 +698,7 @@ var ExpandClient = class extends effect.Effect.Service()("ExpandClient", {
698
698
  scoped: effect.Effect.gen(function* () {
699
699
  const config = yield* ExpandConfig;
700
700
  const httpClient = yield* platform.HttpClient.HttpClient;
701
+ yield* effect.Effect.logInfo(`ExpandClient connected to ${config.baseUrl}`);
701
702
  return make(httpClient, {
702
703
  transformClient: (client) => effect.Effect.succeed(
703
704
  client.pipe(
@@ -765,6 +766,8 @@ var Fetch = class extends effect.Effect.Service()("Fetch", {
765
766
  scoped: effect.Effect.gen(function* () {
766
767
  const client = yield* ExpandClient;
767
768
  const fetch = effect.Effect.fn("Fetch.fetch")(function* ({ url, format, includeMeta }) {
769
+ const formatLabel = format instanceof SnippetsFormat ? "snippets" : format;
770
+ yield* effect.Effect.logDebug(`Fetching: ${url}`).pipe(effect.Effect.annotateLogs({ format: formatLabel, includeMeta }));
768
771
  const result = yield* client.fetch({
769
772
  url,
770
773
  select: {
@@ -776,6 +779,7 @@ var Fetch = class extends effect.Effect.Service()("Fetch", {
776
779
  }
777
780
  });
778
781
  const content = result.data.markdown ?? result.data.html ?? result.data.summary ?? result.data.snippets?.map((snippet) => `${snippet.text} (Score: ${snippet.score})`).join("\n") ?? "";
782
+ yield* effect.Effect.logDebug(`\u{1F4E4} Fetched successfully: ${result.data.response.url}`);
779
783
  return new FetchResult2({
780
784
  content,
781
785
  url: result.data.response.url,
@@ -787,28 +791,65 @@ var Fetch = class extends effect.Effect.Service()("Fetch", {
787
791
  }) {
788
792
  };
789
793
 
790
- // src/tools/index.ts
794
+ // src/Toolkit.ts
791
795
  var toolkit = ai.Toolkit.make(FetchTool);
792
796
  var ToolkitLayer = toolkit.toLayer(
793
797
  effect.Effect.gen(function* () {
798
+ yield* effect.Effect.logInfo("Registering tools: fetch");
794
799
  const fetchService = yield* Fetch;
795
800
  return toolkit.of({
796
801
  fetch: fetchService.fetch
797
802
  });
798
803
  })
799
804
  ).pipe(effect.Layer.provide(Fetch.Default), effect.Layer.provide(ExpandClient.Default), effect.Layer.provide(platformNode.NodeHttpClient.layerUndici));
800
- var ExpandTools = ai.McpServer.toolkit(toolkit).pipe(effect.Layer.provide(ToolkitLayer));
805
+ var ExpandToolKit = ai.McpServer.toolkit(toolkit).pipe(effect.Layer.provide(ToolkitLayer));
806
+
807
+ // src/Server.ts
808
+ var ServerInfo = {
809
+ name: "expandai-mcp-server",
810
+ version: package_default.version
811
+ };
812
+ var makeServerLayer = (options = {}) => options.includeDocs ? effect.Layer.mergeAll(ExpandToolKit, ExpandDocs) : ExpandToolKit;
801
813
 
802
814
  // src/main.ts
803
- var enableDocs = effect.Config.withDefault(effect.Config.boolean("EXPAND_ENABLE_DOCS"), () => false);
815
+ var enableDocs = effect.Config.withDefault(effect.Config.boolean("EXPAND_ENABLE_DOCS"), false);
816
+ var logLevelConfig = effect.Config.withDefault(
817
+ effect.Config.literal("debug", "info", "warning", "error", "none")("LOG_LEVEL"),
818
+ "info"
819
+ );
820
+ var logLevelMap = {
821
+ debug: effect.LogLevel.Debug,
822
+ info: effect.LogLevel.Info,
823
+ warning: effect.LogLevel.Warning,
824
+ error: effect.LogLevel.Error,
825
+ none: effect.LogLevel.None
826
+ };
827
+ var startupBanner = `
828
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
829
+ \u2551 \u2551
830
+ \u2551 \u{1F310} expand.ai MCP Server \u2551
831
+ \u2551 \u2551
832
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`;
804
833
  var program = effect.Effect.gen(function* () {
805
834
  const docsEnabled = yield* enableDocs;
806
- const layers = docsEnabled ? effect.Layer.mergeAll(ExpandTools, ExpandDocs) : ExpandTools;
807
- yield* ai.McpServer.layerStdio({
808
- name: "expandai-mcp-server",
809
- version: package_default.version,
835
+ const logLevel = yield* logLevelConfig;
836
+ yield* effect.Effect.logInfo(startupBanner);
837
+ yield* effect.Effect.logInfo(`Starting v${ServerInfo.version}`);
838
+ yield* effect.Effect.logInfo(`Documentation resources: ${docsEnabled ? "enabled" : "disabled"}`);
839
+ const McpLayer = ai.McpServer.layerStdio({
840
+ ...ServerInfo,
810
841
  stdin: platformNode.NodeStream.stdin,
811
842
  stdout: platformNode.NodeSink.stdout
812
- }).pipe(effect.Layer.provide(layers), effect.Layer.provide(effect.Logger.minimumLogLevel(effect.LogLevel.None)), effect.Layer.launch);
843
+ }).pipe(effect.Layer.provide(makeServerLayer({ includeDocs: docsEnabled })));
844
+ const LifecycleLayer = effect.Layer.scopedDiscard(
845
+ effect.Effect.acquireRelease(
846
+ effect.Effect.logInfo("Server ready and listening on stdio"),
847
+ () => effect.Effect.logInfo("Server shutting down gracefully...")
848
+ )
849
+ );
850
+ yield* effect.Layer.merge(McpLayer, LifecycleLayer).pipe(
851
+ effect.Layer.provide(effect.Logger.minimumLogLevel(logLevelMap[logLevel])),
852
+ effect.Layer.launch
853
+ );
813
854
  });
814
855
  program.pipe(platformNode.NodeRuntime.runMain);
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/main.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/main.js ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ import { ServerInfo, makeServerLayer } from './chunk-7ECG3QBA.js';
3
+ import { McpServer } from '@effect/ai';
4
+ import { NodeSink, NodeStream, NodeRuntime } from '@effect/platform-node';
5
+ import { Config, Effect, Layer, Logger, LogLevel } from 'effect';
6
+
7
+ var enableDocs = Config.withDefault(Config.boolean("EXPAND_ENABLE_DOCS"), false);
8
+ var logLevelConfig = Config.withDefault(
9
+ Config.literal("debug", "info", "warning", "error", "none")("LOG_LEVEL"),
10
+ "info"
11
+ );
12
+ var logLevelMap = {
13
+ debug: LogLevel.Debug,
14
+ info: LogLevel.Info,
15
+ warning: LogLevel.Warning,
16
+ error: LogLevel.Error,
17
+ none: LogLevel.None
18
+ };
19
+ var startupBanner = `
20
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
21
+ \u2551 \u2551
22
+ \u2551 \u{1F310} expand.ai MCP Server \u2551
23
+ \u2551 \u2551
24
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`;
25
+ var program = Effect.gen(function* () {
26
+ const docsEnabled = yield* enableDocs;
27
+ const logLevel = yield* logLevelConfig;
28
+ yield* Effect.logInfo(startupBanner);
29
+ yield* Effect.logInfo(`Starting v${ServerInfo.version}`);
30
+ yield* Effect.logInfo(`Documentation resources: ${docsEnabled ? "enabled" : "disabled"}`);
31
+ const McpLayer = McpServer.layerStdio({
32
+ ...ServerInfo,
33
+ stdin: NodeStream.stdin,
34
+ stdout: NodeSink.stdout
35
+ }).pipe(Layer.provide(makeServerLayer({ includeDocs: docsEnabled })));
36
+ const LifecycleLayer = Layer.scopedDiscard(
37
+ Effect.acquireRelease(
38
+ Effect.logInfo("Server ready and listening on stdio"),
39
+ () => Effect.logInfo("Server shutting down gracefully...")
40
+ )
41
+ );
42
+ yield* Layer.merge(McpLayer, LifecycleLayer).pipe(
43
+ Layer.provide(Logger.minimumLogLevel(logLevelMap[logLevel])),
44
+ Layer.launch
45
+ );
46
+ });
47
+ program.pipe(NodeRuntime.runMain);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expandai/mcp-server",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "MCP server for expand.ai - Give AI agents access to the web",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -9,6 +9,14 @@
9
9
  "bin": {
10
10
  "expandai-mcp-server": "./dist/main.cjs"
11
11
  },
12
+ "exports": {
13
+ ".": "./dist/main.cjs",
14
+ "./Server": {
15
+ "types": "./dist/Server.d.ts",
16
+ "import": "./dist/Server.js",
17
+ "require": "./dist/Server.cjs"
18
+ }
19
+ },
12
20
  "files": [
13
21
  "dist",
14
22
  "src",
@@ -17,10 +25,13 @@
17
25
  ],
18
26
  "repository": {
19
27
  "type": "git",
20
- "url": "https://github.com/expandai/expandai-mcp-server.git"
28
+ "url": "git+https://github.com/expandai/expandai-mcp-server.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/expandai/expandai-mcp-server/issues"
21
32
  },
22
33
  "homepage": "https://expand.ai",
23
- "author": "expand.ai",
34
+ "author": "expand.ai <support@expand.ai>",
24
35
  "license": "Apache-2.0",
25
36
  "keywords": [
26
37
  "mcp",
@@ -1,6 +1,6 @@
1
1
  import { HttpClient, HttpClientRequest } from '@effect/platform'
2
2
  import { Config, Effect, Redacted } from 'effect'
3
- import * as GeneratedClient from './generated/ExpandClient.js'
3
+ import * as GeneratedClient from './Generated.js'
4
4
 
5
5
  export const ExpandConfig = Config.all({
6
6
  apiKey: Config.redacted('EXPAND_API_KEY'),
@@ -13,6 +13,8 @@ export class ExpandClient extends Effect.Service<ExpandClient>()('ExpandClient',
13
13
  const config = yield* ExpandConfig
14
14
  const httpClient = yield* HttpClient.HttpClient
15
15
 
16
+ yield* Effect.logInfo(`ExpandClient connected to ${config.baseUrl}`)
17
+
16
18
  return GeneratedClient.make(httpClient, {
17
19
  transformClient: (client) =>
18
20
  Effect.succeed(
@@ -1,7 +1,7 @@
1
1
  import { Tool } from '@effect/ai'
2
2
  import { Effect, Schema } from 'effect'
3
- import { ExpandClient } from '../ExpandClient.js'
4
- import { PageMeta } from '../generated/ExpandClient.js'
3
+ import { ExpandClient } from './ExpandClient.js'
4
+ import { PageMeta } from './Generated.js'
5
5
 
6
6
  export class SnippetsFormat extends Schema.Class<SnippetsFormat>('SnippetsFormat')({
7
7
  query: Schema.String.annotations({
@@ -64,6 +64,9 @@ export class Fetch extends Effect.Service<Fetch>()('Fetch', {
64
64
  const client = yield* ExpandClient
65
65
 
66
66
  const fetch = Effect.fn('Fetch.fetch')(function* ({ url, format, includeMeta }: FetchParams) {
67
+ const formatLabel = format instanceof SnippetsFormat ? 'snippets' : format
68
+ yield* Effect.logDebug(`Fetching: ${url}`).pipe(Effect.annotateLogs({ format: formatLabel, includeMeta }))
69
+
67
70
  const result = yield* client.fetch({
68
71
  url,
69
72
  select: {
@@ -82,6 +85,8 @@ export class Fetch extends Effect.Service<Fetch>()('Fetch', {
82
85
  result.data.snippets?.map((snippet) => `${snippet.text} (Score: ${snippet.score})`).join('\n') ??
83
86
  ''
84
87
 
88
+ yield* Effect.logDebug(`📤 Fetched successfully: ${result.data.response.url}`)
89
+
85
90
  return new FetchResult({
86
91
  content,
87
92
  url: result.data.response.url,
package/src/Server.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { Layer } from 'effect'
2
+ import packageJson from '../package.json' with { type: 'json' }
3
+ import { ExpandDocs } from './ExpandDocs.js'
4
+ import { ExpandToolKit } from './Toolkit.js'
5
+
6
+ export const ServerInfo = {
7
+ name: 'expandai-mcp-server',
8
+ version: packageJson.version,
9
+ } as const
10
+
11
+ export const makeServerLayer = (options: { readonly includeDocs?: boolean } = {}) =>
12
+ options.includeDocs ? Layer.mergeAll(ExpandToolKit, ExpandDocs) : ExpandToolKit
package/src/Toolkit.ts ADDED
@@ -0,0 +1,23 @@
1
+ import { McpServer, Toolkit } from '@effect/ai'
2
+ import { NodeHttpClient } from '@effect/platform-node'
3
+ import { Effect, Layer } from 'effect'
4
+ import { ExpandClient } from './ExpandClient.js'
5
+ import { Fetch, FetchTool } from './Fetch.js'
6
+
7
+ const toolkit = Toolkit.make(FetchTool)
8
+
9
+ const ToolkitLayer = toolkit
10
+ .toLayer(
11
+ Effect.gen(function* () {
12
+ yield* Effect.logInfo('Registering tools: fetch')
13
+
14
+ const fetchService = yield* Fetch
15
+
16
+ return toolkit.of({
17
+ fetch: fetchService.fetch,
18
+ })
19
+ }),
20
+ )
21
+ .pipe(Layer.provide(Fetch.Default), Layer.provide(ExpandClient.Default), Layer.provide(NodeHttpClient.layerUndici))
22
+
23
+ export const ExpandToolKit = McpServer.toolkit(toolkit).pipe(Layer.provide(ToolkitLayer))
package/src/main.ts CHANGED
@@ -2,23 +2,54 @@
2
2
  import { McpServer } from '@effect/ai'
3
3
  import { NodeRuntime, NodeSink, NodeStream } from '@effect/platform-node'
4
4
  import { Config, Effect, Layer, Logger, LogLevel } from 'effect'
5
- import packageJson from '../package.json' with { type: 'json' }
6
- import { ExpandDocs } from './resources/ExpandDocs.js'
7
- import { ExpandTools } from './tools/index.js'
5
+ import { makeServerLayer, ServerInfo } from './Server.js'
8
6
 
9
- const enableDocs = Config.withDefault(Config.boolean('EXPAND_ENABLE_DOCS'), () => false)
7
+ const enableDocs = Config.withDefault(Config.boolean('EXPAND_ENABLE_DOCS'), false)
8
+
9
+ const logLevelConfig = Config.withDefault(
10
+ Config.literal('debug', 'info', 'warning', 'error', 'none')('LOG_LEVEL'),
11
+ 'info',
12
+ )
13
+
14
+ const logLevelMap = {
15
+ debug: LogLevel.Debug,
16
+ info: LogLevel.Info,
17
+ warning: LogLevel.Warning,
18
+ error: LogLevel.Error,
19
+ none: LogLevel.None,
20
+ } as const
21
+
22
+ const startupBanner = `
23
+ ╔═══════════════════════════════════════════════════╗
24
+ ║ ║
25
+ ║ 🌐 expand.ai MCP Server ║
26
+ ║ ║
27
+ ╚═══════════════════════════════════════════════════╝`
10
28
 
11
29
  const program = Effect.gen(function* () {
12
30
  const docsEnabled = yield* enableDocs
31
+ const logLevel = yield* logLevelConfig
13
32
 
14
- const layers = docsEnabled ? Layer.mergeAll(ExpandTools, ExpandDocs) : ExpandTools
33
+ yield* Effect.logInfo(startupBanner)
34
+ yield* Effect.logInfo(`Starting v${ServerInfo.version}`)
35
+ yield* Effect.logInfo(`Documentation resources: ${docsEnabled ? 'enabled' : 'disabled'}`)
15
36
 
16
- yield* McpServer.layerStdio({
17
- name: 'expandai-mcp-server',
18
- version: packageJson.version,
37
+ const McpLayer = McpServer.layerStdio({
38
+ ...ServerInfo,
19
39
  stdin: NodeStream.stdin,
20
40
  stdout: NodeSink.stdout,
21
- }).pipe(Layer.provide(layers), Layer.provide(Logger.minimumLogLevel(LogLevel.None)), Layer.launch)
41
+ }).pipe(Layer.provide(makeServerLayer({ includeDocs: docsEnabled })))
42
+
43
+ const LifecycleLayer = Layer.scopedDiscard(
44
+ Effect.acquireRelease(Effect.logInfo('Server ready and listening on stdio'), () =>
45
+ Effect.logInfo('Server shutting down gracefully...'),
46
+ ),
47
+ )
48
+
49
+ yield* Layer.merge(McpLayer, LifecycleLayer).pipe(
50
+ Layer.provide(Logger.minimumLogLevel(logLevelMap[logLevel])),
51
+ Layer.launch,
52
+ )
22
53
  })
23
54
 
24
55
  program.pipe(NodeRuntime.runMain)
@@ -1,33 +0,0 @@
1
- import { McpServer, Toolkit } from '@effect/ai'
2
- import { NodeHttpClient } from '@effect/platform-node'
3
- import { Effect, Layer } from 'effect'
4
- import { ExpandClient } from '../ExpandClient.js'
5
- import { Fetch, FetchTool } from './Fetch.js'
6
-
7
- // =============================================================================
8
- // Toolkit (add more tools here)
9
- // =============================================================================
10
-
11
- const toolkit = Toolkit.make(FetchTool)
12
-
13
- // =============================================================================
14
- // Toolkit Layer
15
- // =============================================================================
16
-
17
- const ToolkitLayer = toolkit
18
- .toLayer(
19
- Effect.gen(function* () {
20
- const fetchService = yield* Fetch
21
-
22
- return toolkit.of({
23
- fetch: fetchService.fetch,
24
- })
25
- }),
26
- )
27
- .pipe(Layer.provide(Fetch.Default), Layer.provide(ExpandClient.Default), Layer.provide(NodeHttpClient.layerUndici))
28
-
29
- // =============================================================================
30
- // Export
31
- // =============================================================================
32
-
33
- export const ExpandTools = McpServer.toolkit(toolkit).pipe(Layer.provide(ToolkitLayer))
File without changes
File without changes