Back to skills
SKILL.md
Mistral Local Dev Loop
ASecurity'Configure Mistral AI local development with hot reload, testing, and
- 2 stars
- 0 votes
- 0 copies
- 0 views
- Added November 11, 2026
Works with
Security analysis
92/100- Installs packages at runtime which could introduce malicious dependencies
npx -y skills add pauldx/claudifying --skill mistral-local-dev-loop --agent claude-codeAre you the author of Mistral Local Dev Loop?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/pauldx-mistral-local-dev-loop)---
name: mistral-local-dev-loop
description: 'Configure Mistral AI local development with hot reload, testing, and
mocking.
Use when setting up a development environment, configuring test workflows,
or establishing a fast iteration cycle with Mistral AI.
Trigger with phrases like "mistral dev setup", "mistral local development",
"mistral dev environment", "develop with mistral".
'
allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(pnpm:*), Grep
version: 1.0.0
license: MIT
tags:
- saas
- mistral
- testing
- workflow
compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw
---
# Mistral AI Local Dev Loop
## Overview
Set up a fast, reproducible local development workflow for Mistral AI integrations: project scaffold, environment config, hot reload with `tsx`, unit tests with Vitest mocking, and integration tests against the live API.
## Prerequisites
- Completed `mistral-install-auth` setup
- Node.js 18+ with npm/pnpm
- `MISTRAL_API_KEY` set in environment
## Instructions
### Step 1: Project Structure
```
my-mistral-project/
├── src/
│ ├── mistral/
│ │ ├── client.ts # Singleton client
│ │ ├── config.ts # Config with Zod validation
│ │ └── types.ts # TypeScript types
│ └── index.ts
├── tests/
│ ├── unit/
│ │ └── mistral.test.ts
│ └── integration/
│ └── mistral.integration.test.ts
├── .env.local # Local secrets (git-ignored)
├── .env.example # Template for team
├── tsconfig.json
├── vitest.config.ts
└── package.json
```
### Step 2: Package Configuration
**package.json**
```json
{
"type": "module",
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"test": "vitest run",
"test:watch": "vitest",
"test:integration": "vitest run tests/integration/",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@mistralai/mistralai": "^1.0.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"dotenv": "^16.0.0",
"tsx": "^4.0.0",
"typescript": "^5.0.0",
"vitest": "^1.0.0"
}
}
```
**tsconfig.json**
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
```
### Step 3: Environment Setup
```bash
# Create environment template
cat > .env.example << 'EOF'
MISTRAL_API_KEY=your-api-key-here
MISTRAL_MODEL=mistral-small-latest
LOG_LEVEL=debug
EOF
cp .env.example .env.local
echo '.env.local' >> .gitignore
echo '.env' >> .gitignore
```
### Step 4: Client Module
```typescript
// src/mistral/client.ts
import { Mistral } from '@mistralai/mistralai';
import 'dotenv/config';
let instance: Mistral | null = null;
export function getMistralClient(): Mistral {
if (!instance) {
const apiKey = process.env.MISTRAL_API_KEY;
if (!apiKey) throw new Error('MISTRAL_API_KEY not set');
instance = new Mistral({ apiKey, timeoutMs: 30_000 });
}
return instance;
}
export function resetClient(): void {
instance = null;
}
```
### Step 5: Unit Tests with Mocking
**vitest.config.ts**
```typescript
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'node',
include: ['tests/**/*.test.ts'],
coverage: { provider: 'v8', reporter: ['text', 'json'] },
},
});
```
**tests/unit/mistral.test.ts**
```typescript
import { describe, it, expect, vi, beforeEach } from 'vitest';
// Mock the entire SDK
vi.mock('@mistralai/mistralai', () => ({
Mistral: vi.fn().mockImplementation(() => ({
chat: {
complete: vi.fn().mockResolvedValue({
id: 'test-id',
model: 'mistral-small-latest',
choices: [{
index: 0,
message: { role: 'assistant', content: 'Mocked response' },
finishReason: 'stop',
}],
usage: { promptTokens: 10, completionTokens: 5, totalTokens: 15 },
}),
stream: vi.fn().mockImplementation(async function* () {
yield { data: { choices: [{ delta: { content: 'Streamed ' } }] } };
yield { data: { choices: [{ delta: { content: 'response' } }] } };
}),
},
embeddings: {
create: vi.fn().mockResolvedValue({
data: [{ embedding: new Array(1024).fill(0.1) }],
usage: { totalTokens: 5 },
}),
},
models: {
list: vi.fn().mockResolvedValue({ data: [{ id: 'mistral-small-latest' }] }),
},
})),
}));
describe('Mistral Client', () => {
beforeEach(() => { vi.clearAllMocks(); });
it('should complete chat', async () => {
const { Mistral } = await import('@mistralai/mistralai');
const client = new Mistral({ apiKey: 'test' });
const response = await client.chat.complete({
model: 'mistral-small-latest',
messages: [{ role: 'user', content: 'Test' }],
});
expect(response.choices?.[0]?.message?.content).toBe('Mocked response');
expect(response.usage?.totalTokens).toBe(15);
});
it('should generate embeddings', async () => {
const { Mistral } = await import('@mistralai/mistralai');
const client = new Mistral({ apiKey: 'test' });
const response = await client.embeddings.create({
model: 'mistral-embed',
inputs: ['test text'],
});
expect(response.data[0].embedding).toHaveLength(1024);
});
});
```
### Step 6: Integration Test (Live API)
```typescript
// tests/integration/mistral.integration.test.ts
import { describe, it, expect } from 'vitest';
import { Mistral } from '@mistralai/mistralai';
const apiKey = process.env.MISTRAL_API_KEY;
describe.skipIf(!apiKey)('Mistral Integration', () => {
const client = new Mistral({ apiKey: apiKey! });
it('should list models', async () => {
const models = await client.models.list();
expect(models.data?.length).toBeGreaterThan(0);
}, 10_000);
it('should complete chat', async () => {
const response = await client.chat.complete({
model: 'mistral-small-latest',
messages: [{ role: 'user', content: 'Reply with "ok"' }],
maxTokens: 10,
temperature: 0,
});
expect(response.choices?.[0]?.message?.content).toBeTruthy();
}, 15_000);
it('should generate embeddings', async () => {
const response = await client.embeddings.create({
model: 'mistral-embed',
inputs: ['test'],
});
expect(response.data[0].embedding).toHaveLength(1024);
}, 10_000);
});
```
## Output
- Working dev environment with hot reload (`tsx watch`)
- Unit tests with full SDK mocking
- Integration tests against live API (skip when no key)
- Environment variable management with `.env.local`
## Error Handling
| Error | Cause | Solution |
|-------|-------|----------|
| Module not found | Missing dependency | Run `npm install` |
| Env not loaded | Missing .env.local | Copy from .env.example |
| Integration timeout | Slow API response | Increase test timeout |
| Mock type errors | SDK interface changed | Update mock to match current SDK |
## Resources
- [Mistral TypeScript SDK](https://github.com/mistralai/client-ts)
- [Vitest Documentation](https://vitest.dev/)
- [tsx](https://github.com/privatenumber/tsx)
## Next Steps
See `mistral-sdk-patterns` for production-ready code patterns.
Attribution
Related skills
View all in testing →Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.