# Development Progress
## Current Status
`tested_and_ready`
## Completed
- [x] Project scaffolding with uv
- [x] Dependencies: fastmcp, httpx, pydantic, logfire
- [x] Package structure: src/siigo_mcp/
- [x] auth.py - Token management (24h refresh)
- [x] client.py - Async API client with httpx
- [x] server.py - FastMCP entry with Logfire (conditional)
- [x] tools/reference.py - Taxes, payment types, doc types, warehouses, users
- [x] tools/customers.py - Full CRUD
- [x] tools/products.py - Full CRUD
- [x] tools/invoices.py - Full CRUD + DIAN stamp, PDF, email, annul
- [x] tools/credit_notes.py - List, get, create, PDF
- [x] tools/journals.py - List, get, create
- [x] Dockerfile
- [x] .env.example
- [x] .gitignore
- [x] Claude Code skills (technical, siigo-expert, infrastructure, dev-workflow)
- [x] Fixed: Removed invalid `Depends` pattern (FastMCP uses global client instead)
- [x] Fixed: Made Logfire conditional on LOGFIRE_TOKEN env var
- [x] Verified: Server imports work correctly
- [x] **Dual transport support** (stdio + HTTP):
- `MCP_TRANSPORT=http` for multi-tenant Railway deployment
- `MCP_TRANSPORT=stdio` (default) for local open-source use
- HTTP mode: credentials via headers (X-Siigo-Username, X-Siigo-Access-Key, X-Siigo-Partner-Id)
- stdio mode: credentials from env vars (SIIGO_USERNAME, SIIGO_ACCESS_KEY, SIIGO_PARTNER_ID)
- All 33 tools updated with Context parameter
- Dockerfile updated: EXPOSE 8000, ENV MCP_TRANSPORT=http
- [x] **Dry-run test infrastructure**:
- `DryRunSiigoClient` class that mocks POST/PUT/DELETE
- `DRY_RUN=true` env var to enable dry-run mode
- Pytest fixtures: `siigo_client`, `dry_run_client`
- Test files: `test_reference.py`, `test_dry_run.py`
- Claude Code skill: `.claude/skills/test-agent.md`
- [x] **Safety modes and documentation**:
- `SIIGO_MODE` env var: `read_only` (default), `standard`, `full`
- Tool filtering based on mode (19/30/33 tools)
- README.md with MCP configs for Claude Desktop, Claude Code, Cursor, VS Code
- `docs/GETTING-STARTED.md` non-technical guide
- `tests/test_unit.py` - tests without credentials
- [x] **Local testing verified**:
- Server starts successfully in stdio mode
- Server starts successfully in HTTP mode (port 8000)
- Tool counts verified: read_only=19, standard=30, full=33
- All 10 unit tests passing
- [x] **uvx packaging**:
- Added `[project.scripts]` entry point: `siigo-mcp = siigo_mcp.server:main`
- Added `main()` function to server.py
- Added `tool.uv.package = true` for entry point installation
- Updated README.md and GETTING-STARTED.md with simplified `uvx siigo-mcp` usage
- Tested: `uv run siigo-mcp` works
- [x] **Lazy tools mode** (`SIIGO_LAZY_TOOLS=true`):
- Token optimization: ~5600 tokens (full) → ~310 tokens (lazy)
- Created `src/siigo_mcp/tools/discovery.py` with 3 meta-tools:
- `list_siigo_tools(category?)` - Returns compact index of all tools
- `get_tool_schema(tool_name)` - Returns full schema for a specific tool
- `call_siigo_tool(tool_name, params)` - Executes any tool dynamically
- Updated server.py for conditional tool loading
- Documented in README.md and .env.example
- **Fixed**: Lazy mode now respects SIIGO_MODE filtering (read_only/standard/full)
## In Progress
(none)
## Blockers
(none)
## Next Steps
1. Publish to PyPI: `uv build && uv publish`
2. Deploy to Railway (HTTP mode)
3. Test with real MCP clients (Claude Desktop, Cursor)
## References
- Plan file: `~/.claude/plans/cozy-questing-wozniak.md`
- FastMCP HTTP docs: https://gofastmcp.com/deployment/running-server