@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.
- package/dist/index.js +324 -5
- 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
|
|
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
|
|
2683
|
+
## Building Applications with Quantish MCP
|
|
2572
2684
|
|
|
2573
|
-
When users ask you to create
|
|
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
|
-
###
|
|
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;
|