File indexing completed on 2026-09-28 09:37:31
0001 {% extends 'base.html' %}
0002
0003 {% block title %}API tokens — ePIC Production Monitor{% endblock %}
0004
0005 {% block content %}
0006 <div class="container mt-4" style="max-width: 800px;">
0007 <h2 class="mb-3">API tokens</h2>
0008 <p>A token lets a command-line client such as Claude Code use the MCP endpoint
0009 <code>{{ mcp_url }}</code> and TeamComms as your account. Treat it like a password and revoke it here when it is no longer needed.</p>
0010
0011 {% if new_token %}
0012 <div class="alert alert-success">
0013 <div class="mb-1">New token, shown once. Copy it now:</div>
0014 <code style="font-size: 1.05em; word-break: break-all;">{{ new_token }}</code>
0015 <div class="mt-3 mb-1">Claude Code setup:</div>
0016 <pre class="mb-0" style="white-space: pre-wrap;">claude mcp add --transport http swf-devcloud {{ mcp_url }} --header "Authorization: Bearer {{ new_token }}"</pre>
0017 </div>
0018 {% endif %}
0019
0020 {% if token_error %}<div class="alert alert-danger" role="alert">{{ token_error }}</div>{% endif %}
0021 <form method="post" class="d-flex flex-wrap align-items-center gap-2 mb-4">
0022 {% csrf_token %}
0023 <input type="text" name="label" class="form-control" placeholder="Label, for example: laptop claude code" maxlength="100" style="max-width: 380px;">
0024 <label class="form-check-label"><input type="checkbox" name="teamcomms_ai" class="form-check-input me-1"> AI client in TeamComms</label>
0025 <label>TeamComms service
0026 <select name="teamcomms_service_kind" class="form-select">
0027 <option value="">None</option>
0028 <option value="program">Program / watcher</option>
0029 <option value="connector">Platform connector</option>
0030 </select>
0031 </label>
0032 <button type="submit" class="btn btn-primary">Create token</button>
0033 </form>
0034
0035 <table class="table table-sm align-middle">
0036 <thead><tr><th>Token</th><th>Label</th><th>Created</th><th>Last used</th><th></th></tr></thead>
0037 <tbody>
0038 {% for t in tokens %}
0039 <tr{% if t.revoked %} class="text-muted"{% endif %}>
0040 <td><code>swfr_{{ t.prefix }}…</code></td>
0041 <td>{{ t.label }}{% if t.teamcomms_ai %}<div>TeamComms AI client</div>{% endif %}{% if t.teamcomms_service_kind %}<div>TeamComms {{ t.get_teamcomms_service_kind_display }}</div>{% endif %}</td>
0042 <td>{{ t.created|date:"Y-m-d H:i" }}</td>
0043 <td>{% if t.last_used %}{{ t.last_used|date:"Y-m-d H:i" }}{% else %}never{% endif %}</td>
0044 <td>
0045 {% if t.revoked %}revoked {{ t.revoked|date:"Y-m-d" }}{% else %}
0046 <form method="post" style="display:inline">{% csrf_token %}
0047 <input type="hidden" name="revoke" value="{{ t.pk }}">
0048 <button type="submit" class="btn btn-outline-danger btn-sm">Revoke</button>
0049 </form>
0050 {% endif %}
0051 </td>
0052 </tr>
0053 {% empty %}
0054 <tr><td colspan="5" class="text-muted">No tokens yet.</td></tr>
0055 {% endfor %}
0056 </tbody>
0057 </table>
0058 <p class="text-muted">Requests made with a token reach swf-monitor as your username, exactly as browser requests do.</p>
0059 </div>
0060 {% endblock %}