@gera-services/mcp-gera-nexus 0.1.0 → 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 +63 -14
- package/bin/cli.js +11 -1
- package/data/gerahome_providers_yerevan.csv +111 -0
- package/data/gerajobs_providers.csv +21 -0
- package/dist/data.d.ts +92 -0
- package/dist/data.js +307 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +9 -28
- package/dist/intents.d.ts +50 -0
- package/dist/intents.js +94 -0
- package/dist/server.d.ts +31 -0
- package/dist/server.js +315 -71
- package/package.json +22 -18
- package/server.json +7 -5
package/dist/server.js
CHANGED
|
@@ -1,74 +1,318 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"Return product information about GeraNexus \u2014 the open Agentic Commerce Protocol by Gera Services. Use this to learn what GeraNexus is, why it exists, and when the full MCP toolset will ship.",
|
|
33
|
-
{},
|
|
34
|
-
async () => {
|
|
35
|
-
const info = {
|
|
36
|
-
status: "coming-soon",
|
|
37
|
-
product: "GeraNexus",
|
|
38
|
-
tagline: "The Agentic Commerce Protocol",
|
|
39
|
-
description: 'An open protocol extending MCP into transactional territory so any AI agent can negotiate, book, pay, cancel, refund, dispute, and verify completion across real-world services. Gera exposes all 22 verticals (GeraClinic, GeraHome, GeraMarket, GeraEats, GeraRide, GeraCash, and more) as reference implementations. Goal: become "Stripe for agent commerce."',
|
|
40
|
-
category: "Infrastructure / Protocol",
|
|
41
|
-
plannedActions: [
|
|
42
|
-
"negotiate",
|
|
43
|
-
"book",
|
|
44
|
-
"pay",
|
|
45
|
-
"cancel",
|
|
46
|
-
"refund",
|
|
47
|
-
"dispute",
|
|
48
|
-
"verify-completion"
|
|
49
|
-
],
|
|
50
|
-
revenueModel: [
|
|
51
|
-
"2% transaction fee on agent-initiated commerce",
|
|
52
|
-
"Protocol governance fees from third-party marketplaces",
|
|
53
|
-
"Premium tier: higher volume, priority support, dispute SLA"
|
|
54
|
-
],
|
|
55
|
-
launchEstimate: "Q3-Q4 2026",
|
|
56
|
-
learnMore: "https://geranexus.com",
|
|
57
|
-
parentCompany: "Gera Services Ltd (https://gera.services)",
|
|
58
|
-
fullSpec: "https://github.com/geraservicesuk/globetura/blob/master/ceo/strategy/research/five-ideas-for-2030.md"
|
|
59
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* GeraNexus MCP Server (stdio) — the agent ACTION rails.
|
|
3
|
+
*
|
|
4
|
+
* GeraNexus is "the Agentic Commerce Protocol": the transactional layer AI
|
|
5
|
+
* agents use to DO real-world things across Gera's marketplaces on a user's
|
|
6
|
+
* behalf. This MCP server is the agent-facing front door to that protocol —
|
|
7
|
+
* the "do-this-for-me-safely" layer.
|
|
8
|
+
*
|
|
9
|
+
* Two kinds of tools:
|
|
10
|
+
* • SEARCH tools (read-only) — find real home-service providers, jobs, and
|
|
11
|
+
* restaurants. Backed by live Gera APIs where reachable, the UK FSA FHRS
|
|
12
|
+
* open data for restaurants, and bundled real crawled seed data otherwise.
|
|
13
|
+
* Every result is labelled with its data_source.
|
|
14
|
+
* • ACTION tools (consent-first) — create_booking_intent records a
|
|
15
|
+
* structured, human-confirmable INTENT/lead and returns a confirmation id
|
|
16
|
+
* plus a deep-link the human opens to confirm. It does NOT charge, does NOT
|
|
17
|
+
* commit a provider, and NEVER reports a completed transaction. This is the
|
|
18
|
+
* ConsentGate / human-in-the-loop step of the GeraNexus protocol, applied
|
|
19
|
+
* to every action.
|
|
20
|
+
*
|
|
21
|
+
* Honesty contract: an action that cannot truly complete returns a clearly
|
|
22
|
+
* labelled "intent + next-step link", never a faked confirmation.
|
|
23
|
+
*
|
|
24
|
+
* Product: GeraNexus — agentic commerce protocol (a Gera Systems product).
|
|
25
|
+
*/
|
|
26
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
27
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
28
|
+
import { z } from 'zod';
|
|
29
|
+
import { searchHomeServices, searchJobs, searchRestaurants, } from './data.js';
|
|
30
|
+
import { createIntent, getIntent } from './intents.js';
|
|
31
|
+
function asText(payload) {
|
|
60
32
|
return {
|
|
61
|
-
|
|
33
|
+
content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }],
|
|
62
34
|
};
|
|
63
|
-
}
|
|
64
|
-
);
|
|
65
|
-
async function main() {
|
|
66
|
-
const transport = new import_stdio.StdioServerTransport();
|
|
67
|
-
await server.connect(transport);
|
|
68
|
-
console.error("GeraNexus MCP server (placeholder v0.1.0) running on stdio");
|
|
69
35
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
36
|
+
const DATA_SOURCE_LEGEND = {
|
|
37
|
+
live_api: 'Live data from the Gera marketplace production API.',
|
|
38
|
+
live_fhrs: 'Live UK restaurant data from the Food Standards Agency FHRS open API (api.ratings.food.gov.uk).',
|
|
39
|
+
bundled_seed: 'Real crawled seed data bundled with this server (live API was unreachable or empty). These are verified records, not live availability.',
|
|
40
|
+
};
|
|
41
|
+
export function registerTools(server) {
|
|
42
|
+
// ── Tool 1: search_home_services ──────────────────────────────────────────
|
|
43
|
+
server.registerTool('search_home_services', {
|
|
44
|
+
title: 'Search GeraHome home-service providers',
|
|
45
|
+
description: 'Find home-service providers (plumbers, electricians, cleaners, handymen, etc.) on GeraHome. ' +
|
|
46
|
+
'Tries the live GeraHome production API first; if unreachable or empty, falls back to real ' +
|
|
47
|
+
'crawled provider records bundled with this server (currently Yerevan, sourced from List.am/Spyur). ' +
|
|
48
|
+
"Read-only — finds providers; it does not book anything. The result's \"data_source\" field tells " +
|
|
49
|
+
'you whether rows are live or bundled seed. Pass these provider ids to create_booking_intent to ' +
|
|
50
|
+
'start a consent-first booking.',
|
|
51
|
+
inputSchema: {
|
|
52
|
+
category: z
|
|
53
|
+
.string()
|
|
54
|
+
.optional()
|
|
55
|
+
.describe('Service category, e.g. "plumber", "electrician", "cleaner".'),
|
|
56
|
+
city: z.string().optional().describe('City to search in, e.g. "Yerevan".'),
|
|
57
|
+
limit: z
|
|
58
|
+
.number()
|
|
59
|
+
.int()
|
|
60
|
+
.min(1)
|
|
61
|
+
.max(50)
|
|
62
|
+
.optional()
|
|
63
|
+
.describe('Max providers to return (default 10).'),
|
|
64
|
+
},
|
|
65
|
+
}, async ({ category, city, limit }) => {
|
|
66
|
+
const r = await searchHomeServices({ category, city, limit: limit ?? 10 });
|
|
67
|
+
return asText({
|
|
68
|
+
query: { category: category ?? null, city: city ?? null },
|
|
69
|
+
data_source: r.data_source,
|
|
70
|
+
data_source_meaning: DATA_SOURCE_LEGEND[r.data_source],
|
|
71
|
+
note: r.note,
|
|
72
|
+
result_count: r.providers.length,
|
|
73
|
+
providers: r.providers,
|
|
74
|
+
public_url: r.public_url,
|
|
75
|
+
next_step: 'To request a booking, call create_booking_intent with action_kind="home_booking" and a chosen provider id. That creates a consent-first lead for the user to confirm — it does NOT charge or commit.',
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
// ── Tool 2: search_jobs ───────────────────────────────────────────────────
|
|
79
|
+
server.registerTool('search_jobs', {
|
|
80
|
+
title: 'Search GeraJobs job postings',
|
|
81
|
+
description: 'Search jobs on GeraJobs by keyword and location. Tries the live GeraJobs production API first; ' +
|
|
82
|
+
'if unreachable or empty, returns real recruitment-agency / job-board supply partners bundled with ' +
|
|
83
|
+
'this server (clearly labelled — these are where vacancies come from, not individual postings). ' +
|
|
84
|
+
'Read-only. The "data_source" field tells you which you got. To apply, use create_booking_intent ' +
|
|
85
|
+
'with action_kind="job_application" — that creates a consent-first application lead, not a submitted application.',
|
|
86
|
+
inputSchema: {
|
|
87
|
+
query: z
|
|
88
|
+
.string()
|
|
89
|
+
.optional()
|
|
90
|
+
.describe('Keyword, e.g. "software engineer", "nurse", "driver".'),
|
|
91
|
+
location: z
|
|
92
|
+
.string()
|
|
93
|
+
.optional()
|
|
94
|
+
.describe('Location filter, e.g. "London", "GB", "remote".'),
|
|
95
|
+
limit: z
|
|
96
|
+
.number()
|
|
97
|
+
.int()
|
|
98
|
+
.min(1)
|
|
99
|
+
.max(50)
|
|
100
|
+
.optional()
|
|
101
|
+
.describe('Max results to return (default 10).'),
|
|
102
|
+
},
|
|
103
|
+
}, async ({ query, location, limit }) => {
|
|
104
|
+
const r = await searchJobs({ query, location, limit: limit ?? 10 });
|
|
105
|
+
return asText({
|
|
106
|
+
query: { query: query ?? null, location: location ?? null },
|
|
107
|
+
data_source: r.data_source,
|
|
108
|
+
data_source_meaning: DATA_SOURCE_LEGEND[r.data_source],
|
|
109
|
+
note: r.note,
|
|
110
|
+
result_count: r.jobs.length,
|
|
111
|
+
jobs: r.jobs,
|
|
112
|
+
public_url: r.public_url,
|
|
113
|
+
next_step: 'To apply, call create_booking_intent with action_kind="job_application". That creates a consent-first application lead for the user to confirm and submit — it does NOT auto-submit an application.',
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
// ── Tool 3: search_restaurants ────────────────────────────────────────────
|
|
117
|
+
server.registerTool('search_restaurants', {
|
|
118
|
+
title: 'Search restaurants (live UK FHRS data)',
|
|
119
|
+
description: 'Find restaurants for GeraEats, with their current UK Food Hygiene Ratings. Backed by the live ' +
|
|
120
|
+
'Food Standards Agency FHRS open API (api.ratings.food.gov.uk) — genuinely live UK restaurant data, ' +
|
|
121
|
+
'no auth. Filter by city/name and minimum hygiene rating (0-5). Read-only. To place an order, use ' +
|
|
122
|
+
'create_booking_intent with action_kind="restaurant_order" — a consent-first order lead, not a paid order.',
|
|
123
|
+
inputSchema: {
|
|
124
|
+
city: z
|
|
125
|
+
.string()
|
|
126
|
+
.optional()
|
|
127
|
+
.describe('UK city/town/area to search, e.g. "Bristol", "Manchester".'),
|
|
128
|
+
name: z
|
|
129
|
+
.string()
|
|
130
|
+
.optional()
|
|
131
|
+
.describe('Restaurant name to search for, e.g. "Dishoom".'),
|
|
132
|
+
min_rating: z
|
|
133
|
+
.number()
|
|
134
|
+
.int()
|
|
135
|
+
.min(0)
|
|
136
|
+
.max(5)
|
|
137
|
+
.optional()
|
|
138
|
+
.describe('Minimum food hygiene rating (0-5). E.g. 4 = only well-rated places.'),
|
|
139
|
+
limit: z
|
|
140
|
+
.number()
|
|
141
|
+
.int()
|
|
142
|
+
.min(1)
|
|
143
|
+
.max(50)
|
|
144
|
+
.optional()
|
|
145
|
+
.describe('Max restaurants to return (default 10).'),
|
|
146
|
+
},
|
|
147
|
+
}, async ({ city, name, min_rating, limit }) => {
|
|
148
|
+
const r = await searchRestaurants({
|
|
149
|
+
city,
|
|
150
|
+
name,
|
|
151
|
+
min_rating,
|
|
152
|
+
limit: limit ?? 10,
|
|
153
|
+
});
|
|
154
|
+
return asText({
|
|
155
|
+
query: { city: city ?? null, name: name ?? null, min_rating: min_rating ?? null },
|
|
156
|
+
data_source: r.data_source,
|
|
157
|
+
data_source_meaning: DATA_SOURCE_LEGEND[r.data_source],
|
|
158
|
+
note: r.note,
|
|
159
|
+
result_count: r.restaurants.length,
|
|
160
|
+
restaurants: r.restaurants,
|
|
161
|
+
public_url: r.public_url,
|
|
162
|
+
next_step: 'To order, call create_booking_intent with action_kind="restaurant_order". That creates a consent-first order lead for the user to confirm and pay — it does NOT charge.',
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
// ── Tool 4: create_booking_intent ─────────────────────────────────────────
|
|
166
|
+
// The consent-first action rail. Never charges, never commits, never fakes.
|
|
167
|
+
server.registerTool('create_booking_intent', {
|
|
168
|
+
title: 'Create a consent-first booking/action INTENT (no payment)',
|
|
169
|
+
description: "Create a structured, human-confirmable INTENT to act on a Gera marketplace on the user's behalf — " +
|
|
170
|
+
'a home-service booking, a job application, or a restaurant order. ' +
|
|
171
|
+
'IMPORTANT — this is the consent gate: it does NOT take payment, does NOT commit a provider, and does ' +
|
|
172
|
+
'NOT execute the transaction. It records what the user wants, assigns a tracking intent_id, writes an ' +
|
|
173
|
+
'audit entry, and returns a confirmation_url (a deep-link) the HUMAN opens to review and complete the ' +
|
|
174
|
+
'action on the real Gera surface. Present the intent and the confirmation link to the user; tell them ' +
|
|
175
|
+
'plainly that nothing has been booked or paid yet and that they must confirm. Use get_action_status to ' +
|
|
176
|
+
'check an intent later. Never tell the user a booking/order/application is "done" from this tool — it is a lead awaiting their confirmation.',
|
|
177
|
+
inputSchema: {
|
|
178
|
+
action_kind: z
|
|
179
|
+
.enum(['home_booking', 'job_application', 'restaurant_order'])
|
|
180
|
+
.describe('Which marketplace action to create an intent for.'),
|
|
181
|
+
provider_id: z
|
|
182
|
+
.string()
|
|
183
|
+
.optional()
|
|
184
|
+
.describe('Id of the chosen provider/job/restaurant from a search_* tool result.'),
|
|
185
|
+
provider_name: z
|
|
186
|
+
.string()
|
|
187
|
+
.optional()
|
|
188
|
+
.describe('Human-readable name of the chosen provider/job/restaurant.'),
|
|
189
|
+
requested_for: z
|
|
190
|
+
.string()
|
|
191
|
+
.optional()
|
|
192
|
+
.describe('When the user wants it, e.g. "2026-06-20 morning", "ASAP".'),
|
|
193
|
+
contact_name: z
|
|
194
|
+
.string()
|
|
195
|
+
.optional()
|
|
196
|
+
.describe('Name the user wants to book under (kept in the intent for the human to confirm).'),
|
|
197
|
+
notes: z
|
|
198
|
+
.string()
|
|
199
|
+
.optional()
|
|
200
|
+
.describe('Free-text details: the task, the order items, the role applied for, etc.'),
|
|
201
|
+
consent_acknowledged: z
|
|
202
|
+
.boolean()
|
|
203
|
+
.describe('Must be true: confirms the agent has told the user this creates a lead for THEM to confirm, not an executed/paid transaction.'),
|
|
204
|
+
},
|
|
205
|
+
}, async (args) => {
|
|
206
|
+
if (!args.consent_acknowledged) {
|
|
207
|
+
return asText({
|
|
208
|
+
ok: false,
|
|
209
|
+
error: 'consent_required',
|
|
210
|
+
message: 'Refusing to create an intent without consent_acknowledged=true. First tell the user this will create a booking/order/application LEAD that THEY must confirm (no payment is taken here), then call again with consent_acknowledged=true.',
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
const marketplaceByKind = {
|
|
214
|
+
home_booking: 'GeraHome',
|
|
215
|
+
job_application: 'GeraJobs',
|
|
216
|
+
restaurant_order: 'GeraEats',
|
|
217
|
+
};
|
|
218
|
+
const verbByKind = {
|
|
219
|
+
home_booking: 'Home-service booking',
|
|
220
|
+
job_application: 'Job application',
|
|
221
|
+
restaurant_order: 'Restaurant order',
|
|
222
|
+
};
|
|
223
|
+
const kind = args.action_kind;
|
|
224
|
+
const target = args.provider_name ?? args.provider_id ?? 'selected listing';
|
|
225
|
+
const summary = `${verbByKind[kind]} request for "${target}"` +
|
|
226
|
+
(args.requested_for ? `, requested for ${args.requested_for}` : '') +
|
|
227
|
+
'. Awaiting human confirmation — nothing booked or paid yet.';
|
|
228
|
+
const intent = createIntent({
|
|
229
|
+
kind,
|
|
230
|
+
marketplace: marketplaceByKind[kind],
|
|
231
|
+
provider_id: args.provider_id,
|
|
232
|
+
provider_name: args.provider_name,
|
|
233
|
+
summary,
|
|
234
|
+
details: {
|
|
235
|
+
requested_for: args.requested_for ?? null,
|
|
236
|
+
contact_name: args.contact_name ?? null,
|
|
237
|
+
notes: args.notes ?? null,
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
return asText({
|
|
241
|
+
ok: true,
|
|
242
|
+
kind: 'intent',
|
|
243
|
+
is_executed_transaction: false,
|
|
244
|
+
payment_taken: false,
|
|
245
|
+
intent_id: intent.intent_id,
|
|
246
|
+
status: intent.status,
|
|
247
|
+
status_meaning: 'A lead has been recorded. The user must open confirmation_url to review and complete the action. No provider is committed and no money has moved.',
|
|
248
|
+
summary: intent.summary,
|
|
249
|
+
target: intent.target,
|
|
250
|
+
details: intent.details,
|
|
251
|
+
confirmation_url: intent.confirmation_url,
|
|
252
|
+
expires_at: intent.expires_at,
|
|
253
|
+
audit_signature: intent.audit_signature,
|
|
254
|
+
audit_trail: intent.audit_trail,
|
|
255
|
+
present_to_user: `I've prepared a ${verbByKind[kind].toLowerCase()} request (id ${intent.intent_id}). ` +
|
|
256
|
+
`Nothing is booked or paid yet — please confirm it here: ${intent.confirmation_url}`,
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
// ── Tool 5: get_action_status ─────────────────────────────────────────────
|
|
260
|
+
server.registerTool('get_action_status', {
|
|
261
|
+
title: 'Look up a booking/action intent status',
|
|
262
|
+
description: 'Look up the status of an intent created earlier by create_booking_intent, by its intent_id. ' +
|
|
263
|
+
'Returns the current status (pending_human_confirmation | expired | unknown) and the audit trail. ' +
|
|
264
|
+
'Note: intents are tracked per running server session — an id from a different session returns "unknown". ' +
|
|
265
|
+
'This server does NOT poll the marketplace for downstream completion; confirmation/payment happens on the ' +
|
|
266
|
+
'Gera surface via the confirmation_url, outside this tool.',
|
|
267
|
+
inputSchema: {
|
|
268
|
+
intent_id: z
|
|
269
|
+
.string()
|
|
270
|
+
.describe('The intent_id returned by create_booking_intent.'),
|
|
271
|
+
},
|
|
272
|
+
}, async ({ intent_id }) => {
|
|
273
|
+
const intent = getIntent(intent_id);
|
|
274
|
+
if (!intent) {
|
|
275
|
+
return asText({
|
|
276
|
+
intent_id,
|
|
277
|
+
status: 'unknown',
|
|
278
|
+
message: 'No intent with that id in this server session. It may have been created in a different session, or the id is wrong. Intents are not persisted across restarts in this version.',
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
return asText({
|
|
282
|
+
intent_id: intent.intent_id,
|
|
283
|
+
status: intent.status,
|
|
284
|
+
is_executed_transaction: false,
|
|
285
|
+
summary: intent.summary,
|
|
286
|
+
target: intent.target,
|
|
287
|
+
confirmation_url: intent.confirmation_url,
|
|
288
|
+
expires_at: intent.expires_at,
|
|
289
|
+
audit_signature: intent.audit_signature,
|
|
290
|
+
audit_trail: intent.audit_trail,
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/** Construct a fully-configured GeraNexus McpServer (all tools registered). */
|
|
295
|
+
export function createServer() {
|
|
296
|
+
const server = new McpServer({
|
|
297
|
+
name: 'gera-nexus',
|
|
298
|
+
version: '1.0.0',
|
|
299
|
+
});
|
|
300
|
+
registerTools(server);
|
|
301
|
+
return server;
|
|
302
|
+
}
|
|
303
|
+
export const server = createServer();
|
|
304
|
+
export async function main() {
|
|
305
|
+
const transport = new StdioServerTransport();
|
|
306
|
+
await server.connect(transport);
|
|
307
|
+
// stderr only — stdout is the MCP transport.
|
|
308
|
+
console.error('GeraNexus MCP server running on stdio (gera-nexus v1.0.0)');
|
|
309
|
+
}
|
|
310
|
+
const isMain = typeof process !== 'undefined' &&
|
|
311
|
+
process.argv[1] &&
|
|
312
|
+
/server\.js$/.test(process.argv[1]);
|
|
313
|
+
if (isMain) {
|
|
314
|
+
main().catch((err) => {
|
|
315
|
+
console.error('Fatal:', err);
|
|
316
|
+
process.exit(1);
|
|
317
|
+
});
|
|
318
|
+
}
|
package/package.json
CHANGED
|
@@ -1,54 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gera-services/mcp-gera-nexus",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "MCP server
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "GeraNexus MCP server — the agentic-commerce ACTION rails. Lets an AI agent search Gera marketplaces (home services, jobs, restaurants) and create consent-first booking INTENTS on a user's behalf. A Gera Systems product.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/server.js",
|
|
8
|
+
"types": "dist/server.d.ts",
|
|
5
9
|
"mcpName": "io.github.geraservicesuk/mcp-gera-nexus",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
10
|
"bin": {
|
|
9
11
|
"mcp-gera-nexus": "bin/cli.js"
|
|
10
12
|
},
|
|
11
13
|
"files": [
|
|
12
14
|
"dist",
|
|
13
15
|
"bin",
|
|
16
|
+
"data",
|
|
17
|
+
"server.json",
|
|
14
18
|
"README.md",
|
|
15
|
-
"LICENSE"
|
|
16
|
-
"server.json"
|
|
19
|
+
"LICENSE"
|
|
17
20
|
],
|
|
18
21
|
"publishConfig": {
|
|
19
22
|
"access": "public"
|
|
20
23
|
},
|
|
21
24
|
"scripts": {
|
|
22
|
-
"build": "
|
|
25
|
+
"build": "tsc --noCheck",
|
|
23
26
|
"type-check": "tsc --noEmit",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"prepublishOnly": "npm run build"
|
|
27
|
+
"start": "node bin/cli.js",
|
|
28
|
+
"smoke": "node scripts/smoke.mjs"
|
|
27
29
|
},
|
|
28
30
|
"keywords": [
|
|
29
31
|
"mcp",
|
|
30
32
|
"model-context-protocol",
|
|
31
33
|
"ai",
|
|
34
|
+
"ai-agent",
|
|
35
|
+
"agentic-commerce",
|
|
32
36
|
"gera",
|
|
33
37
|
"gera-nexus",
|
|
34
|
-
"
|
|
38
|
+
"booking",
|
|
39
|
+
"marketplace"
|
|
35
40
|
],
|
|
36
41
|
"author": {
|
|
37
|
-
"name": "Gera
|
|
42
|
+
"name": "Gera Systems",
|
|
38
43
|
"email": "engineering@gera.services",
|
|
39
44
|
"url": "https://gera.services"
|
|
40
45
|
},
|
|
41
|
-
"
|
|
46
|
+
"homepage": "https://geranexus.com",
|
|
42
47
|
"repository": {
|
|
43
48
|
"type": "git",
|
|
44
|
-
"url": "https://github.com/geraservicesuk/
|
|
49
|
+
"url": "https://github.com/geraservicesuk/globetura.git",
|
|
50
|
+
"directory": "packages/mcp-gera-nexus"
|
|
45
51
|
},
|
|
46
|
-
"homepage": "https://geranexus.com",
|
|
47
52
|
"bugs": {
|
|
48
|
-
"url": "https://github.com/geraservicesuk/
|
|
53
|
+
"url": "https://github.com/geraservicesuk/globetura/issues"
|
|
49
54
|
},
|
|
50
55
|
"engines": {
|
|
51
|
-
"node": ">=
|
|
56
|
+
"node": ">=20"
|
|
52
57
|
},
|
|
53
58
|
"dependencies": {
|
|
54
59
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
@@ -56,7 +61,6 @@
|
|
|
56
61
|
},
|
|
57
62
|
"devDependencies": {
|
|
58
63
|
"@types/node": "^20.12.0",
|
|
59
|
-
"esbuild": "^0.28.0",
|
|
60
64
|
"typescript": "^5.4.0"
|
|
61
65
|
}
|
|
62
66
|
}
|
package/server.json
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.geraservicesuk/mcp-gera-nexus",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "Search Gera marketplaces and create consent-first booking intents. No payment taken by server.",
|
|
5
|
+
"version": "1.0.0",
|
|
5
6
|
"repository": {
|
|
6
|
-
"url": "https://github.com/geraservicesuk/
|
|
7
|
-
"source": "github"
|
|
7
|
+
"url": "https://github.com/geraservicesuk/globetura",
|
|
8
|
+
"source": "github",
|
|
9
|
+
"subfolder": "packages/mcp-gera-nexus"
|
|
8
10
|
},
|
|
9
|
-
"
|
|
11
|
+
"websiteUrl": "https://geranexus.com",
|
|
10
12
|
"packages": [
|
|
11
13
|
{
|
|
12
14
|
"registryType": "npm",
|
|
13
15
|
"identifier": "@gera-services/mcp-gera-nexus",
|
|
14
|
-
"version": "
|
|
16
|
+
"version": "1.0.0",
|
|
15
17
|
"transport": {
|
|
16
18
|
"type": "stdio"
|
|
17
19
|
},
|