diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 65b722cf7c1499ff053429aaed1217477c78b9ce..075a2d792f7d87d5edb2ab0dad9b58cb4b41caea 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -235,6 +235,69 @@ u_long resolve_ip(char *addr)
 
 #ifdef JAVASCRIPT
 
+static JSClass js_method_class = {
+     "Method"				/* name			*/
+    ,0						/* flags		*/
+	,JS_PropertyStub		/* addProperty	*/
+	,JS_PropertyStub		/* delProperty	*/
+	,JS_PropertyStub		/* getProperty	*/
+	,JS_PropertyStub		/* setProperty	*/
+	,JS_EnumerateStub		/* enumerate	*/
+	,JS_ResolveStub			/* resolve		*/
+	,JS_ConvertStub			/* convert		*/
+	,JS_FinalizeStub		/* finalize		*/
+};
+
+static const char* method_array_name = "_method_list";
+
+static JSBool 
+DLLCALL js_DefineMethods(JSContext* cx, JSObject* obj, JSFunctionSpec *funcs)
+{
+	int			i;
+	jsuint		len=0;
+	jsval		val;
+	JSObject*	method;
+	JSObject*	method_array;
+
+	if(!JS_DefineFunctions(cx,obj,funcs))
+		return(JS_FALSE);
+
+	/* Return existing user object if it's already been created */
+	if(JS_GetProperty(cx,obj,method_array_name,&val) && val!=JSVAL_VOID)
+		method_array=JSVAL_TO_OBJECT(val);
+	else
+		if((method_array=JS_NewArrayObject(cx, 0, NULL))==NULL) 
+			return(JS_FALSE);
+
+	JS_GetArrayLength(cx, method_array, &len);
+
+	for(i=0;funcs[i].name;i++) {
+
+		method = JS_NewObject(cx, &js_method_class, NULL, method_array);
+
+		if(method==NULL)
+			return(JS_FALSE);
+
+		val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,funcs[i].name));
+		if(!JS_SetProperty(cx, method, "name", &val))
+			return(JS_FALSE);
+
+		val = INT_TO_JSVAL(funcs[i].nargs);
+		if(!JS_SetProperty(cx, method, "nargs", &val))
+			return(JS_FALSE);
+
+		val=OBJECT_TO_JSVAL(method);
+		if(!JS_SetElement(cx, method_array, len+i, &val))
+			return(JS_FALSE);
+	}
+
+	if(!JS_DefineProperty(cx, obj, method_array_name, OBJECT_TO_JSVAL(method_array)
+		, NULL, NULL, 0))
+		return(JS_FALSE);
+
+	return(JS_TRUE);
+}
+
 /* 
  * @method: log
  * @syntax: log([value][,value][...])
@@ -508,7 +571,7 @@ bool sbbs_t::js_init()
 		if((js_glob=js_CreateGlobalObject(js_cx, &cfg))==NULL)
 			break;
 
-		if(!JS_DefineFunctions(js_cx, js_glob, js_global_functions))
+		if(!js_DefineMethods(js_cx, js_glob, js_global_functions))
 			break;
 
 		/* System Object */
@@ -541,7 +604,7 @@ bool sbbs_t::js_init()
 
 		/* Server Object */
 		if((server=JS_DefineObject(js_cx, js_glob, "server", &js_server_class
-			,NULL,0))==NULL)
+			,NULL,JSPROP_ENUMERATE))==NULL)
 			break;
 
 		sprintf(ver,"%s v%s%c",TELNET_SERVER,VERSION,REVISION);
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index 719e404326271ef54867eaabf59b81fc11cab38f..518a43501c245bc46e0d150bafd1e7ba3d7bbe49 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -828,6 +828,9 @@ extern "C" {
 
 #ifdef JAVASCRIPT
 
+	/* main.cpp */
+	DLLEXPORT JSBool	DLLCALL js_DefineMethods(JSContext* cx, JSObject* obj, JSFunctionSpec *fs);
+
 	/* js_global.c */
 	DLLEXPORT JSObject* DLLCALL js_CreateGlobalObject(JSContext* cx, scfg_t* cfg);