@gainable.dev/mcp-server 0.1.0 → 0.1.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/config.d.ts CHANGED
@@ -1,10 +1,8 @@
1
- export type AgentScopes = Record<string, string[]>;
2
1
  export interface ScopingConfig {
3
2
  appName: string;
4
3
  accountId: string;
5
4
  allowedDatasets: string[];
6
5
  mongodbUri: string;
7
- agentScopes: AgentScopes;
8
6
  /** Per-session field: which collections this agent can access. undefined = unrestricted. */
9
7
  agentCollections?: string[];
10
8
  }
package/dist/config.js CHANGED
@@ -12,20 +12,5 @@ export function loadConfig() {
12
12
  .split(',')
13
13
  .map(s => s.trim())
14
14
  .filter(Boolean);
15
- const agentScopes = parseAgentScopes(process.env.AGENT_SCOPES);
16
- return { appName, accountId, allowedDatasets, mongodbUri, agentScopes };
17
- }
18
- function parseAgentScopes(raw) {
19
- if (!raw)
20
- return {};
21
- try {
22
- const parsed = JSON.parse(raw);
23
- if (typeof parsed !== 'object' || parsed === null)
24
- return {};
25
- return parsed;
26
- }
27
- catch {
28
- console.warn('AGENT_SCOPES is not valid JSON, ignoring.');
29
- return {};
30
- }
15
+ return { appName, accountId, allowedDatasets, mongodbUri };
31
16
  }
@@ -5,11 +5,17 @@ import type { ScopingConfig } from './config.js';
5
5
  *
6
6
  * Each Weavy agent connects with a URL like `/mcp?agent=marketing-agent`.
7
7
  * The agent ID is extracted from the query parameter and used to look up
8
- * which collections that agent is allowed to access (from AGENT_SCOPES env var).
8
+ * which collections that agent is allowed to access (from MongoDB).
9
9
  */
10
10
  export declare class GainableHttpRunner extends StreamableHttpRunner {
11
11
  private baseConfig;
12
+ private scopeClient;
12
13
  constructor(config: ConstructorParameters<typeof StreamableHttpRunner>[0], scopingConfig: ScopingConfig);
14
+ /**
15
+ * Look up an agent's scopes from MongoDB.
16
+ * Returns the scopes array if the agent has restrictions, or undefined if unrestricted.
17
+ */
18
+ private getAgentScopes;
13
19
  protected createServerForRequest({ request, serverOptions, sessionOptions, }: Parameters<StreamableHttpRunner['createServerForRequest']>[0]): Promise<import("mongodb-mcp-server").Server<{
14
20
  apiBaseUrl: string;
15
21
  assistantBaseUrl: string;
@@ -1,3 +1,4 @@
1
+ import { MongoClient } from 'mongodb';
1
2
  import { StreamableHttpRunner } from 'mongodb-mcp-server';
2
3
  import { createScopedConnectionManagerFactory } from './scopedConnectionManager.js';
3
4
  /**
@@ -5,20 +6,37 @@ import { createScopedConnectionManagerFactory } from './scopedConnectionManager.
5
6
  *
6
7
  * Each Weavy agent connects with a URL like `/mcp?agent=marketing-agent`.
7
8
  * The agent ID is extracted from the query parameter and used to look up
8
- * which collections that agent is allowed to access (from AGENT_SCOPES env var).
9
+ * which collections that agent is allowed to access (from MongoDB).
9
10
  */
10
11
  export class GainableHttpRunner extends StreamableHttpRunner {
11
12
  baseConfig;
13
+ scopeClient = null;
12
14
  constructor(config, scopingConfig) {
13
15
  super(config);
14
16
  this.baseConfig = scopingConfig;
15
17
  }
18
+ /**
19
+ * Look up an agent's scopes from MongoDB.
20
+ * Returns the scopes array if the agent has restrictions, or undefined if unrestricted.
21
+ */
22
+ async getAgentScopes(agentUid) {
23
+ if (!this.scopeClient) {
24
+ this.scopeClient = new MongoClient(this.baseConfig.mongodbUri);
25
+ await this.scopeClient.connect();
26
+ }
27
+ const db = this.scopeClient.db(this.baseConfig.accountId);
28
+ const agent = await db.collection('agents').findOne({ appId: this.baseConfig.appName, uid: agentUid }, { projection: { scopes: 1 } });
29
+ if (!agent?.scopes || agent.scopes.length === 0)
30
+ return undefined;
31
+ return agent.scopes;
32
+ }
16
33
  async createServerForRequest({ request, serverOptions, sessionOptions, }) {
17
34
  const agentId = extractAgentId(request);
18
- console.log(`[MCP Session] agent=${agentId ?? '(none)'} | scoped=${agentId && this.baseConfig.agentScopes[agentId] ? 'yes' : 'no'}`);
19
- const agentCollections = agentId
20
- ? this.baseConfig.agentScopes[agentId]
21
- : undefined;
35
+ let agentCollections;
36
+ if (agentId) {
37
+ agentCollections = await this.getAgentScopes(agentId);
38
+ }
39
+ console.log(`[MCP Session] agent=${agentId ?? '(none)'} | scoped=${agentCollections ? 'yes' : 'no'}`);
22
40
  // Build per-agent scoping config
23
41
  const agentConfig = {
24
42
  ...this.baseConfig,
package/dist/index.js CHANGED
@@ -17,6 +17,9 @@ const userConfig = UserConfigSchema.parse({
17
17
  httpHost: '127.0.0.1',
18
18
  connectionString: config.mongodbUri,
19
19
  telemetry: 'disabled',
20
+ // 24h idle timeout — sessions are long-lived (Weavy agent conversations)
21
+ idleTimeoutMs: 86400000,
22
+ notificationTimeoutMs: 82800000,
20
23
  disabledTools: [
21
24
  'drop-database', 'drop-collection', 'create-collection',
22
25
  'list-databases', 'rename-collection', 'drop-index',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gainable.dev/mcp-server",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Scoped MCP server for Gainable in-app copilot agents — wraps mongodb-mcp-server with per-app data isolation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",