Skip to main content
Glama

TradeStation MCP Server

by maven81g
test-mcp-final.js•7.16 kB
// Final test script for all MCP server functions import axios from 'axios'; import dotenv from 'dotenv'; dotenv.config(); const TS_TOKEN_URL = 'https://signin.tradestation.com/oauth/token'; const TS_API_BASE = 'https://sim-api.tradestation.com/v3'; async function getAccessToken() { const TS_CLIENT_ID = process.env.TRADESTATION_CLIENT_ID; const TS_CLIENT_SECRET = process.env.TRADESTATION_CLIENT_SECRET; const TS_REFRESH_TOKEN = process.env.TRADESTATION_REFRESH_TOKEN; console.log('šŸ”‘ Obtaining access token...'); const response = await axios.post(TS_TOKEN_URL, new URLSearchParams({ grant_type: 'refresh_token', client_id: TS_CLIENT_ID, client_secret: TS_CLIENT_SECRET, refresh_token: TS_REFRESH_TOKEN }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); console.log('āœ… Access token obtained\n'); return response.data.access_token; } async function testEndpoint(name, method, endpoint, token, data = null) { console.log(`\nšŸ“” Testing: ${name}`); console.log(` Endpoint: ${method} ${endpoint}`); try { const config = { method, url: `${TS_API_BASE}${endpoint}`, headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Accept': 'application/json' }, timeout: 30000 }; if (data && (method === 'POST' || method === 'PUT')) { config.data = data; } const response = await axios(config); console.log(` āœ… SUCCESS (${response.status})`); const preview = JSON.stringify(response.data, null, 2); console.log(` Response: ${preview.substring(0, 250)}...`); return { success: true, data: response.data }; } catch (error) { const status = error.response?.status || 'ERROR'; const errorMsg = error.response?.data?.Message || error.response?.data?.message || error.message; console.log(` āŒ FAILED (${status}): ${errorMsg}`); return { success: false, error: errorMsg, status }; } } async function runTests() { console.log('═══════════════════════════════════════════════════════'); console.log(' TradeStation MCP Server - Final Test Suite'); console.log('═══════════════════════════════════════════════════════\n'); const token = await getAccessToken(); const results = []; // Market Data Functions console.log('\nā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”'); console.log('│ MARKET DATA FUNCTIONS │'); console.log('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜'); results.push(await testEndpoint('marketData', 'GET', '/marketdata/quotes/SPY,QQQ', token)); results.push(await testEndpoint('barChart', 'GET', '/marketdata/barcharts/SPY?interval=5&unit=Minute&barsback=5', token)); results.push(await testEndpoint('getSymbolDetails', 'GET', '/marketdata/symbols/SPY,AAPL', token)); results.push(await testEndpoint('getOptionExpirations', 'GET', '/marketdata/options/expirations/AAPL', token)); results.push(await testEndpoint('getOptionStrikes', 'GET', '/marketdata/options/strikes/AAPL', token)); // Account Functions console.log('\nā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”'); console.log('│ ACCOUNT FUNCTIONS │'); console.log('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜'); const accountsResult = await testEndpoint('getAccounts', 'GET', '/brokerage/accounts', token); results.push(accountsResult); let accountId = null; if (accountsResult.success && accountsResult.data?.Accounts?.length > 0) { accountId = accountsResult.data.Accounts[0].AccountID; console.log(`\n ā„¹ļø Using Account ID: ${accountId}`); results.push(await testEndpoint('getBalances', 'GET', `/brokerage/accounts/${accountId}/balances`, token)); results.push(await testEndpoint('getPositions', 'GET', `/brokerage/accounts/${accountId}/positions`, token)); results.push(await testEndpoint('getOrders', 'GET', `/brokerage/accounts/${accountId}/orders`, token)); } // Order Preview console.log('\nā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”'); console.log('│ ORDER PREVIEW (READ-ONLY) │'); console.log('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜'); if (accountId) { // Test with proper format const confirmData = { AccountID: accountId, Symbol: "SPY", Quantity: "1", OrderType: "Limit", TradeAction: "Buy", LimitPrice: "500.00", TimeInForce: { Duration: "Day" } }; results.push(await testEndpoint('confirmOrder', 'POST', '/orderexecution/orderconfirm', token, confirmData)); } // Summary console.log('\n═══════════════════════════════════════════════════════'); console.log(' TEST SUMMARY'); console.log('═══════════════════════════════════════════════════════'); const successful = results.filter(r => r.success).length; const failed = results.filter(r => !r.success).length; const total = results.length; console.log(`\n Total Tests: ${total}`); console.log(` āœ… Passed: ${successful}`); console.log(` āŒ Failed: ${failed}`); console.log(` Success Rate: ${((successful/total)*100).toFixed(1)}%\n`); console.log('═══════════════════════════════════════════════════════\n'); if (successful >= total - 1) { // Allow 1 failure for confirmOrder console.log('šŸŽ‰ All critical tests passed! MCP server is ready.\n'); } else { console.log('āš ļø Some tests failed. Review errors above.\n'); } } runTests().catch(console.error);

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/maven81g/tradestation_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server