@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 +0 -2
- package/dist/config.js +1 -16
- package/dist/gainableHttpRunner.d.ts +7 -1
- package/dist/gainableHttpRunner.js +23 -5
- package/dist/index.js +3 -0
- package/package.json +1 -1
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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