@osmosis-ai/mesh-server 0.2.0 → 0.3.0

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
@@ -3,8 +3,14 @@ export interface MeshServerConfig {
3
3
  port: number;
4
4
  /** Path to SQLite database for mesh storage (default: ':memory:') */
5
5
  dbPath: string;
6
- /** Allow anonymous contributions (default: true) */
6
+ /** Allow anonymous contributions (default: true for reads, false for writes) */
7
7
  allowAnonymous: boolean;
8
+ /** API keys that can contribute (write). Empty = no auth required. */
9
+ writeKeys: string[];
10
+ /** API keys that can read. Empty = public reads. */
11
+ readKeys: string[];
12
+ /** Rate limit: max contributions per key per hour */
13
+ rateLimitPerHour: number;
8
14
  }
9
15
  export declare const DEFAULT_MESH_CONFIG: MeshServerConfig;
10
16
  export declare function resolveMeshConfig(partial?: Partial<MeshServerConfig>): MeshServerConfig;
package/dist/config.js CHANGED
@@ -2,6 +2,9 @@ export const DEFAULT_MESH_CONFIG = {
2
2
  port: 7433,
3
3
  dbPath: ':memory:',
4
4
  allowAnonymous: true,
5
+ writeKeys: [],
6
+ readKeys: [],
7
+ rateLimitPerHour: 1000,
5
8
  };
6
9
  export function resolveMeshConfig(partial) {
7
10
  return { ...DEFAULT_MESH_CONFIG, ...partial };
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACnD,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,UAAU;IAClB,cAAc,EAAE,IAAI;CACrB,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,OAAmC;IACnE,OAAO,EAAE,GAAG,mBAAmB,EAAE,GAAG,OAAO,EAAE,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACnD,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,UAAU;IAClB,cAAc,EAAE,IAAI;IACpB,SAAS,EAAE,EAAE;IACb,QAAQ,EAAE,EAAE;IACZ,gBAAgB,EAAE,IAAI;CACvB,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,OAAmC;IACnE,OAAO,EAAE,GAAG,mBAAmB,EAAE,GAAG,OAAO,EAAE,CAAC;AAChD,CAAC"}
@@ -7,15 +7,20 @@ import { mkdirSync } from 'node:fs';
7
7
  import { dirname } from 'node:path';
8
8
  const port = parseInt(process.env.MESH_PORT || '7433', 10);
9
9
  const dbPath = process.env.MESH_DB_PATH || '/data/mesh.db';
10
+ const writeKeys = (process.env.MESH_WRITE_KEYS || '').split(',').filter(Boolean);
11
+ const readKeys = (process.env.MESH_READ_KEYS || '').split(',').filter(Boolean);
12
+ const rateLimitPerHour = parseInt(process.env.MESH_RATE_LIMIT || '1000', 10);
10
13
  // Ensure data directory exists
11
14
  try {
12
15
  mkdirSync(dirname(dbPath), { recursive: true });
13
16
  }
14
17
  catch { }
15
18
  // startMeshServer already calls server.listen() internally
16
- const handle = startMeshServer({ port, dbPath, allowAnonymous: true });
19
+ const handle = startMeshServer({ port, dbPath, allowAnonymous: writeKeys.length === 0, writeKeys, readKeys, rateLimitPerHour });
17
20
  console.log(`🧠 Osmosis mesh server running on port ${port}`);
18
21
  console.log(` Database: ${dbPath}`);
22
+ console.log(` Auth: ${writeKeys.length > 0 ? `${writeKeys.length} write key(s)` : 'open (no write keys)'}`);
23
+ console.log(` Rate limit: ${rateLimitPerHour}/hr per key`);
19
24
  console.log(` Ready to accept contributions`);
20
25
  // Graceful shutdown
21
26
  process.on('SIGTERM', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,eAAe,CAAC;AAE3D,+BAA+B;AAC/B,IAAI,CAAC;IACH,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAClD,CAAC;AAAC,MAAM,CAAC,CAAA,CAAC;AAEV,2DAA2D;AAC3D,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;AAEvE,OAAO,CAAC,GAAG,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAC;AAC9D,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC;AACtC,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;AAEhD,oBAAoB;AACpB,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,eAAe,CAAC;AAC3D,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACjF,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC/E,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAE7E,+BAA+B;AAC/B,IAAI,CAAC;IACH,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAClD,CAAC;AAAC,MAAM,CAAC,CAAA,CAAC;AAEV,2DAA2D;AAC3D,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC;AAEhI,OAAO,CAAC,GAAG,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAC;AAC9D,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC;AACtC,OAAO,CAAC,GAAG,CAAC,YAAY,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,eAAe,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC,CAAC;AAC9G,OAAO,CAAC,GAAG,CAAC,kBAAkB,gBAAgB,aAAa,CAAC,CAAC;AAC7D,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;AAEhD,oBAAoB;AACpB,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/server.js CHANGED
@@ -3,6 +3,27 @@ function json(res, status, data) {
3
3
  res.writeHead(status, { 'Content-Type': 'application/json' });
4
4
  res.end(JSON.stringify(data));
5
5
  }
6
+ /** Extract API key from Authorization header or query param */
7
+ function extractKey(req, url) {
8
+ const authHeader = req.headers['authorization'];
9
+ if (authHeader?.startsWith('Bearer '))
10
+ return authHeader.slice(7);
11
+ return url.searchParams.get('key');
12
+ }
13
+ /** Simple in-memory rate limiter */
14
+ const rateBuckets = new Map();
15
+ function checkRateLimit(key, limit) {
16
+ const now = Date.now();
17
+ const bucket = rateBuckets.get(key);
18
+ if (!bucket || now > bucket.resetAt) {
19
+ rateBuckets.set(key, { count: 1, resetAt: now + 3600_000 });
20
+ return true;
21
+ }
22
+ if (bucket.count >= limit)
23
+ return false;
24
+ bucket.count++;
25
+ return true;
26
+ }
6
27
  function readBody(req) {
7
28
  return new Promise((resolve, reject) => {
8
29
  const chunks = [];
@@ -26,6 +47,25 @@ export function createMeshServer(store, config) {
26
47
  const path = url.pathname;
27
48
  const method = req.method ?? 'GET';
28
49
  try {
50
+ const apiKey = extractKey(req, url);
51
+ // Auth check for writes
52
+ if (method === 'POST' && config.writeKeys.length > 0) {
53
+ if (!apiKey || !config.writeKeys.includes(apiKey)) {
54
+ return json(res, 401, { error: 'Invalid or missing API key. Pass via Authorization: Bearer <key>' });
55
+ }
56
+ }
57
+ // Auth check for reads (if readKeys configured)
58
+ if (method === 'GET' && config.readKeys.length > 0 && path !== '/mesh/stats') {
59
+ if (!apiKey || !config.readKeys.includes(apiKey)) {
60
+ return json(res, 401, { error: 'Invalid or missing API key' });
61
+ }
62
+ }
63
+ // Rate limiting for writes
64
+ if (method === 'POST' && apiKey) {
65
+ if (!checkRateLimit(apiKey, config.rateLimitPerHour)) {
66
+ return json(res, 429, { error: 'Rate limit exceeded. Try again later.' });
67
+ }
68
+ }
29
69
  // POST /mesh/contribute — accept atoms from clients
30
70
  if (method === 'POST' && path === '/mesh/contribute') {
31
71
  const body = JSON.parse(await readBody(req));
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osmosis-ai/mesh-server",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Centralized mesh server for Osmosis knowledge sharing",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/config.ts CHANGED
@@ -3,14 +3,23 @@ export interface MeshServerConfig {
3
3
  port: number;
4
4
  /** Path to SQLite database for mesh storage (default: ':memory:') */
5
5
  dbPath: string;
6
- /** Allow anonymous contributions (default: true) */
6
+ /** Allow anonymous contributions (default: true for reads, false for writes) */
7
7
  allowAnonymous: boolean;
8
+ /** API keys that can contribute (write). Empty = no auth required. */
9
+ writeKeys: string[];
10
+ /** API keys that can read. Empty = public reads. */
11
+ readKeys: string[];
12
+ /** Rate limit: max contributions per key per hour */
13
+ rateLimitPerHour: number;
8
14
  }
9
15
 
10
16
  export const DEFAULT_MESH_CONFIG: MeshServerConfig = {
11
17
  port: 7433,
12
18
  dbPath: ':memory:',
13
19
  allowAnonymous: true,
20
+ writeKeys: [],
21
+ readKeys: [],
22
+ rateLimitPerHour: 1000,
14
23
  };
15
24
 
16
25
  export function resolveMeshConfig(partial?: Partial<MeshServerConfig>): MeshServerConfig {
package/src/entrypoint.ts CHANGED
@@ -8,6 +8,9 @@ import { dirname } from 'node:path';
8
8
 
9
9
  const port = parseInt(process.env.MESH_PORT || '7433', 10);
10
10
  const dbPath = process.env.MESH_DB_PATH || '/data/mesh.db';
11
+ const writeKeys = (process.env.MESH_WRITE_KEYS || '').split(',').filter(Boolean);
12
+ const readKeys = (process.env.MESH_READ_KEYS || '').split(',').filter(Boolean);
13
+ const rateLimitPerHour = parseInt(process.env.MESH_RATE_LIMIT || '1000', 10);
11
14
 
12
15
  // Ensure data directory exists
13
16
  try {
@@ -15,10 +18,12 @@ try {
15
18
  } catch {}
16
19
 
17
20
  // startMeshServer already calls server.listen() internally
18
- const handle = startMeshServer({ port, dbPath, allowAnonymous: true });
21
+ const handle = startMeshServer({ port, dbPath, allowAnonymous: writeKeys.length === 0, writeKeys, readKeys, rateLimitPerHour });
19
22
 
20
23
  console.log(`🧠 Osmosis mesh server running on port ${port}`);
21
24
  console.log(` Database: ${dbPath}`);
25
+ console.log(` Auth: ${writeKeys.length > 0 ? `${writeKeys.length} write key(s)` : 'open (no write keys)'}`);
26
+ console.log(` Rate limit: ${rateLimitPerHour}/hr per key`);
22
27
  console.log(` Ready to accept contributions`);
23
28
 
24
29
  // Graceful shutdown
package/src/server.ts CHANGED
@@ -8,6 +8,28 @@ function json(res: ServerResponse, status: number, data: unknown): void {
8
8
  res.end(JSON.stringify(data));
9
9
  }
10
10
 
11
+ /** Extract API key from Authorization header or query param */
12
+ function extractKey(req: IncomingMessage, url: URL): string | null {
13
+ const authHeader = req.headers['authorization'];
14
+ if (authHeader?.startsWith('Bearer ')) return authHeader.slice(7);
15
+ return url.searchParams.get('key');
16
+ }
17
+
18
+ /** Simple in-memory rate limiter */
19
+ const rateBuckets = new Map<string, { count: number; resetAt: number }>();
20
+
21
+ function checkRateLimit(key: string, limit: number): boolean {
22
+ const now = Date.now();
23
+ const bucket = rateBuckets.get(key);
24
+ if (!bucket || now > bucket.resetAt) {
25
+ rateBuckets.set(key, { count: 1, resetAt: now + 3600_000 });
26
+ return true;
27
+ }
28
+ if (bucket.count >= limit) return false;
29
+ bucket.count++;
30
+ return true;
31
+ }
32
+
11
33
  function readBody(req: IncomingMessage): Promise<string> {
12
34
  return new Promise((resolve, reject) => {
13
35
  const chunks: Buffer[] = [];
@@ -33,6 +55,29 @@ export function createMeshServer(store: AtomStore, config: MeshServerConfig): Se
33
55
  const method = req.method ?? 'GET';
34
56
 
35
57
  try {
58
+ const apiKey = extractKey(req, url);
59
+
60
+ // Auth check for writes
61
+ if (method === 'POST' && config.writeKeys.length > 0) {
62
+ if (!apiKey || !config.writeKeys.includes(apiKey)) {
63
+ return json(res, 401, { error: 'Invalid or missing API key. Pass via Authorization: Bearer <key>' });
64
+ }
65
+ }
66
+
67
+ // Auth check for reads (if readKeys configured)
68
+ if (method === 'GET' && config.readKeys.length > 0 && path !== '/mesh/stats') {
69
+ if (!apiKey || !config.readKeys.includes(apiKey)) {
70
+ return json(res, 401, { error: 'Invalid or missing API key' });
71
+ }
72
+ }
73
+
74
+ // Rate limiting for writes
75
+ if (method === 'POST' && apiKey) {
76
+ if (!checkRateLimit(apiKey, config.rateLimitPerHour)) {
77
+ return json(res, 429, { error: 'Rate limit exceeded. Try again later.' });
78
+ }
79
+ }
80
+
36
81
  // POST /mesh/contribute — accept atoms from clients
37
82
  if (method === 'POST' && path === '/mesh/contribute') {
38
83
  const body = JSON.parse(await readBody(req));