glyphforge 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.
package/README.md ADDED
@@ -0,0 +1,445 @@
1
+ # GlyphForge
2
+
3
+ **Unicode Text Transform API & MCP Server**
4
+
5
+ Transform text into 30+ Unicode styles via REST API and Model Context Protocol (MCP) server. Bold, italic, zalgo, vaporwave, fraktur, and more.
6
+
7
+ ```
8
+ Hello World -> š—›š—²š—¹š—¹š—¼ š—Ŗš—¼š—æš—¹š—± (bold)
9
+ Hello World -> š˜š˜¦š˜­š˜­š˜° š˜žš˜°š˜³š˜­š˜„ (italic)
10
+ Hello World -> š“—š“®š“µš“µš“ø š“¦š“øš“»š“µš“­ (script)
11
+ Hello World -> HĢ·Ģ¢e̵͔l̶̪l̸͚o̤̓ WĢ·oĢør̵l̶dĢ“ (zalgo)
12
+ Hello World -> ļ¼Øļ½…ļ½Œļ½Œļ½ć€€ļ¼·ļ½ļ½’ļ½Œļ½„ (vaporwave)
13
+ ```
14
+
15
+ ## Features
16
+
17
+ - **30+ Text Styles** - Mathematical fonts, enclosures, decorations, encodings
18
+ - **REST API** - Simple HTTP endpoints with JSON responses
19
+ - **MCP Server** - Native integration with Claude, Cursor, and AI tools
20
+ - **Rate Limiting** - Built-in with Upstash Redis or in-memory fallback
21
+ - **Stripe Payments** - Subscription billing for Pro/Business tiers
22
+ - **TypeScript** - Fully typed codebase with strict mode
23
+
24
+ ## Available Styles
25
+
26
+ | Category | Styles |
27
+ |----------|--------|
28
+ | **Mathematical Fonts** | bold, italic, boldItalic, script, boldScript, fraktur, boldFraktur, doubleStruck, monospace |
29
+ | **Enclosures** | circled, negativeCircled, squared, negativeSquared, parenthesized |
30
+ | **Size Variants** | smallCaps, superscript, subscript |
31
+ | **Transformations** | upsideDown, vaporwave, regional, leet |
32
+ | **Encodings** | morse, binary, hex |
33
+ | **Decorations** | zalgo, strikethrough, underline, sparkles, wave |
34
+ | **Aliases** | bubble (=circled), medieval (=fraktur) |
35
+
36
+ ## Quick Start
37
+
38
+ ### Installation
39
+
40
+ ```bash
41
+ # Clone the repository
42
+ git clone https://github.com/glyphforge/glyphforge.git
43
+ cd glyphforge
44
+
45
+ # Install dependencies
46
+ npm install
47
+
48
+ # Set up environment
49
+ cp .env.example .env
50
+ ```
51
+
52
+ ### Run Development Server
53
+
54
+ ```bash
55
+ # Start API server (http://localhost:3000)
56
+ npm run dev
57
+
58
+ # Start MCP server (stdio transport)
59
+ npm run dev:mcp
60
+ ```
61
+
62
+ ### Test the API
63
+
64
+ ```bash
65
+ # List available styles
66
+ curl http://localhost:3000/styles
67
+
68
+ # Register for a free API key
69
+ curl -X POST http://localhost:3000/register \
70
+ -H "Content-Type: application/json" \
71
+ -d '{"name": "My App", "email": "me@example.com"}'
72
+
73
+ # Transform text
74
+ curl -X POST http://localhost:3000/transform \
75
+ -H "Content-Type: application/json" \
76
+ -H "Authorization: Bearer YOUR_API_KEY" \
77
+ -d '{"text": "Hello World", "style": "bold"}'
78
+ ```
79
+
80
+ ## API Reference
81
+
82
+ ### Public Endpoints (No Auth Required)
83
+
84
+ #### `GET /` - API Info
85
+ Returns API name, version, and available features.
86
+
87
+ #### `GET /health` - Health Check
88
+ ```json
89
+ { "status": "ok", "version": "1.0.0" }
90
+ ```
91
+
92
+ #### `GET /styles` - List Styles
93
+ Returns all 30+ available transformation styles with examples.
94
+
95
+ #### `GET /docs` - API Documentation
96
+ Returns full API documentation as JSON.
97
+
98
+ #### `POST /register` - Get Free API Key
99
+ ```bash
100
+ curl -X POST http://localhost:3000/register \
101
+ -H "Content-Type: application/json" \
102
+ -d '{"name": "Project Name", "email": "user@example.com"}'
103
+ ```
104
+
105
+ Response:
106
+ ```json
107
+ {
108
+ "success": true,
109
+ "data": {
110
+ "apiKey": "gf_...",
111
+ "tier": "free",
112
+ "limits": { "requestsPerMonth": 3000, "requestsPerDay": 100 }
113
+ }
114
+ }
115
+ ```
116
+
117
+ ### Authenticated Endpoints
118
+
119
+ Authentication via header or query parameter:
120
+ - Header: `Authorization: Bearer <api-key>`
121
+ - Query: `?api_key=<api-key>`
122
+
123
+ #### `POST /transform` - Transform Text
124
+ ```bash
125
+ curl -X POST http://localhost:3000/transform \
126
+ -H "Authorization: Bearer YOUR_API_KEY" \
127
+ -H "Content-Type: application/json" \
128
+ -d '{"text": "Hello", "style": "bold"}'
129
+ ```
130
+
131
+ Response:
132
+ ```json
133
+ {
134
+ "success": true,
135
+ "data": {
136
+ "original": "Hello",
137
+ "style": "bold",
138
+ "transformed": "š—›š—²š—¹š—¹š—¼"
139
+ }
140
+ }
141
+ ```
142
+
143
+ #### `GET /transform` - Transform via Query
144
+ ```bash
145
+ curl "http://localhost:3000/transform?text=Hello&style=italic&api_key=YOUR_KEY"
146
+ ```
147
+
148
+ #### `POST /transform/all` - All Styles at Once
149
+ ```bash
150
+ curl -X POST http://localhost:3000/transform/all \
151
+ -H "Authorization: Bearer YOUR_API_KEY" \
152
+ -H "Content-Type: application/json" \
153
+ -d '{"text": "Hi"}'
154
+ ```
155
+
156
+ Returns transformations in all 30+ styles.
157
+
158
+ #### `POST /batch` - Batch Transform
159
+ ```bash
160
+ curl -X POST http://localhost:3000/batch \
161
+ -H "Authorization: Bearer YOUR_API_KEY" \
162
+ -H "Content-Type: application/json" \
163
+ -d '{
164
+ "items": [
165
+ {"text": "Hello", "style": "bold"},
166
+ {"text": "World", "style": "italic"}
167
+ ]
168
+ }'
169
+ ```
170
+
171
+ ### Stripe Payment Endpoints
172
+
173
+ #### `POST /stripe/checkout` - Create Checkout Session
174
+ ```json
175
+ {
176
+ "apiKey": "gf_...",
177
+ "plan": "pro",
178
+ "successUrl": "https://yoursite.com/success",
179
+ "cancelUrl": "https://yoursite.com/pricing"
180
+ }
181
+ ```
182
+
183
+ #### `POST /stripe/portal` - Customer Portal
184
+ Manage subscription and billing.
185
+
186
+ #### `GET /stripe/status` - Subscription Status
187
+ Returns current tier, usage, and subscription details.
188
+
189
+ ## MCP Server
190
+
191
+ GlyphForge includes a Model Context Protocol server for AI tool integration.
192
+
193
+ ### Claude Desktop Configuration
194
+
195
+ Add to your `claude_desktop_config.json`:
196
+
197
+ ```json
198
+ {
199
+ "mcpServers": {
200
+ "glyphforge": {
201
+ "command": "npx",
202
+ "args": ["glyphforge-mcp"]
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ ### Available MCP Tools
209
+
210
+ | Tool | Description |
211
+ |------|-------------|
212
+ | `transform_text` | Transform text to a specific Unicode style |
213
+ | `transform_all` | Apply all 30+ styles to text |
214
+ | `list_styles` | List available styles with examples |
215
+ | `batch_transform` | Transform multiple texts at once |
216
+
217
+ ### Usage in Claude
218
+
219
+ Once configured, you can use natural language:
220
+
221
+ > "Transform 'Hello World' to bold"
222
+ > "Show me all Unicode styles for 'GlyphForge'"
223
+ > "Convert this text to zalgo with maxi intensity"
224
+
225
+ ## Project Structure
226
+
227
+ ```
228
+ glyphforge/
229
+ ā”œā”€ā”€ src/
230
+ │ ā”œā”€ā”€ api/
231
+ │ │ ā”œā”€ā”€ index.ts # Hono server setup
232
+ │ │ ā”œā”€ā”€ routes.ts # API endpoints
233
+ │ │ └── middleware/
234
+ │ │ ā”œā”€ā”€ auth.ts # API key authentication
235
+ │ │ └── rate-limit.ts # Rate limiting
236
+ │ ā”œā”€ā”€ mcp/
237
+ │ │ └── server.ts # MCP server implementation
238
+ │ ā”œā”€ā”€ transforms/
239
+ │ │ ā”œā”€ā”€ index.ts # Transform functions
240
+ │ │ └── unicode-maps.ts # Character mappings
241
+ │ ā”œā”€ā”€ db/
242
+ │ │ ā”œā”€ā”€ client.ts # Database queries
243
+ │ │ └── schema.ts # Drizzle ORM schema
244
+ │ └── payments/
245
+ │ └── stripe.ts # Stripe integration
246
+ ā”œā”€ā”€ landing/
247
+ │ └── index.html # Landing page
248
+ ā”œā”€ā”€ package.json
249
+ ā”œā”€ā”€ tsconfig.json
250
+ ā”œā”€ā”€ .env.example
251
+ ā”œā”€ā”€ DEPLOYMENT.md # Deployment guide
252
+ └── PLAN.md # Business plan
253
+ ```
254
+
255
+ ## Environment Variables
256
+
257
+ ```env
258
+ # Server
259
+ PORT=3000
260
+ NODE_ENV=development
261
+
262
+ # Database
263
+ DATABASE_PATH=./glyphforge.db
264
+
265
+ # Stripe (required for payments)
266
+ STRIPE_SECRET_KEY=sk_test_...
267
+ STRIPE_WEBHOOK_SECRET=whsec_...
268
+ STRIPE_PRICE_PRO=price_...
269
+ STRIPE_PRICE_BUSINESS=price_...
270
+
271
+ # Upstash Redis (optional - distributed rate limiting)
272
+ UPSTASH_REDIS_REST_URL=https://...
273
+ UPSTASH_REDIS_REST_TOKEN=...
274
+ ```
275
+
276
+ ## Scripts
277
+
278
+ | Command | Description |
279
+ |---------|-------------|
280
+ | `npm run dev` | Start API server with hot reload |
281
+ | `npm run dev:mcp` | Start MCP server |
282
+ | `npm run build` | Compile TypeScript |
283
+ | `npm run start` | Run production API server |
284
+ | `npm run start:mcp` | Run production MCP server |
285
+ | `npm run test` | Run tests with Vitest |
286
+ | `npm run typecheck` | Type check without emitting |
287
+
288
+ ## Tech Stack
289
+
290
+ - **Runtime**: Node.js 20+
291
+ - **Language**: TypeScript (strict mode)
292
+ - **API Framework**: [Hono](https://hono.dev) - lightweight, edge-ready
293
+ - **Database**: SQLite via [better-sqlite3](https://github.com/WiseLibs/better-sqlite3)
294
+ - **ORM**: [Drizzle](https://orm.drizzle.team)
295
+ - **Payments**: [Stripe](https://stripe.com)
296
+ - **Rate Limiting**: [Upstash](https://upstash.com) Redis (with in-memory fallback)
297
+ - **MCP**: [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/sdk)
298
+ - **Validation**: [Zod](https://zod.dev)
299
+
300
+ ## Pricing Tiers
301
+
302
+ | Tier | Price | Requests | Features |
303
+ |------|-------|----------|----------|
304
+ | **Free** | $0/month | 3,000/month (100/day) | REST API, all styles |
305
+ | **Pro** | $9/month | 10,000/month | REST API + MCP, priority support |
306
+ | **Business** | $29/month | 100,000/month | REST API + MCP, dedicated support |
307
+ | **Enterprise** | Custom | Unlimited | SLA, custom integration |
308
+
309
+ ## Deployment
310
+
311
+ See [DEPLOYMENT.md](./DEPLOYMENT.md) for complete deployment instructions including:
312
+
313
+ - Railway deployment (recommended)
314
+ - Fly.io deployment
315
+ - Stripe configuration
316
+ - Custom domain setup
317
+ - Monitoring and scaling
318
+
319
+ ### Quick Deploy to Railway
320
+
321
+ ```bash
322
+ npm install -g @railway/cli
323
+ railway login
324
+ railway init
325
+ railway variables set PORT=3000 NODE_ENV=production
326
+ railway up
327
+ ```
328
+
329
+ ## Database Schema
330
+
331
+ ### `api_keys` Table
332
+ | Column | Type | Description |
333
+ |--------|------|-------------|
334
+ | id | TEXT | Primary key (nanoid) |
335
+ | key | TEXT | API key (gf_...) |
336
+ | name | TEXT | Project name |
337
+ | email | TEXT | User email |
338
+ | tier | TEXT | free/pro/business/enterprise |
339
+ | stripe_customer_id | TEXT | Stripe customer ID |
340
+ | requests_this_month | INTEGER | Monthly usage counter |
341
+ | requests_total | INTEGER | All-time usage |
342
+
343
+ ### `usage_logs` Table
344
+ | Column | Type | Description |
345
+ |--------|------|-------------|
346
+ | id | TEXT | Primary key |
347
+ | api_key_id | TEXT | Foreign key to api_keys |
348
+ | endpoint | TEXT | API endpoint called |
349
+ | style | TEXT | Style used (if applicable) |
350
+ | input_length | INTEGER | Input text length |
351
+ | response_time | INTEGER | Response time in ms |
352
+
353
+ ## Rate Limits
354
+
355
+ - **Per-minute**: 100 requests (all tiers)
356
+ - **Per-month**: Based on tier (see pricing)
357
+
358
+ Rate limit headers included in responses:
359
+ - `X-RateLimit-Limit`
360
+ - `X-RateLimit-Remaining`
361
+ - `X-RateLimit-Reset`
362
+
363
+ ## Zalgo Options
364
+
365
+ The zalgo style supports intensity levels:
366
+
367
+ ```json
368
+ {
369
+ "text": "Hello",
370
+ "style": "zalgo",
371
+ "zalgoIntensity": "mini" // mini, normal, or maxi
372
+ }
373
+ ```
374
+
375
+ | Intensity | Effect |
376
+ |-----------|--------|
377
+ | `mini` | Subtle corruption |
378
+ | `normal` | Standard zalgo (default) |
379
+ | `maxi` | Maximum chaos |
380
+
381
+ ## Examples
382
+
383
+ ### JavaScript/Node.js
384
+
385
+ ```javascript
386
+ const response = await fetch('https://api.glyphforge.dev/transform', {
387
+ method: 'POST',
388
+ headers: {
389
+ 'Content-Type': 'application/json',
390
+ 'Authorization': 'Bearer gf_your_api_key'
391
+ },
392
+ body: JSON.stringify({
393
+ text: 'Hello World',
394
+ style: 'bold'
395
+ })
396
+ });
397
+
398
+ const { data } = await response.json();
399
+ console.log(data.transformed); // š—›š—²š—¹š—¹š—¼ š—Ŗš—¼š—æš—¹š—±
400
+ ```
401
+
402
+ ### Python
403
+
404
+ ```python
405
+ import requests
406
+
407
+ response = requests.post(
408
+ 'https://api.glyphforge.dev/transform',
409
+ headers={'Authorization': 'Bearer gf_your_api_key'},
410
+ json={'text': 'Hello World', 'style': 'script'}
411
+ )
412
+
413
+ print(response.json()['data']['transformed']) # š“—š“®š“µš“µš“ø š“¦š“øš“»š“µš“­
414
+ ```
415
+
416
+ ### cURL
417
+
418
+ ```bash
419
+ curl -X POST https://api.glyphforge.dev/transform \
420
+ -H "Authorization: Bearer gf_your_api_key" \
421
+ -H "Content-Type: application/json" \
422
+ -d '{"text": "Hello", "style": "vaporwave"}'
423
+ ```
424
+
425
+ ## Contributing
426
+
427
+ 1. Fork the repository
428
+ 2. Create a feature branch (`git checkout -b feature/amazing`)
429
+ 3. Commit changes (`git commit -m 'Add amazing feature'`)
430
+ 4. Push to branch (`git push origin feature/amazing`)
431
+ 5. Open a Pull Request
432
+
433
+ ## License
434
+
435
+ MIT License - see [LICENSE](./LICENSE) for details.
436
+
437
+ ## Support
438
+
439
+ - Documentation: [/docs endpoint](https://api.glyphforge.dev/docs)
440
+ - Issues: [GitHub Issues](https://github.com/glyphforge/glyphforge/issues)
441
+ - Email: support@glyphforge.dev
442
+
443
+ ---
444
+
445
+ Built with care by GlyphForge
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":""}
@@ -0,0 +1,220 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { transform, transformAll, getStylesInfo, STYLES } from '../transforms/index.js';
6
+ const server = new Server({
7
+ name: 'glyphforge',
8
+ version: '1.0.0',
9
+ }, {
10
+ capabilities: {
11
+ tools: {},
12
+ },
13
+ });
14
+ // List available tools
15
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
16
+ return {
17
+ tools: [
18
+ {
19
+ name: 'transform_text',
20
+ description: 'Transform text into a specific Unicode style. Available styles: ' + Object.keys(STYLES).join(', '),
21
+ inputSchema: {
22
+ type: 'object',
23
+ properties: {
24
+ text: {
25
+ type: 'string',
26
+ description: 'The text to transform',
27
+ },
28
+ style: {
29
+ type: 'string',
30
+ description: 'The style to apply',
31
+ enum: Object.keys(STYLES),
32
+ },
33
+ zalgoIntensity: {
34
+ type: 'string',
35
+ description: 'Intensity for zalgo style (mini, normal, maxi)',
36
+ enum: ['mini', 'normal', 'maxi'],
37
+ },
38
+ },
39
+ required: ['text', 'style'],
40
+ },
41
+ },
42
+ {
43
+ name: 'transform_all',
44
+ description: 'Transform text into all available styles at once',
45
+ inputSchema: {
46
+ type: 'object',
47
+ properties: {
48
+ text: {
49
+ type: 'string',
50
+ description: 'The text to transform',
51
+ },
52
+ },
53
+ required: ['text'],
54
+ },
55
+ },
56
+ {
57
+ name: 'list_styles',
58
+ description: 'List all available text transformation styles with examples',
59
+ inputSchema: {
60
+ type: 'object',
61
+ properties: {},
62
+ },
63
+ },
64
+ {
65
+ name: 'batch_transform',
66
+ description: 'Transform multiple texts with multiple styles',
67
+ inputSchema: {
68
+ type: 'object',
69
+ properties: {
70
+ items: {
71
+ type: 'array',
72
+ description: 'Array of transformation requests',
73
+ items: {
74
+ type: 'object',
75
+ properties: {
76
+ text: { type: 'string' },
77
+ style: { type: 'string', enum: Object.keys(STYLES) },
78
+ },
79
+ required: ['text', 'style'],
80
+ },
81
+ },
82
+ },
83
+ required: ['items'],
84
+ },
85
+ },
86
+ ],
87
+ };
88
+ });
89
+ // Handle tool calls
90
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
91
+ const { name, arguments: args } = request.params;
92
+ try {
93
+ switch (name) {
94
+ case 'transform_text': {
95
+ const { text, style, zalgoIntensity } = args;
96
+ if (!text || typeof text !== 'string') {
97
+ throw new Error('Text is required and must be a string');
98
+ }
99
+ if (!style || !Object.keys(STYLES).includes(style)) {
100
+ throw new Error(`Invalid style. Available styles: ${Object.keys(STYLES).join(', ')}`);
101
+ }
102
+ const options = zalgoIntensity ? { intensity: zalgoIntensity } : {};
103
+ const result = transform(text, style, options);
104
+ return {
105
+ content: [
106
+ {
107
+ type: 'text',
108
+ text: JSON.stringify({
109
+ original: text,
110
+ style,
111
+ transformed: result,
112
+ }, null, 2),
113
+ },
114
+ ],
115
+ };
116
+ }
117
+ case 'transform_all': {
118
+ const { text } = args;
119
+ if (!text || typeof text !== 'string') {
120
+ throw new Error('Text is required and must be a string');
121
+ }
122
+ const result = transformAll(text);
123
+ return {
124
+ content: [
125
+ {
126
+ type: 'text',
127
+ text: JSON.stringify({
128
+ original: text,
129
+ transformations: result,
130
+ }, null, 2),
131
+ },
132
+ ],
133
+ };
134
+ }
135
+ case 'list_styles': {
136
+ const styles = getStylesInfo();
137
+ return {
138
+ content: [
139
+ {
140
+ type: 'text',
141
+ text: JSON.stringify({
142
+ totalStyles: styles.length,
143
+ styles: styles.map(s => ({
144
+ name: s.name,
145
+ description: s.description,
146
+ example: s.example,
147
+ })),
148
+ }, null, 2),
149
+ },
150
+ ],
151
+ };
152
+ }
153
+ case 'batch_transform': {
154
+ const { items } = args;
155
+ if (!Array.isArray(items) || items.length === 0) {
156
+ throw new Error('Items array is required and must not be empty');
157
+ }
158
+ const results = items.map((item, index) => {
159
+ try {
160
+ return {
161
+ index,
162
+ original: item.text,
163
+ style: item.style,
164
+ transformed: transform(item.text, item.style),
165
+ success: true,
166
+ };
167
+ }
168
+ catch (error) {
169
+ return {
170
+ index,
171
+ original: item.text,
172
+ style: item.style,
173
+ error: error instanceof Error ? error.message : 'Unknown error',
174
+ success: false,
175
+ };
176
+ }
177
+ });
178
+ return {
179
+ content: [
180
+ {
181
+ type: 'text',
182
+ text: JSON.stringify({
183
+ totalItems: items.length,
184
+ successful: results.filter(r => r.success).length,
185
+ results,
186
+ }, null, 2),
187
+ },
188
+ ],
189
+ };
190
+ }
191
+ default:
192
+ throw new Error(`Unknown tool: ${name}`);
193
+ }
194
+ }
195
+ catch (error) {
196
+ return {
197
+ content: [
198
+ {
199
+ type: 'text',
200
+ text: JSON.stringify({
201
+ error: true,
202
+ message: error instanceof Error ? error.message : 'Unknown error',
203
+ }),
204
+ },
205
+ ],
206
+ isError: true,
207
+ };
208
+ }
209
+ });
210
+ // Start the server
211
+ async function main() {
212
+ const transport = new StdioServerTransport();
213
+ await server.connect(transport);
214
+ console.error('GlyphForge MCP Server running on stdio');
215
+ }
216
+ main().catch((error) => {
217
+ console.error('Fatal error:', error);
218
+ process.exit(1);
219
+ });
220
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}