me3-protocol 2.2.0 → 2.3.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 +96 -77
- package/dist/index.d.ts +23 -3
- package/dist/index.js +85 -8
- package/examples/full.json +10 -2
- package/package.json +1 -1
- package/schema.json +71 -4
package/README.md
CHANGED
|
@@ -1,115 +1,126 @@
|
|
|
1
1
|
# me3 Protocol (me.json)
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
**The place machines check before acting on a person.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`me.json` is a minimal protocol that lets you declare what actions AI agents and services can take on your behalf—and how.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## The Problem
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Machines are already making decisions about people:
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- "Should I book a meeting with this person?"
|
|
12
|
+
- "Can I subscribe them to updates?"
|
|
13
|
+
- "How should I introduce them?"
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
Without an authoritative source, they guess. They scrape. They get it wrong.
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
Schema.org describes _pages_. `me.json` declares _people_—their identity, their preferences, and their **intents**.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
2. **Fallback**: `https://yourdomain.com/.well-known/me`
|
|
19
|
+
## The Solution: Intents
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
The core of `me.json` is the `intents` object—machine-readable declarations of what visitors and agents can do:
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"version": "0.1",
|
|
26
|
+
"name": "Jane Doe",
|
|
27
|
+
"bio": "Creative Director at Studio X",
|
|
28
|
+
"intents": {
|
|
29
|
+
"subscribe": {
|
|
30
|
+
"enabled": true,
|
|
31
|
+
"title": "Design Weekly",
|
|
32
|
+
"description": "Curated design links every Sunday",
|
|
33
|
+
"frequency": "weekly"
|
|
34
|
+
},
|
|
35
|
+
"book": {
|
|
36
|
+
"enabled": true,
|
|
37
|
+
"title": "30-min Consultation",
|
|
38
|
+
"description": "Let's discuss your project",
|
|
39
|
+
"duration": 30,
|
|
40
|
+
"url": "https://cal.com/janedoe"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
28
45
|
|
|
29
|
-
|
|
46
|
+
**Without `me.json`**: An AI asked "Can I book a call with Jane?" has to guess, scrape her site, or fail.
|
|
30
47
|
|
|
31
|
-
The
|
|
48
|
+
**With `me.json`**: The AI reads `intents.book`, confirms it's enabled, and knows exactly where to send the user.
|
|
32
49
|
|
|
33
|
-
|
|
50
|
+
That's the protocol's value: **authority before action**.
|
|
34
51
|
|
|
35
|
-
|
|
52
|
+
## Supported Intents
|
|
36
53
|
|
|
37
|
-
|
|
54
|
+
| Intent | Purpose | Key Fields |
|
|
55
|
+
| :---------- | :--------------------------- | :--------------------------------------------------- |
|
|
56
|
+
| `subscribe` | Newsletter/updates signup | `enabled`, `title`, `description`, `frequency` |
|
|
57
|
+
| `book` | Meeting/consultation booking | `enabled`, `title`, `description`, `url`, `duration` |
|
|
38
58
|
|
|
39
|
-
|
|
40
|
-
| :--------- | :------- | :------- | :------------------------------------------------ |
|
|
41
|
-
| `version` | `string` | **Yes** | Protocol version (currently "0.1"). |
|
|
42
|
-
| `name` | `string` | **Yes** | Your display name. |
|
|
43
|
-
| `handle` | `string` | No | Your preferred username/handle. |
|
|
44
|
-
| `bio` | `string` | No | Short bio (max 500 chars). |
|
|
45
|
-
| `avatar` | `string` | No | URL to your profile picture. |
|
|
46
|
-
| `banner` | `string` | No | URL to a header/banner image. |
|
|
47
|
-
| `location` | `string` | No | Freeform location string (e.g. "Remote"). |
|
|
48
|
-
| `links` | `object` | No | Social links (website, github, twitter, etc.). |
|
|
49
|
-
| `buttons` | `array` | No | Primary actions (e.g., "Book Call", "Subscribe"). |
|
|
50
|
-
| `pages` | `array` | No | Custom content pages. |
|
|
51
|
-
| `footer` | `object` | No | Custom footer config (or `false` to hide). |
|
|
59
|
+
More intents (like `contact` for routing preferences) are planned.
|
|
52
60
|
|
|
53
|
-
|
|
61
|
+
---
|
|
54
62
|
|
|
55
|
-
|
|
63
|
+
## Full Schema
|
|
56
64
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
65
|
+
Beyond intents, `me.json` includes identity and presentation fields:
|
|
66
|
+
|
|
67
|
+
| Field | Type | Required | Description |
|
|
68
|
+
| :--------- | :------- | :------- | :--------------------------------------------------- |
|
|
69
|
+
| `version` | `string` | **Yes** | Protocol version (currently `"0.1"`). |
|
|
70
|
+
| `name` | `string` | **Yes** | Display name. |
|
|
71
|
+
| `handle` | `string` | No | Preferred username/handle. |
|
|
72
|
+
| `bio` | `string` | No | Short bio (max 500 chars). |
|
|
73
|
+
| `avatar` | `string` | No | Profile picture URL. |
|
|
74
|
+
| `banner` | `string` | No | Header/banner image URL. |
|
|
75
|
+
| `location` | `string` | No | Freeform location (e.g., "Berlin" or "Remote"). |
|
|
76
|
+
| `links` | `object` | No | Social links (`website`, `github`, `twitter`, etc.). |
|
|
77
|
+
| `buttons` | `array` | No | Call-to-action buttons for human visitors. |
|
|
78
|
+
| `pages` | `array` | No | Custom content pages (markdown). |
|
|
79
|
+
| `intents` | `object` | No | Machine-actionable declarations (see above). |
|
|
80
|
+
| `footer` | `object` | No | Footer config (or `false` to hide). |
|
|
81
|
+
|
|
82
|
+
See [`examples/full.json`](./examples/full.json) for a complete example.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Hosting & Discovery
|
|
87
|
+
|
|
88
|
+
Your `me.json` must be publicly accessible at:
|
|
79
89
|
|
|
80
|
-
|
|
90
|
+
1. **Primary**: `https://yourdomain.com/me.json`
|
|
91
|
+
2. **Fallback**: `https://yourdomain.com/.well-known/me`
|
|
81
92
|
|
|
82
|
-
|
|
93
|
+
### Requirements
|
|
83
94
|
|
|
84
|
-
- **
|
|
85
|
-
- **
|
|
86
|
-
- **
|
|
87
|
-
- **NOT Reputation / Ranking**: No scoring, ranking, endorsements, verification, or algorithmic ordering.
|
|
95
|
+
- **HTTPS only**
|
|
96
|
+
- **CORS enabled**: Serve with `Access-Control-Allow-Origin: *` so browser-based agents can read it
|
|
97
|
+
- **Content-Type**: `application/json`
|
|
88
98
|
|
|
89
|
-
|
|
99
|
+
---
|
|
90
100
|
|
|
91
|
-
|
|
92
|
-
- **Backwards compatibility**: `0.1` is intended to stay stable. Changes should be additive and conservative.
|
|
93
|
-
- **Extensions**: top-level fields are intentionally strict. If you need custom keys, prefer placing them under `links` (e.g. `"links": { "mastodon": "...", "custom": "..." }`) until the protocol defines a first-class place for extensions.
|
|
101
|
+
## What me.json is NOT
|
|
94
102
|
|
|
95
|
-
|
|
103
|
+
- **NOT authentication** — This is public data. No logins, no private keys.
|
|
104
|
+
- **NOT a social network** — No feeds, no likes, no central server.
|
|
105
|
+
- **NOT a platform** — Host it anywhere: GitHub Pages, Vercel, your own server.
|
|
106
|
+
- **NOT reputation** — No scores, rankings, or verification.
|
|
96
107
|
|
|
97
|
-
|
|
108
|
+
---
|
|
98
109
|
|
|
99
|
-
|
|
110
|
+
## Usage
|
|
111
|
+
|
|
112
|
+
### Install
|
|
100
113
|
|
|
101
114
|
```bash
|
|
102
115
|
npm install me3-protocol
|
|
103
116
|
```
|
|
104
117
|
|
|
118
|
+
### Validate
|
|
119
|
+
|
|
105
120
|
```typescript
|
|
106
121
|
import { validateProfile, parseMe3Json } from "me3-protocol";
|
|
107
122
|
|
|
108
|
-
|
|
109
|
-
const result = validateProfile(myProfileData);
|
|
110
|
-
|
|
111
|
-
// Parse and validate a string
|
|
112
|
-
const result = parseMe3Json(jsonString);
|
|
123
|
+
const result = validateProfile(profileData);
|
|
113
124
|
|
|
114
125
|
if (!result.valid) {
|
|
115
126
|
console.error(result.errors);
|
|
@@ -118,4 +129,12 @@ if (!result.valid) {
|
|
|
118
129
|
|
|
119
130
|
### JSON Schema
|
|
120
131
|
|
|
121
|
-
A standard JSON Schema is available
|
|
132
|
+
A standard JSON Schema is available at [`schema.json`](./schema.json).
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Versioning
|
|
137
|
+
|
|
138
|
+
- **Current version**: `0.1`
|
|
139
|
+
- **Stability**: Additive changes only. Breaking changes require a version bump.
|
|
140
|
+
- **Extensions**: Custom fields should go under `links` until the protocol defines extension points.
|
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,24 @@ export interface Me3IntentSubscribe {
|
|
|
61
61
|
/** How often subscribers will hear from you */
|
|
62
62
|
frequency?: "daily" | "weekly" | "monthly" | "irregular";
|
|
63
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Availability windows for booking.
|
|
66
|
+
* Defines when the person is available for meetings.
|
|
67
|
+
*/
|
|
68
|
+
export interface Me3BookingAvailability {
|
|
69
|
+
/** Timezone for the availability windows (e.g., "America/New_York") */
|
|
70
|
+
timezone: string;
|
|
71
|
+
/** Weekly availability windows by day */
|
|
72
|
+
windows: {
|
|
73
|
+
monday?: string[];
|
|
74
|
+
tuesday?: string[];
|
|
75
|
+
wednesday?: string[];
|
|
76
|
+
thursday?: string[];
|
|
77
|
+
friday?: string[];
|
|
78
|
+
saturday?: string[];
|
|
79
|
+
sunday?: string[];
|
|
80
|
+
};
|
|
81
|
+
}
|
|
64
82
|
/**
|
|
65
83
|
* Booking/scheduling intent.
|
|
66
84
|
* Declares that the person accepts meeting bookings.
|
|
@@ -74,10 +92,12 @@ export interface Me3IntentBook {
|
|
|
74
92
|
description?: string;
|
|
75
93
|
/** Meeting duration in minutes */
|
|
76
94
|
duration?: number;
|
|
77
|
-
/** Booking provider (e.g., "cal.com", "calendly") */
|
|
95
|
+
/** Booking provider (e.g., "cal.com", "calendly") - for external providers */
|
|
78
96
|
provider?: string;
|
|
79
|
-
/** Direct booking URL */
|
|
80
|
-
url
|
|
97
|
+
/** Direct booking URL - for external booking systems */
|
|
98
|
+
url?: string;
|
|
99
|
+
/** Availability windows - for native me3 booking */
|
|
100
|
+
availability?: Me3BookingAvailability;
|
|
81
101
|
}
|
|
82
102
|
/**
|
|
83
103
|
* Intents object - declares what actions visitors/agents can take.
|
package/dist/index.js
CHANGED
|
@@ -396,16 +396,93 @@ function validateProfile(data) {
|
|
|
396
396
|
message: "Book provider must be a string",
|
|
397
397
|
});
|
|
398
398
|
}
|
|
399
|
-
if
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
399
|
+
// URL is optional if availability is set (native me3 booking)
|
|
400
|
+
if (book.url !== undefined) {
|
|
401
|
+
if (typeof book.url !== "string") {
|
|
402
|
+
errors.push({
|
|
403
|
+
field: "intents.book.url",
|
|
404
|
+
message: "Book URL must be a string",
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
else if (!URL_REGEX.test(book.url)) {
|
|
408
|
+
errors.push({
|
|
409
|
+
field: "intents.book.url",
|
|
410
|
+
message: "Book URL must be a valid URL starting with http:// or https://",
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
// Validate availability if present
|
|
415
|
+
if (book.availability !== undefined) {
|
|
416
|
+
if (typeof book.availability !== "object" ||
|
|
417
|
+
book.availability === null) {
|
|
418
|
+
errors.push({
|
|
419
|
+
field: "intents.book.availability",
|
|
420
|
+
message: "Book availability must be an object",
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
const availability = book.availability;
|
|
425
|
+
if (!availability.timezone ||
|
|
426
|
+
typeof availability.timezone !== "string") {
|
|
427
|
+
errors.push({
|
|
428
|
+
field: "intents.book.availability.timezone",
|
|
429
|
+
message: "Availability timezone is required",
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
if (availability.windows !== undefined) {
|
|
433
|
+
if (typeof availability.windows !== "object" ||
|
|
434
|
+
availability.windows === null) {
|
|
435
|
+
errors.push({
|
|
436
|
+
field: "intents.book.availability.windows",
|
|
437
|
+
message: "Availability windows must be an object",
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
const windows = availability.windows;
|
|
442
|
+
const validDays = [
|
|
443
|
+
"monday",
|
|
444
|
+
"tuesday",
|
|
445
|
+
"wednesday",
|
|
446
|
+
"thursday",
|
|
447
|
+
"friday",
|
|
448
|
+
"saturday",
|
|
449
|
+
"sunday",
|
|
450
|
+
];
|
|
451
|
+
const timeWindowRegex = /^\d{2}:\d{2}-\d{2}:\d{2}$/;
|
|
452
|
+
for (const [day, value] of Object.entries(windows)) {
|
|
453
|
+
if (!validDays.includes(day)) {
|
|
454
|
+
errors.push({
|
|
455
|
+
field: `intents.book.availability.windows.${day}`,
|
|
456
|
+
message: `Invalid day: ${day}`,
|
|
457
|
+
});
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
if (!Array.isArray(value)) {
|
|
461
|
+
errors.push({
|
|
462
|
+
field: `intents.book.availability.windows.${day}`,
|
|
463
|
+
message: `Windows for ${day} must be an array`,
|
|
464
|
+
});
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
for (const window of value) {
|
|
468
|
+
if (typeof window !== "string" ||
|
|
469
|
+
!timeWindowRegex.test(window)) {
|
|
470
|
+
errors.push({
|
|
471
|
+
field: `intents.book.availability.windows.${day}`,
|
|
472
|
+
message: `Invalid time window format. Use HH:MM-HH:MM`,
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
404
480
|
}
|
|
405
|
-
|
|
481
|
+
// Either URL or availability must be set for booking to work
|
|
482
|
+
if (!book.url && !book.availability) {
|
|
406
483
|
errors.push({
|
|
407
|
-
field: "intents.book
|
|
408
|
-
message: "Book
|
|
484
|
+
field: "intents.book",
|
|
485
|
+
message: "Book intent requires either a URL (for external booking) or availability (for native booking)",
|
|
409
486
|
});
|
|
410
487
|
}
|
|
411
488
|
}
|
package/examples/full.json
CHANGED
|
@@ -40,8 +40,16 @@
|
|
|
40
40
|
"title": "30-min Consultation",
|
|
41
41
|
"description": "Let's discuss your project",
|
|
42
42
|
"duration": 30,
|
|
43
|
-
"
|
|
44
|
-
|
|
43
|
+
"availability": {
|
|
44
|
+
"timezone": "America/New_York",
|
|
45
|
+
"windows": {
|
|
46
|
+
"monday": ["09:00-12:00", "14:00-17:00"],
|
|
47
|
+
"tuesday": ["09:00-17:00"],
|
|
48
|
+
"wednesday": ["09:00-17:00"],
|
|
49
|
+
"thursday": ["09:00-17:00"],
|
|
50
|
+
"friday": ["09:00-12:00"]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
45
53
|
}
|
|
46
54
|
}
|
|
47
55
|
}
|
package/package.json
CHANGED
package/schema.json
CHANGED
|
@@ -2,6 +2,70 @@
|
|
|
2
2
|
"$ref": "#/definitions/Me3Profile",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"definitions": {
|
|
5
|
+
"Me3BookingAvailability": {
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"description": "Availability windows for booking. Defines when the person is available for meetings.",
|
|
8
|
+
"properties": {
|
|
9
|
+
"timezone": {
|
|
10
|
+
"description": "Timezone for the availability windows (e.g., \"America/New_York\")",
|
|
11
|
+
"type": "string"
|
|
12
|
+
},
|
|
13
|
+
"windows": {
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"description": "Weekly availability windows by day",
|
|
16
|
+
"properties": {
|
|
17
|
+
"friday": {
|
|
18
|
+
"items": {
|
|
19
|
+
"type": "string"
|
|
20
|
+
},
|
|
21
|
+
"type": "array"
|
|
22
|
+
},
|
|
23
|
+
"monday": {
|
|
24
|
+
"items": {
|
|
25
|
+
"type": "string"
|
|
26
|
+
},
|
|
27
|
+
"type": "array"
|
|
28
|
+
},
|
|
29
|
+
"saturday": {
|
|
30
|
+
"items": {
|
|
31
|
+
"type": "string"
|
|
32
|
+
},
|
|
33
|
+
"type": "array"
|
|
34
|
+
},
|
|
35
|
+
"sunday": {
|
|
36
|
+
"items": {
|
|
37
|
+
"type": "string"
|
|
38
|
+
},
|
|
39
|
+
"type": "array"
|
|
40
|
+
},
|
|
41
|
+
"thursday": {
|
|
42
|
+
"items": {
|
|
43
|
+
"type": "string"
|
|
44
|
+
},
|
|
45
|
+
"type": "array"
|
|
46
|
+
},
|
|
47
|
+
"tuesday": {
|
|
48
|
+
"items": {
|
|
49
|
+
"type": "string"
|
|
50
|
+
},
|
|
51
|
+
"type": "array"
|
|
52
|
+
},
|
|
53
|
+
"wednesday": {
|
|
54
|
+
"items": {
|
|
55
|
+
"type": "string"
|
|
56
|
+
},
|
|
57
|
+
"type": "array"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"type": "object"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"required": [
|
|
64
|
+
"timezone",
|
|
65
|
+
"windows"
|
|
66
|
+
],
|
|
67
|
+
"type": "object"
|
|
68
|
+
},
|
|
5
69
|
"Me3Button": {
|
|
6
70
|
"additionalProperties": false,
|
|
7
71
|
"properties": {
|
|
@@ -69,6 +133,10 @@
|
|
|
69
133
|
"additionalProperties": false,
|
|
70
134
|
"description": "Booking/scheduling intent. Declares that the person accepts meeting bookings.",
|
|
71
135
|
"properties": {
|
|
136
|
+
"availability": {
|
|
137
|
+
"$ref": "#/definitions/Me3BookingAvailability",
|
|
138
|
+
"description": "Availability windows - for native me3 booking"
|
|
139
|
+
},
|
|
72
140
|
"description": {
|
|
73
141
|
"description": "What the meeting is about",
|
|
74
142
|
"type": "string"
|
|
@@ -82,7 +150,7 @@
|
|
|
82
150
|
"type": "boolean"
|
|
83
151
|
},
|
|
84
152
|
"provider": {
|
|
85
|
-
"description": "Booking provider (e.g., \"cal.com\", \"calendly\")",
|
|
153
|
+
"description": "Booking provider (e.g., \"cal.com\", \"calendly\") - for external providers",
|
|
86
154
|
"type": "string"
|
|
87
155
|
},
|
|
88
156
|
"title": {
|
|
@@ -90,13 +158,12 @@
|
|
|
90
158
|
"type": "string"
|
|
91
159
|
},
|
|
92
160
|
"url": {
|
|
93
|
-
"description": "Direct booking URL",
|
|
161
|
+
"description": "Direct booking URL - for external booking systems",
|
|
94
162
|
"type": "string"
|
|
95
163
|
}
|
|
96
164
|
},
|
|
97
165
|
"required": [
|
|
98
|
-
"enabled"
|
|
99
|
-
"url"
|
|
166
|
+
"enabled"
|
|
100
167
|
],
|
|
101
168
|
"type": "object"
|
|
102
169
|
},
|