@quantish/agent 0.1.2 → 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.
Files changed (2) hide show
  1. package/dist/index.js +324 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -913,8 +913,111 @@ var filesystemTools = [
913
913
  },
914
914
  required: ["path", "old_string", "new_string"]
915
915
  }
916
+ },
917
+ {
918
+ name: "setup_env",
919
+ description: "Setup or update environment variables in a .env file for an application. Creates .env if it doesn't exist. Optionally creates a .env.example template. Use this when building any application that needs API keys or configuration.",
920
+ input_schema: {
921
+ type: "object",
922
+ properties: {
923
+ path: {
924
+ type: "string",
925
+ description: 'Path to the .env file (default: ".env" in current directory)'
926
+ },
927
+ variables: {
928
+ type: "object",
929
+ description: 'Object with environment variable names as keys and values. Example: { "QUANTISH_API_KEY": "abc123", "TOKEN_ID": "xyz" }',
930
+ additionalProperties: { type: "string" }
931
+ },
932
+ overwrite: {
933
+ type: "boolean",
934
+ description: "If true, overwrite existing variables. Default false (skip existing)."
935
+ },
936
+ create_example: {
937
+ type: "boolean",
938
+ description: "If true, also create a .env.example template file with placeholder values."
939
+ }
940
+ },
941
+ required: ["variables"]
942
+ }
916
943
  }
917
944
  ];
945
+ async function setupEnv(envPath = ".env", variables, options) {
946
+ try {
947
+ const resolvedPath = path.resolve(envPath);
948
+ let content = "";
949
+ const existingVars = {};
950
+ if (existsSync(resolvedPath)) {
951
+ content = await fs.readFile(resolvedPath, "utf-8");
952
+ for (const line of content.split("\n")) {
953
+ const trimmed = line.trim();
954
+ if (trimmed && !trimmed.startsWith("#")) {
955
+ const eqIndex = trimmed.indexOf("=");
956
+ if (eqIndex > 0) {
957
+ const key = trimmed.slice(0, eqIndex);
958
+ const value = trimmed.slice(eqIndex + 1);
959
+ existingVars[key] = value;
960
+ }
961
+ }
962
+ }
963
+ }
964
+ const updatedVars = [];
965
+ const addedVars = [];
966
+ const skippedVars = [];
967
+ for (const [key, value] of Object.entries(variables)) {
968
+ if (existingVars[key] !== void 0) {
969
+ if (options?.overwrite) {
970
+ const regex = new RegExp(`^${key}=.*$`, "m");
971
+ content = content.replace(regex, `${key}=${value}`);
972
+ updatedVars.push(key);
973
+ } else {
974
+ skippedVars.push(key);
975
+ }
976
+ } else {
977
+ if (content && !content.endsWith("\n")) {
978
+ content += "\n";
979
+ }
980
+ content += `${key}=${value}
981
+ `;
982
+ addedVars.push(key);
983
+ }
984
+ }
985
+ await fs.writeFile(resolvedPath, content, "utf-8");
986
+ if (options?.createExample) {
987
+ const examplePath = resolvedPath.replace(/\.env$/, ".env.example");
988
+ let exampleContent = "# Environment variables for this application\n";
989
+ exampleContent += "# Copy this file to .env and fill in your values\n\n";
990
+ for (const key of Object.keys({ ...existingVars, ...variables })) {
991
+ if (key === "QUANTISH_API_KEY") {
992
+ exampleContent += `# Get your API key at https://quantish.live
993
+ `;
994
+ exampleContent += `${key}=your_api_key_here
995
+
996
+ `;
997
+ } else {
998
+ exampleContent += `${key}=
999
+ `;
1000
+ }
1001
+ }
1002
+ await fs.writeFile(examplePath, exampleContent, "utf-8");
1003
+ }
1004
+ return {
1005
+ success: true,
1006
+ data: {
1007
+ path: resolvedPath,
1008
+ added: addedVars,
1009
+ updated: updatedVars,
1010
+ skipped: skippedVars,
1011
+ exampleCreated: options?.createExample || false
1012
+ }
1013
+ };
1014
+ } catch (error2) {
1015
+ return {
1016
+ success: false,
1017
+ error: `Failed to setup env: ${error2 instanceof Error ? error2.message : String(error2)}`
1018
+ };
1019
+ }
1020
+ }
918
1021
  async function executeFilesystemTool(name, args) {
919
1022
  switch (name) {
920
1023
  case "read_file":
@@ -937,6 +1040,15 @@ async function executeFilesystemTool(name, args) {
937
1040
  args.new_string,
938
1041
  { replaceAll: args.replace_all }
939
1042
  );
1043
+ case "setup_env":
1044
+ return setupEnv(
1045
+ args.path || ".env",
1046
+ args.variables,
1047
+ {
1048
+ overwrite: args.overwrite,
1049
+ createExample: args.create_example
1050
+ }
1051
+ );
940
1052
  default:
941
1053
  return { success: false, error: `Unknown filesystem tool: ${name}` };
942
1054
  }
@@ -2566,11 +2678,11 @@ You can work with the local filesystem:
2566
2678
  - When writing code, follow existing patterns and conventions
2567
2679
  - For dangerous operations (rm, sudo), explain what you're doing
2568
2680
 
2569
- You help users build trading bots and agents by combining coding skills with trading capabilities.
2681
+ You help users build ANY application that interacts with prediction markets - trading bots, web apps, mobile backends, dashboards, notification systems, analytics tools, Discord bots, Telegram bots, and more.
2570
2682
 
2571
- ## Building Standalone Trading Bots
2683
+ ## Building Applications with Quantish MCP
2572
2684
 
2573
- When users ask you to create trading bots or agents that run independently (not through this CLI), here's how to integrate with the Quantish MCP API:
2685
+ When users ask you to create ANY application that uses prediction market data or trading (bots, APIs, web apps, scripts, etc.), you MUST use the Quantish MCP API. This is the ONLY way to access market data and trading functionality in standalone applications.
2574
2686
 
2575
2687
  ### MCP API Endpoint
2576
2688
  \`\`\`
@@ -2702,14 +2814,221 @@ async function monitorPrice(tokenId, threshold) {
2702
2814
  setInterval(() => monitorPrice(process.env.TOKEN_ID, 0.5), 60000);
2703
2815
  \`\`\`
2704
2816
 
2705
- ### Bot Best Practices
2817
+ ### Best Practices
2706
2818
  1. **Environment Variables**: Always use process.env for API keys
2707
2819
  2. **Error Handling**: Wrap all API calls in try/catch
2708
2820
  3. **Rate Limiting**: Poll at 30-60 second intervals minimum
2709
2821
  4. **Logging**: Log all trades with timestamps for debugging
2710
2822
  5. **Testing**: Test with small amounts first
2711
2823
  6. **Graceful Shutdown**: Handle SIGINT to clean up
2712
- 7. **.env.example**: Always create a template for required env vars`;
2824
+ 7. **.env.example**: Always create a template for required env vars
2825
+
2826
+ ## CRITICAL: Code Generation Rules (MUST FOLLOW)
2827
+
2828
+ When generating ANY code that uses Quantish/MCP (bots, apps, scripts, APIs, etc.):
2829
+
2830
+ ### MANDATORY Requirements
2831
+
2832
+ 1. **ALWAYS include the callTool() helper function** - Copy it EXACTLY from the template above
2833
+ 2. **ALWAYS use callTool() for ALL MCP operations** - Never use direct API calls to Polymarket
2834
+ 3. **NEVER hardcode prices, market data, or API responses** - Always fetch live data via callTool()
2835
+ 4. **NEVER comment out MCP calls** - All API calls must be real, working, executable code
2836
+ 5. **ALWAYS create .env.example** - Document all required environment variables
2837
+ 6. **ALWAYS validate QUANTISH_API_KEY exists** - Fail fast with clear error if missing
2838
+ 7. **ALWAYS use dotenv** - \`require('dotenv').config()\` at the top of every file
2839
+
2840
+ ### File Structure for ANY Application
2841
+
2842
+ When creating an application, ALWAYS create these files:
2843
+ 1. Main application file (e.g., \`app.js\`, \`bot.js\`, \`server.js\`)
2844
+ 2. \`.env.example\` with all required variables documented
2845
+ 3. \`package.json\` with dependencies (dotenv, etc.)
2846
+ 4. \`README.md\` with setup instructions
2847
+
2848
+ ### Example .env.example (ALWAYS CREATE THIS)
2849
+ \`\`\`
2850
+ # Quantish MCP API Key (required for trading)
2851
+ # Get yours at: https://quantish.live
2852
+ QUANTISH_API_KEY=your_api_key_here
2853
+
2854
+ # Market Configuration (customize for your use case)
2855
+ TOKEN_ID=your_token_id_here
2856
+ CONDITION_ID=your_condition_id_here
2857
+ \`\`\`
2858
+
2859
+ ### WRONG vs CORRECT Code Examples
2860
+
2861
+ WRONG - Hardcoded data (NEVER DO THIS):
2862
+ \`\`\`javascript
2863
+ const prices = { YES: 0.55, NO: 0.45 }; // WRONG: hardcoded
2864
+ const mockResult = { mid: "0.50" }; // WRONG: mock data
2865
+ // await callTool('place_order', {...}); // WRONG: commented out
2866
+ \`\`\`
2867
+
2868
+ CORRECT - Live MCP calls (ALWAYS DO THIS):
2869
+ \`\`\`javascript
2870
+ const priceResult = await callTool('get_price', { tokenId });
2871
+ const price = parseFloat(priceResult.mid);
2872
+ const orderResult = await callTool('place_order', {
2873
+ conditionId, tokenId, side: 'BUY', price, size
2874
+ });
2875
+ console.log('Order placed:', orderResult.orderId);
2876
+ \`\`\`
2877
+
2878
+ ### Complete Production-Ready Template
2879
+
2880
+ Use this as the starting point for ANY application:
2881
+
2882
+ \`\`\`javascript
2883
+ #!/usr/bin/env node
2884
+ /**
2885
+ * Quantish Application Template
2886
+ * Replace this with your application description
2887
+ */
2888
+
2889
+ require('dotenv').config();
2890
+
2891
+ // ============================================
2892
+ // MCP Configuration - DO NOT MODIFY
2893
+ // ============================================
2894
+ const TRADING_MCP_URL = 'https://quantish-sdk-production.up.railway.app/mcp/execute';
2895
+ const DISCOVERY_MCP_URL = 'https://quantish.live/mcp/execute';
2896
+ const DISCOVERY_API_KEY = 'qm_ueQeqrmvZyHtR1zuVbLYkhx0fKyVAuV8'; // Public key for discovery
2897
+
2898
+ // Validate required environment variables
2899
+ if (!process.env.QUANTISH_API_KEY) {
2900
+ console.error('ERROR: QUANTISH_API_KEY environment variable is required');
2901
+ console.error('Get your API key at: https://quantish.live');
2902
+ console.error('Then create a .env file with: QUANTISH_API_KEY=your_key_here');
2903
+ process.exit(1);
2904
+ }
2905
+
2906
+ // ============================================
2907
+ // MCP Helper Functions - COPY THESE EXACTLY
2908
+ // ============================================
2909
+
2910
+ /**
2911
+ * Call a trading tool (requires QUANTISH_API_KEY)
2912
+ * Tools: get_balances, get_positions, place_order, cancel_order, get_orders,
2913
+ * get_orderbook, get_price, get_deposit_addresses, transfer_usdc
2914
+ */
2915
+ async function callTradingTool(name, args = {}) {
2916
+ const response = await fetch(TRADING_MCP_URL, {
2917
+ method: 'POST',
2918
+ headers: {
2919
+ 'Content-Type': 'application/json',
2920
+ 'x-api-key': process.env.QUANTISH_API_KEY
2921
+ },
2922
+ body: JSON.stringify({
2923
+ jsonrpc: '2.0',
2924
+ method: 'tools/call',
2925
+ params: { name, arguments: args },
2926
+ id: Date.now()
2927
+ })
2928
+ });
2929
+
2930
+ const data = await response.json();
2931
+ if (data.error) throw new Error(data.error.message || JSON.stringify(data.error));
2932
+
2933
+ try {
2934
+ return JSON.parse(data.result.content[0].text);
2935
+ } catch {
2936
+ return data.result.content[0].text;
2937
+ }
2938
+ }
2939
+
2940
+ /**
2941
+ * Call a discovery tool (no auth required)
2942
+ * Tools: search_markets, get_market_details, get_trending_markets, find_arbitrage
2943
+ */
2944
+ async function callDiscoveryTool(name, args = {}) {
2945
+ const response = await fetch(DISCOVERY_MCP_URL, {
2946
+ method: 'POST',
2947
+ headers: {
2948
+ 'Content-Type': 'application/json',
2949
+ 'X-API-Key': DISCOVERY_API_KEY
2950
+ },
2951
+ body: JSON.stringify({
2952
+ jsonrpc: '2.0',
2953
+ method: 'tools/call',
2954
+ params: { name, arguments: args },
2955
+ id: Date.now()
2956
+ })
2957
+ });
2958
+
2959
+ const data = await response.json();
2960
+ if (data.error) throw new Error(data.error.message || JSON.stringify(data.error));
2961
+
2962
+ try {
2963
+ return JSON.parse(data.result.content[0].text);
2964
+ } catch {
2965
+ return data.result.content[0].text;
2966
+ }
2967
+ }
2968
+
2969
+ // Shorthand for common operations
2970
+ const callTool = callTradingTool; // Default to trading tools
2971
+
2972
+ // ============================================
2973
+ // Your Application Code Goes Here
2974
+ // ============================================
2975
+
2976
+ async function main() {
2977
+ console.log('Starting application...');
2978
+
2979
+ try {
2980
+ // Example: Get wallet balances
2981
+ const balances = await callTool('get_balances');
2982
+ console.log('Wallet balances:', balances);
2983
+
2984
+ // Example: Search for markets
2985
+ const markets = await callDiscoveryTool('search_markets', {
2986
+ query: 'Bitcoin',
2987
+ limit: 5
2988
+ });
2989
+ console.log('Found markets:', markets.found);
2990
+
2991
+ // Example: Get price for a token
2992
+ if (process.env.TOKEN_ID) {
2993
+ const price = await callTool('get_price', {
2994
+ tokenId: process.env.TOKEN_ID
2995
+ });
2996
+ console.log('Current price:', price.mid);
2997
+ }
2998
+
2999
+ } catch (error) {
3000
+ console.error('Error:', error.message);
3001
+ }
3002
+ }
3003
+
3004
+ // Graceful shutdown
3005
+ process.on('SIGINT', () => {
3006
+ console.log('\\nShutting down...');
3007
+ process.exit(0);
3008
+ });
3009
+
3010
+ process.on('SIGTERM', () => {
3011
+ console.log('\\nShutting down...');
3012
+ process.exit(0);
3013
+ });
3014
+
3015
+ // Run the application
3016
+ main().catch(console.error);
3017
+ \`\`\`
3018
+
3019
+ ### Application Types You Can Build
3020
+
3021
+ - **Trading Bots**: Automated trading based on price thresholds, trends, or signals
3022
+ - **Price Monitors**: Alert systems for price movements via email, SMS, Discord, Telegram
3023
+ - **Web Dashboards**: React/Next.js apps displaying market data and portfolio
3024
+ - **API Backends**: Express/Fastify servers exposing market data to frontends
3025
+ - **Analytics Tools**: Scripts that analyze historical prices and trends
3026
+ - **Arbitrage Scanners**: Tools that find and execute arbitrage opportunities
3027
+ - **Portfolio Trackers**: Apps that track positions across multiple markets
3028
+ - **Notification Services**: Webhooks that trigger on market events
3029
+ - **Discord/Telegram Bots**: Chat bots that provide market info and execute trades
3030
+
3031
+ For ALL of these, use the MCP helper functions above. Never make direct API calls to Polymarket or other services.`;
2713
3032
  var Agent = class {
2714
3033
  anthropic;
2715
3034
  mcpClient;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantish/agent",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "AI-powered agent for building trading bots on Polymarket",
5
5
  "type": "module",
6
6
  "bin": {