@ratio-mcp/dev-server 1.0.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.
Files changed (97) hide show
  1. package/dist/api/developer.d.ts +13 -0
  2. package/dist/api/developer.d.ts.map +1 -0
  3. package/dist/api/developer.js +66 -0
  4. package/dist/api/developer.js.map +1 -0
  5. package/dist/api/oauth.d.ts +36 -0
  6. package/dist/api/oauth.d.ts.map +1 -0
  7. package/dist/api/oauth.js +77 -0
  8. package/dist/api/oauth.js.map +1 -0
  9. package/dist/index.d.ts +3 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +16 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/server.d.ts +6 -0
  14. package/dist/server.d.ts.map +1 -0
  15. package/dist/server.js +57 -0
  16. package/dist/server.js.map +1 -0
  17. package/dist/store/requirements-store.d.ts +8 -0
  18. package/dist/store/requirements-store.d.ts.map +1 -0
  19. package/dist/store/requirements-store.js +67 -0
  20. package/dist/store/requirements-store.js.map +1 -0
  21. package/dist/store/token-store.d.ts +12 -0
  22. package/dist/store/token-store.d.ts.map +1 -0
  23. package/dist/store/token-store.js +94 -0
  24. package/dist/store/token-store.js.map +1 -0
  25. package/dist/templates/backend/.env.example +20 -0
  26. package/dist/templates/backend/nest-cli.json +5 -0
  27. package/dist/templates/backend/package.json +26 -0
  28. package/dist/templates/backend/src/app.module.ts +10 -0
  29. package/dist/templates/backend/src/main.ts +12 -0
  30. package/dist/templates/backend/tsconfig.json +21 -0
  31. package/dist/templates/frontend/.env.example +6 -0
  32. package/dist/templates/frontend/index.html +13 -0
  33. package/dist/templates/frontend/package.json +24 -0
  34. package/dist/templates/frontend/src/App.tsx +32 -0
  35. package/dist/templates/frontend/src/components/Layout.tsx +53 -0
  36. package/dist/templates/frontend/src/context/AuthContext.tsx +59 -0
  37. package/dist/templates/frontend/src/index.css +48 -0
  38. package/dist/templates/frontend/src/main.tsx +16 -0
  39. package/dist/templates/frontend/src/pages/Callback.tsx +53 -0
  40. package/dist/templates/frontend/src/pages/Dashboard.tsx +24 -0
  41. package/dist/templates/frontend/src/pages/Login.tsx +42 -0
  42. package/dist/templates/frontend/src/services/api.ts +48 -0
  43. package/dist/templates/frontend/tsconfig.json +21 -0
  44. package/dist/templates/frontend/vite.config.ts +15 -0
  45. package/dist/tools/app-management.d.ts +3 -0
  46. package/dist/tools/app-management.d.ts.map +1 -0
  47. package/dist/tools/app-management.js +132 -0
  48. package/dist/tools/app-management.js.map +1 -0
  49. package/dist/tools/auth.d.ts +3 -0
  50. package/dist/tools/auth.d.ts.map +1 -0
  51. package/dist/tools/auth.js +164 -0
  52. package/dist/tools/auth.js.map +1 -0
  53. package/dist/tools/build.d.ts +3 -0
  54. package/dist/tools/build.d.ts.map +1 -0
  55. package/dist/tools/build.js +178 -0
  56. package/dist/tools/build.js.map +1 -0
  57. package/dist/tools/codegen.d.ts +3 -0
  58. package/dist/tools/codegen.d.ts.map +1 -0
  59. package/dist/tools/codegen.js +315 -0
  60. package/dist/tools/codegen.js.map +1 -0
  61. package/dist/tools/developer-auth.d.ts +3 -0
  62. package/dist/tools/developer-auth.d.ts.map +1 -0
  63. package/dist/tools/developer-auth.js +87 -0
  64. package/dist/tools/developer-auth.js.map +1 -0
  65. package/dist/tools/index.d.ts +16 -0
  66. package/dist/tools/index.d.ts.map +1 -0
  67. package/dist/tools/index.js +27 -0
  68. package/dist/tools/index.js.map +1 -0
  69. package/dist/tools/lifecycle.d.ts +3 -0
  70. package/dist/tools/lifecycle.d.ts.map +1 -0
  71. package/dist/tools/lifecycle.js +95 -0
  72. package/dist/tools/lifecycle.js.map +1 -0
  73. package/dist/tools/requirements.d.ts +3 -0
  74. package/dist/tools/requirements.d.ts.map +1 -0
  75. package/dist/tools/requirements.js +169 -0
  76. package/dist/tools/requirements.js.map +1 -0
  77. package/dist/tools/scaffold.d.ts +3 -0
  78. package/dist/tools/scaffold.d.ts.map +1 -0
  79. package/dist/tools/scaffold.js +209 -0
  80. package/dist/tools/scaffold.js.map +1 -0
  81. package/dist/tools/submission.d.ts +3 -0
  82. package/dist/tools/submission.d.ts.map +1 -0
  83. package/dist/tools/submission.js +138 -0
  84. package/dist/tools/submission.js.map +1 -0
  85. package/dist/utils/errors.d.ts +34 -0
  86. package/dist/utils/errors.d.ts.map +1 -0
  87. package/dist/utils/errors.js +81 -0
  88. package/dist/utils/errors.js.map +1 -0
  89. package/dist/utils/logger.d.ts +29 -0
  90. package/dist/utils/logger.d.ts.map +1 -0
  91. package/dist/utils/logger.js +74 -0
  92. package/dist/utils/logger.js.map +1 -0
  93. package/dist/utils/zod-to-json.d.ts +7 -0
  94. package/dist/utils/zod-to-json.d.ts.map +1 -0
  95. package/dist/utils/zod-to-json.js +63 -0
  96. package/dist/utils/zod-to-json.js.map +1 -0
  97. package/package.json +31 -0
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Ratio App</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "ratio-app-frontend",
3
+ "private": true,
4
+ "version": "0.1.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "react": "^18.2.0",
13
+ "react-dom": "^18.2.0",
14
+ "react-router-dom": "^6.20.0",
15
+ "axios": "^1.6.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/react": "^18.2.0",
19
+ "@types/react-dom": "^18.2.0",
20
+ "@vitejs/plugin-react": "^4.2.0",
21
+ "typescript": "^5.3.0",
22
+ "vite": "^5.0.0"
23
+ }
24
+ }
@@ -0,0 +1,32 @@
1
+ import { Routes, Route, Navigate } from 'react-router-dom';
2
+ import { useAuth } from './context/AuthContext';
3
+ import Layout from './components/Layout';
4
+ import Dashboard from './pages/Dashboard';
5
+ import Login from './pages/Login';
6
+ import Callback from './pages/Callback';
7
+
8
+ function PrivateRoute({ children }: { children: React.ReactNode }) {
9
+ const { isAuthenticated } = useAuth();
10
+ return isAuthenticated ? <>{children}</> : <Navigate to="/login" />;
11
+ }
12
+
13
+ export default function App() {
14
+ return (
15
+ <Routes>
16
+ <Route path="/login" element={<Login />} />
17
+ <Route path="/callback" element={<Callback />} />
18
+ <Route
19
+ path="/*"
20
+ element={
21
+ <PrivateRoute>
22
+ <Layout>
23
+ <Routes>
24
+ <Route path="/" element={<Dashboard />} />
25
+ </Routes>
26
+ </Layout>
27
+ </PrivateRoute>
28
+ }
29
+ />
30
+ </Routes>
31
+ );
32
+ }
@@ -0,0 +1,53 @@
1
+ import { ReactNode } from 'react';
2
+ import { Link } from 'react-router-dom';
3
+ import { useAuth } from '../context/AuthContext';
4
+
5
+ export default function Layout({ children }: { children: ReactNode }) {
6
+ const { logout, merchantId } = useAuth();
7
+
8
+ return (
9
+ <div style={{ display: 'flex', minHeight: '100vh' }}>
10
+ {/* Sidebar */}
11
+ <aside
12
+ style={{
13
+ width: 240,
14
+ background: '#1a1a2e',
15
+ color: '#fff',
16
+ padding: '1.5rem 1rem',
17
+ display: 'flex',
18
+ flexDirection: 'column',
19
+ }}
20
+ >
21
+ <h2 style={{ fontSize: '1.2rem', marginBottom: '2rem' }}>Ratio App</h2>
22
+ <nav style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
23
+ <Link to="/" style={{ color: '#ccc', padding: '0.5rem', borderRadius: 6 }}>
24
+ Dashboard
25
+ </Link>
26
+ {/* Add more nav links here as you build pages */}
27
+ </nav>
28
+ <div style={{ borderTop: '1px solid #333', paddingTop: '1rem', fontSize: '0.85rem' }}>
29
+ <div style={{ color: '#888', marginBottom: '0.5rem' }}>
30
+ Merchant: {merchantId || '—'}
31
+ </div>
32
+ <button
33
+ onClick={logout}
34
+ style={{
35
+ width: '100%',
36
+ background: '#e74c3c',
37
+ border: 'none',
38
+ padding: '0.5rem',
39
+ borderRadius: 6,
40
+ color: '#fff',
41
+ cursor: 'pointer',
42
+ }}
43
+ >
44
+ Logout
45
+ </button>
46
+ </div>
47
+ </aside>
48
+
49
+ {/* Main Content */}
50
+ <main style={{ flex: 1, padding: '2rem' }}>{children}</main>
51
+ </div>
52
+ );
53
+ }
@@ -0,0 +1,59 @@
1
+ import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
2
+ import { api } from '../services/api';
3
+
4
+ interface AuthState {
5
+ accessToken: string | null;
6
+ merchantId: string | null;
7
+ isAuthenticated: boolean;
8
+ }
9
+
10
+ interface AuthContextType extends AuthState {
11
+ login: (token: string, merchantId: string) => void;
12
+ logout: () => void;
13
+ }
14
+
15
+ const AuthContext = createContext<AuthContextType | null>(null);
16
+
17
+ export function AuthProvider({ children }: { children: ReactNode }) {
18
+ const [auth, setAuth] = useState<AuthState>({
19
+ accessToken: null,
20
+ merchantId: null,
21
+ isAuthenticated: false,
22
+ });
23
+
24
+ useEffect(() => {
25
+ // Check for stored token on mount
26
+ const token = sessionStorage.getItem('ratio_access_token');
27
+ const merchant = sessionStorage.getItem('ratio_merchant_id');
28
+ if (token) {
29
+ setAuth({ accessToken: token, merchantId: merchant, isAuthenticated: true });
30
+ api.setToken(token);
31
+ }
32
+ }, []);
33
+
34
+ const login = (token: string, merchantId: string) => {
35
+ sessionStorage.setItem('ratio_access_token', token);
36
+ sessionStorage.setItem('ratio_merchant_id', merchantId);
37
+ api.setToken(token);
38
+ setAuth({ accessToken: token, merchantId, isAuthenticated: true });
39
+ };
40
+
41
+ const logout = () => {
42
+ sessionStorage.removeItem('ratio_access_token');
43
+ sessionStorage.removeItem('ratio_merchant_id');
44
+ api.setToken(null);
45
+ setAuth({ accessToken: null, merchantId: null, isAuthenticated: false });
46
+ };
47
+
48
+ return (
49
+ <AuthContext.Provider value={{ ...auth, login, logout }}>
50
+ {children}
51
+ </AuthContext.Provider>
52
+ );
53
+ }
54
+
55
+ export function useAuth() {
56
+ const context = useContext(AuthContext);
57
+ if (!context) throw new Error('useAuth must be used within AuthProvider');
58
+ return context;
59
+ }
@@ -0,0 +1,48 @@
1
+ :root {
2
+ font-family: Inter, system-ui, -apple-system, sans-serif;
3
+ line-height: 1.5;
4
+ font-weight: 400;
5
+ color: #213547;
6
+ background-color: #f8f9fa;
7
+ }
8
+
9
+ * {
10
+ margin: 0;
11
+ padding: 0;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ body {
16
+ min-height: 100vh;
17
+ }
18
+
19
+ a {
20
+ color: #646cff;
21
+ text-decoration: none;
22
+ }
23
+
24
+ a:hover {
25
+ color: #535bf2;
26
+ }
27
+
28
+ button {
29
+ border-radius: 8px;
30
+ border: 1px solid transparent;
31
+ padding: 0.6em 1.2em;
32
+ font-size: 1em;
33
+ font-weight: 500;
34
+ font-family: inherit;
35
+ background-color: #646cff;
36
+ color: white;
37
+ cursor: pointer;
38
+ transition: background-color 0.25s;
39
+ }
40
+
41
+ button:hover {
42
+ background-color: #535bf2;
43
+ }
44
+
45
+ button:disabled {
46
+ opacity: 0.6;
47
+ cursor: not-allowed;
48
+ }
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import { BrowserRouter } from 'react-router-dom';
4
+ import App from './App';
5
+ import { AuthProvider } from './context/AuthContext';
6
+ import './index.css';
7
+
8
+ ReactDOM.createRoot(document.getElementById('root')!).render(
9
+ <React.StrictMode>
10
+ <BrowserRouter>
11
+ <AuthProvider>
12
+ <App />
13
+ </AuthProvider>
14
+ </BrowserRouter>
15
+ </React.StrictMode>,
16
+ );
@@ -0,0 +1,53 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { useNavigate, useSearchParams } from 'react-router-dom';
3
+ import { useAuth } from '../context/AuthContext';
4
+
5
+ export default function Callback() {
6
+ const [searchParams] = useSearchParams();
7
+ const navigate = useNavigate();
8
+ const { login } = useAuth();
9
+ const [error, setError] = useState<string | null>(null);
10
+
11
+ useEffect(() => {
12
+ const code = searchParams.get('code');
13
+ if (!code) {
14
+ setError('No authorization code received.');
15
+ return;
16
+ }
17
+
18
+ // Exchange the auth code for tokens via your backend
19
+ fetch(`${import.meta.env.VITE_API_URL || 'http://localhost:3000/api'}/auth/callback`, {
20
+ method: 'POST',
21
+ headers: { 'Content-Type': 'application/json' },
22
+ body: JSON.stringify({ code }),
23
+ })
24
+ .then((res) => res.json())
25
+ .then((data) => {
26
+ if (data.access_token) {
27
+ login(data.access_token, data.merchant_id || '');
28
+ navigate('/');
29
+ } else {
30
+ setError(data.message || 'Token exchange failed.');
31
+ }
32
+ })
33
+ .catch(() => setError('Failed to exchange authorization code.'));
34
+ }, [searchParams, login, navigate]);
35
+
36
+ if (error) {
37
+ return (
38
+ <div style={{ padding: '2rem', textAlign: 'center' }}>
39
+ <h2>Authentication Error</h2>
40
+ <p style={{ color: '#e74c3c' }}>{error}</p>
41
+ <button onClick={() => navigate('/login')} style={{ marginTop: '1rem' }}>
42
+ Back to Login
43
+ </button>
44
+ </div>
45
+ );
46
+ }
47
+
48
+ return (
49
+ <div style={{ padding: '2rem', textAlign: 'center' }}>
50
+ <p>Completing sign-in...</p>
51
+ </div>
52
+ );
53
+ }
@@ -0,0 +1,24 @@
1
+ import { useAuth } from '../context/AuthContext';
2
+
3
+ export default function Dashboard() {
4
+ const { merchantId } = useAuth();
5
+
6
+ return (
7
+ <div>
8
+ <h1 style={{ marginBottom: '1rem' }}>Dashboard</h1>
9
+ <div
10
+ style={{
11
+ background: '#fff',
12
+ borderRadius: 8,
13
+ padding: '1.5rem',
14
+ boxShadow: '0 1px 3px rgba(0,0,0,0.1)',
15
+ }}
16
+ >
17
+ <p>Welcome to your Ratio app. Merchant ID: <strong>{merchantId}</strong></p>
18
+ <p style={{ color: '#666', marginTop: '0.5rem' }}>
19
+ Start building your resource pages — orders, products, customers, etc.
20
+ </p>
21
+ </div>
22
+ </div>
23
+ );
24
+ }
@@ -0,0 +1,42 @@
1
+ export default function Login() {
2
+ const clientId = import.meta.env.VITE_RATIO_CLIENT_ID || '';
3
+ const redirectUri = import.meta.env.VITE_RATIO_REDIRECT_URI || `${window.location.origin}/callback`;
4
+ const dashboardUrl = import.meta.env.VITE_RATIO_DASHBOARD_URL || 'https://dev-developers.dev.gokwik.in';
5
+
6
+ const handleLogin = () => {
7
+ // Redirect to Ratio OAuth consent screen
8
+ const authUrl = `${dashboardUrl}/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code`;
9
+ window.location.href = authUrl;
10
+ };
11
+
12
+ return (
13
+ <div
14
+ style={{
15
+ display: 'flex',
16
+ justifyContent: 'center',
17
+ alignItems: 'center',
18
+ minHeight: '100vh',
19
+ background: '#f0f2f5',
20
+ }}
21
+ >
22
+ <div
23
+ style={{
24
+ background: '#fff',
25
+ padding: '3rem',
26
+ borderRadius: 12,
27
+ boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
28
+ textAlign: 'center',
29
+ maxWidth: 400,
30
+ }}
31
+ >
32
+ <h1 style={{ marginBottom: '0.5rem' }}>Ratio App</h1>
33
+ <p style={{ color: '#666', marginBottom: '2rem' }}>
34
+ Sign in with your Ratio merchant account to continue.
35
+ </p>
36
+ <button onClick={handleLogin} style={{ width: '100%', padding: '0.75rem' }}>
37
+ Sign in with Ratio
38
+ </button>
39
+ </div>
40
+ </div>
41
+ );
42
+ }
@@ -0,0 +1,48 @@
1
+ import axios, { AxiosInstance } from 'axios';
2
+
3
+ class ApiService {
4
+ private client: AxiosInstance;
5
+ private token: string | null = null;
6
+
7
+ constructor() {
8
+ this.client = axios.create({
9
+ baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000/api',
10
+ headers: { 'Content-Type': 'application/json' },
11
+ });
12
+
13
+ // Attach token to every request
14
+ this.client.interceptors.request.use((config) => {
15
+ if (this.token) {
16
+ config.headers.Authorization = `Bearer ${this.token}`;
17
+ }
18
+ return config;
19
+ });
20
+ }
21
+
22
+ setToken(token: string | null) {
23
+ this.token = token;
24
+ }
25
+
26
+ // Generic CRUD helpers — resource pages will use these
27
+ async get<T>(path: string, params?: Record<string, unknown>): Promise<T> {
28
+ const { data } = await this.client.get(path, { params });
29
+ return data;
30
+ }
31
+
32
+ async post<T>(path: string, body?: unknown): Promise<T> {
33
+ const { data } = await this.client.post(path, body);
34
+ return data;
35
+ }
36
+
37
+ async put<T>(path: string, body?: unknown): Promise<T> {
38
+ const { data } = await this.client.put(path, body);
39
+ return data;
40
+ }
41
+
42
+ async delete<T>(path: string): Promise<T> {
43
+ const { data } = await this.client.delete(path);
44
+ return data;
45
+ }
46
+ }
47
+
48
+ export const api = new ApiService();
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "bundler",
9
+ "allowImportingTsExtensions": true,
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true,
12
+ "noEmit": true,
13
+ "strict": true,
14
+ "jsx": "react-jsx",
15
+ "baseUrl": ".",
16
+ "paths": {
17
+ "@/*": ["./src/*"]
18
+ }
19
+ },
20
+ "include": ["src"]
21
+ }
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ server: {
7
+ port: 5173,
8
+ proxy: {
9
+ '/api': {
10
+ target: 'http://localhost:3000',
11
+ changeOrigin: true,
12
+ },
13
+ },
14
+ },
15
+ });
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from './index.js';
2
+ export declare const appManagementTools: ToolDefinition[];
3
+ //# sourceMappingURL=app-management.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-management.d.ts","sourceRoot":"","sources":["../../src/tools/app-management.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,kBAAkB,EAAE,cAAc,EA2H9C,CAAC"}
@@ -0,0 +1,132 @@
1
+ import { z } from 'zod';
2
+ import { developerApiRequest } from '../api/developer.js';
3
+ import { logger } from '../utils/logger.js';
4
+ export const appManagementTools = [
5
+ {
6
+ name: 'create_app',
7
+ description: 'Create a new application in the Ratio Developer Dashboard. Returns app_id, client_id, and client_secret.',
8
+ inputSchema: z.object({
9
+ name: z.string().min(1).max(100).describe('Application name (required)'),
10
+ description: z.string().max(2000).optional().describe('Application description'),
11
+ category_ids: z.array(z.string()).min(1).describe('Category strings (e.g. ["analytics", "marketing"])'),
12
+ redirect_uri: z.string().optional().describe('OAuth callback URL'),
13
+ contact_email: z.string().optional().describe('Contact email'),
14
+ tags: z.array(z.string()).optional().describe('Application tags'),
15
+ icon: z.string().optional().describe('Icon URL'),
16
+ }),
17
+ handler: async (input) => {
18
+ const inp = input;
19
+ logger.info(`Creating application: ${inp.name}`);
20
+ const appData = { name: inp.name, categoryIds: inp.category_ids };
21
+ if (inp.description)
22
+ appData['description'] = inp.description;
23
+ if (inp.redirect_uri)
24
+ appData['redirectUri'] = inp.redirect_uri;
25
+ if (inp.contact_email)
26
+ appData['contactEmail'] = inp.contact_email;
27
+ if (inp.tags)
28
+ appData['tags'] = inp.tags;
29
+ if (inp.icon)
30
+ appData['icon'] = inp.icon;
31
+ const response = await developerApiRequest('POST', '/applications', appData);
32
+ const app = response.data;
33
+ return {
34
+ success: true,
35
+ message: 'Application created successfully',
36
+ application: {
37
+ id: app.id,
38
+ name: app.name,
39
+ slug: app.slug,
40
+ client_id: app.clientId,
41
+ client_secret: app.clientSecret,
42
+ status: app.status,
43
+ },
44
+ next_steps: [
45
+ '1. Save client_id and client_secret securely',
46
+ '2. Call define_app_requirements with scopes',
47
+ '3. Call scaffold_frontend to create the frontend project',
48
+ '4. Build, zip, upload, and submit for review',
49
+ '5. After admin approval: OAuth → scaffold_backend → generate_api_routes',
50
+ ],
51
+ };
52
+ },
53
+ },
54
+ {
55
+ name: 'get_app',
56
+ description: 'Get details of an existing application from the Ratio Developer Dashboard.',
57
+ inputSchema: z.object({
58
+ app_id: z.string().min(1).describe('Application ID to retrieve'),
59
+ }),
60
+ handler: async (input) => {
61
+ const { app_id } = input;
62
+ const response = await developerApiRequest('GET', `/applications/${app_id}`);
63
+ return { success: true, application: response };
64
+ },
65
+ },
66
+ {
67
+ name: 'update_app',
68
+ description: 'Update an existing application. Only provided fields will be updated.',
69
+ inputSchema: z.object({
70
+ app_id: z.string().min(1).describe('Application ID to update'),
71
+ name: z.string().optional().describe('New name'),
72
+ description: z.string().optional().describe('New description'),
73
+ category_ids: z.array(z.string()).optional().describe('New categories'),
74
+ redirect_uri: z.string().optional().describe('New redirect URI'),
75
+ contact_email: z.string().optional().describe('New contact email'),
76
+ tags: z.array(z.string()).optional().describe('New tags'),
77
+ icon: z.string().optional().describe('New icon URL'),
78
+ }),
79
+ handler: async (input) => {
80
+ const inp = input;
81
+ const updateData = {};
82
+ if (inp.name !== undefined)
83
+ updateData['name'] = inp.name;
84
+ if (inp.description !== undefined)
85
+ updateData['description'] = inp.description;
86
+ if (inp.category_ids !== undefined)
87
+ updateData['categoryIds'] = inp.category_ids;
88
+ if (inp.redirect_uri !== undefined)
89
+ updateData['redirectUri'] = inp.redirect_uri;
90
+ if (inp.contact_email !== undefined)
91
+ updateData['contactEmail'] = inp.contact_email;
92
+ if (inp.tags !== undefined)
93
+ updateData['tags'] = inp.tags;
94
+ if (inp.icon !== undefined)
95
+ updateData['icon'] = inp.icon;
96
+ const response = await developerApiRequest('PATCH', `/applications/${inp.app_id}`, updateData);
97
+ return { success: true, message: 'Application updated', application: response };
98
+ },
99
+ },
100
+ {
101
+ name: 'delete_app',
102
+ description: 'Delete an application. This action cannot be undone.',
103
+ inputSchema: z.object({
104
+ app_id: z.string().min(1).describe('Application ID to delete'),
105
+ confirm: z.boolean().describe('Set to true to confirm deletion'),
106
+ }),
107
+ handler: async (input) => {
108
+ const { app_id, confirm } = input;
109
+ if (!confirm)
110
+ return { success: false, message: 'Deletion not confirmed. Set confirm: true.' };
111
+ await developerApiRequest('DELETE', `/applications/${app_id}`);
112
+ return { success: true, message: `Application ${app_id} deleted` };
113
+ },
114
+ },
115
+ {
116
+ name: 'list_apps',
117
+ description: 'List all applications created by the developer.',
118
+ inputSchema: z.object({}),
119
+ handler: async () => {
120
+ const response = await developerApiRequest('GET', '/applications');
121
+ return {
122
+ success: true,
123
+ total: response.data.total,
124
+ applications: response.data.applications.map((app) => ({
125
+ id: app.id, name: app.name, slug: app.slug,
126
+ client_id: app.clientId, status: app.status, description: app.description,
127
+ })),
128
+ };
129
+ },
130
+ },
131
+ ];
132
+ //# sourceMappingURL=app-management.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-management.js","sourceRoot":"","sources":["../../src/tools/app-management.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from './index.js';
2
+ export declare const authTools: ToolDefinition[];
3
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,SAAS,EAAE,cAAc,EAgLrC,CAAC"}