cMCP 0.4.1
Model Context Protocol library in pure C11
Loading...
Searching...
No Matches
cmcp_server.h
Go to the documentation of this file.
1/**
2 * @file cmcp_server.h
3 * @brief Server API: lifecycle, tool/resource/prompt registry,
4 * dispatch, notifications.
5 *
6 * A `cmcp_server_t` owns:
7 *
8 * - The registries for tools, resources, and prompts.
9 * - The dispatch loop driving the worker pool.
10 * - The lifecycle of a single MCP session (handshake → operate →
11 * teardown) against one transport.
12 *
13 * Capabilities (`tools`, `resources`, `prompts`) are auto-advertised
14 * when at least one matching primitive is registered. Server-initiated
15 * notifications go via `cmcp_server_notify` (generic) and the
16 * capability-gated convenience wrappers. Handlers run on a small
17 * worker-pool thread; they get a per-call `cmcp_handler_ctx_t` for
18 * cooperative cancellation, progress reporting, and (in 2025-11-25)
19 * `elicitation/create` round-trips back to the host.
20 *
21 * See `examples/echo-server.c` for a complete minimal server and
22 * `tools/filesystem-mcp/main.c` for a production-shaped one.
23 */
24#ifndef CMCP_SERVER_H
25#define CMCP_SERVER_H
26
27#include "cmcp_json.h"
28#include "cmcp_types.h"
29#include "cmcp_transport.h"
30
31typedef struct cmcp_server cmcp_server_t;
32
33/* Allocate a server. name/version are copied. */
34cmcp_server_t *cmcp_server_new(const char *name, const char *version);
36
37/* Declare what this server can do. Caller's struct is copied. If never
38 * called, defaults are all-zero (no optional capabilities).
39 *
40 * NOTE: the `tools` capability is *also* implicitly declared whenever
41 * one or more tools have been registered via cmcp_server_add_tool().
42 * Set `tools_list_changed = 1` only if you intend to actually emit
43 * `notifications/tools/list_changed` (Phase 2.4). */
45 const cmcp_server_capabilities_t *caps);
46
47/* Optional human-readable description, echoed in the handshake's
48 * `serverInfo.description` (MCP 2025-11-25 Minor 2). The MCP registry's
49 * `server.json` format already carries it; the field now reaches the
50 * peer at handshake time so the host can show it during initialization.
51 * Pass NULL to clear. Returns CMCP_OK or CMCP_ENOMEM. */
52int cmcp_server_set_description(cmcp_server_t *s, const char *description);
53
54/* Read back the client's advertised description, if any (NULL when the
55 * peer didn't send one or the handshake hasn't completed). The returned
56 * pointer is borrowed and valid only as long as the server is. */
58
59/* ====================================================================== */
60/* Handler context */
61/* ====================================================================== */
62
63/* Opaque per-call handle the library passes to every handler. It is the
64 * handler's channel back to the run loop for two things: cooperative
65 * cancellation and progress reporting. Valid only for the duration of
66 * the handler call — do not retain the pointer past it. */
67typedef struct cmcp_handler_ctx cmcp_handler_ctx_t;
68
69/* Non-zero once the peer has asked to cancel this call (sent a
70 * `notifications/cancelled` for this request id) or the handler timeout
71 * has elapsed. A long-running handler should poll this and return early
72 * when set; cancellation is cooperative — a handler that never polls
73 * simply runs to completion. NULL-safe (returns 0). */
75
76/* Emit a `notifications/progress` update for this call. `progress` is
77 * the amount done so far; `total` is the expected total, or negative if
78 * unknown. `message` is an optional human-readable status (may be
79 * NULL). If the caller attached no progressToken this is a no-op
80 * returning CMCP_OK — a handler never has to branch on that. NULL-safe. */
82 double progress, double total,
83 const char *message);
84
85/* Look up a transport-level header for the request being handled,
86 * case-insensitively (e.g. `cmcp_handler_get_header(hctx,
87 * "Authorization")`). Lets a host implement per-tool auth: the MCP
88 * threat model terminates TLS in front of the server, but the bytes have
89 * to reach policy, and this is how a handler sees them.
90 *
91 * Returns a BORROWED pointer valid only for the duration of this handler
92 * call — copy it if you need it longer; never free it. Returns NULL when
93 * the header is absent, the name is NULL, or the transport carries no
94 * headers at all (the stdio transport always returns NULL — there is no
95 * out-of-band metadata channel there).
96 *
97 * Redaction note: this returns the RAW value — the credential scrubber
98 * (CMCP_LOG_REDACT) does not touch it, because the handler is the
99 * consumer of auth policy and must see the real bytes. The scrubber only
100 * masks credential-shaped keys inside a `cmcp_server_log` data payload,
101 * so if a handler chooses to log a fetched token it is still protected
102 * there; the library itself never logs request headers. NULL-safe. */
104 const char *name);
105
106/* Attach a structured result to this tool call. The library wraps it
107 * as `structuredContent` in the tools/call response. If the tool has
108 * an `output_schema`, the value is validated against it before send;
109 * a validation failure surfaces as -32603 INTERNAL_ERROR per spec
110 * ("server MUST provide structuredContent that matches the schema").
111 *
112 * `value` is consumed (caller transfers ownership). Pass NULL to
113 * clear a previously-set value. Calling on a non-tool handler ctx
114 * (resource/prompt) is a no-op — only tool results carry
115 * structuredContent. NULL-safe on hctx. */
117 cmcp_json_t *value);
118
119/* ====================================================================== */
120/* Tool registry */
121/* ====================================================================== */
122
123/* Handler for a `tools/call` invocation.
124 *
125 * `arguments` The parsed `params.arguments` object from the
126 * request. May be NULL if the caller sent no args.
127 * Borrowed — handler must NOT free.
128 * `userdata` Whatever was passed at registration time.
129 * `hctx` Per-call handle — cancellation + progress. See
130 * cmcp_handler_cancelled / cmcp_handler_progress.
131 * `out_content` OUT. Handler must set to an owned cmcp_json_t array
132 * of content items, e.g. [{"type":"text","text":...}].
133 * Library wraps NULL as an empty array. The library
134 * takes ownership on success.
135 * `out_is_error` OUT. Set to non-zero to mark this as a *tool-level*
136 * error (the call ran, but the operation failed —
137 * e.g. file-not-found). The response still carries
138 * `content`; the spec says clients render it as the
139 * error message. JSON-RPC errors are reserved for
140 * *protocol* failures and bypass this path entirely.
141 *
142 * Return CMCP_OK on success. Any non-zero return is treated as an
143 * INTERNAL_ERROR (-32603) and `out_*` values are ignored. */
144typedef int (*cmcp_tool_handler_fn)(const cmcp_json_t *arguments,
145 void *userdata,
146 cmcp_handler_ctx_t *hctx,
147 cmcp_json_t **out_content,
148 int *out_is_error);
149
150/* Tool descriptor (caller-owned, copied by add_tool). */
151typedef struct {
152 const char *name; /* required, unique per server */
153 const char *title; /* optional, human display name */
154 const char *description; /* optional, may be NULL */
155 /* JSON Schema for the input as JSON text. May be NULL. Phase 1.6
156 * will validate inbound `arguments` against this. */
157 const char *input_schema;
158 /* JSON Schema for the structured output as JSON text. May be NULL.
159 * When set, any value the handler attaches via
160 * cmcp_handler_set_structured is validated against this schema
161 * before being sent — a mismatch surfaces as a -32603 internal
162 * error per spec ("server MUST provide structuredContent that
163 * matches"). Independent of `input_schema`. */
164 const char *output_schema;
165 /* Optional icons (MCP 2025-11-25 SEP-973). JSON-text array of icon
166 * descriptors `[{src: string, mimeType?: string, sizes?: [string]}]`.
167 * Parsed eagerly at registration; echoed verbatim in tools/list.
168 * NULL → field omitted from the wire (backward-compat). */
169 const char *icons;
171 void *userdata; /* opaque, kept verbatim */
173
174/* Register a tool. Strings/schema are deep-copied. The schema string
175 * is parsed eagerly: malformed JSON returns CMCP_EPARSE.
176 *
177 * Returns:
178 * CMCP_OK on success
179 * CMCP_EINVAL on missing required fields
180 * CMCP_EPARSE if `input_schema` is non-NULL and not valid JSON
181 * CMCP_EPROTOCOL if a tool with the same name is already registered
182 * CMCP_ENOMEM on allocation failure
183 *
184 * MUST be called BEFORE `cmcp_server_run()`. Adding tools concurrently
185 * with the run loop is unsupported in v0.1.
186 *
187 * ----------------------------------------------------------------------
188 * HANDLER CONTRACT — cancellation is COOPERATIVE.
189 * ----------------------------------------------------------------------
190 * Handlers run in-process on a fixed worker pool (size `CMCP_WORKERS`,
191 * default 4). The library NEVER force-kills a handler: there is no
192 * pthread_cancel, no per-handler thread teardown. The cancel paths
193 * (`notifications/cancelled` from the peer, and the
194 * `CMCP_HANDLER_TIMEOUT_MS` watchdog) only FLAG the call — they flip the
195 * bit that `cmcp_handler_cancelled(hctx)` reads. A handler that never
196 * polls it runs to completion regardless.
197 *
198 * Therefore every handler MUST:
199 * 1. Poll `cmcp_handler_cancelled(hctx)` periodically inside any loop
200 * or before any long/blocking step, and return early when it reads
201 * non-zero. (Returning early is free — the worker discards the
202 * response for an already-cancelled request.)
203 * 2. Not block unboundedly. A handler stuck in `while (1) {}` or an
204 * un-timed blocking syscall burns its worker slot forever. With the
205 * default pool, FOUR such handlers deadlock the whole server — no
206 * further request, not even `initialize`, gets a worker.
207 *
208 * This is a contract on YOU, not a bug in the pool. The pool is bounded
209 * on purpose (predictable footprint, the Pi-class deployment target).
210 *
211 * Coarse memory insurance (opt-in): set `CMCP_HANDLER_RLIMIT_AS_MB` to a
212 * positive integer and the server applies that as a process-wide
213 * `RLIMIT_AS` ceiling at `cmcp_server_run()` entry, so a runaway handler
214 * hits malloc-returns-NULL instead of OOM-killing the box. It is
215 * process-wide and coarse (it also caps the library + host), NOT
216 * per-handler isolation — true out-of-process sandboxing is a separate,
217 * deferred tier. Unset/0 → no limit (default). See docs/architecture.md
218 * "Worker pool & the handler contract". */
220
221/* Convenience: build a content-array containing a single text item.
222 * Caller assigns the result into `*out_content` from a tool handler;
223 * library will free it after emitting the response. Returns NULL on
224 * allocation failure. */
225cmcp_json_t *cmcp_tool_text_content(const char *text);
226
227/* Convenience: build a content-array containing a single resource_link
228 * item — `{type: "resource_link", uri, name, description?, mimeType?}`
229 * per the 2025-11-25 spec. Use when a tool wants to point at a
230 * resource instead of inlining its content. Multiple items can be
231 * appended to a single array via cmcp_json_array_append; use this
232 * helper for the first one and build subsequent ones inline. NULL
233 * uri/name → returns NULL. */
234cmcp_json_t *cmcp_tool_resource_link_content(const char *uri,
235 const char *name,
236 const char *description,
237 const char *mime_type);
238
239/* ====================================================================== */
240/* Resource registry */
241/* ====================================================================== */
242
243/* Handler for a `resources/read` invocation.
244 *
245 * `uri` The URI the caller asked for. Always equals the
246 * resource's registered URI (the dispatcher matches
247 * before invoking). Borrowed.
248 * `userdata` Whatever was passed at registration time.
249 * `hctx` Per-call handle — cancellation + progress. See
250 * cmcp_handler_cancelled / cmcp_handler_progress.
251 * `out_contents` OUT. Owned cmcp_json_t array of content items, e.g.
252 * [{"uri":..., "mimeType":..., "text":...}]. The
253 * library takes ownership on success. NULL is treated
254 * as an empty array.
255 * `out_is_error` OUT. Set to non-zero to mark this as a resource-
256 * level error (analogous to tool-level error). The
257 * wire still carries `contents`; clients render it
258 * as the error message.
259 *
260 * Return CMCP_OK on success. Any non-zero return is treated as an
261 * INTERNAL_ERROR (-32603) and `out_*` values are ignored. */
262typedef int (*cmcp_resource_read_fn)(const char *uri,
263 void *userdata,
264 cmcp_handler_ctx_t *hctx,
265 cmcp_json_t **out_contents,
266 int *out_is_error);
267
268/* Resource descriptor (caller-owned, copied by add_resource). */
269typedef struct {
270 const char *uri; /* required, unique per server */
271 const char *name; /* required, programmatic id */
272 const char *title; /* optional, human display name —
273 * distinct from `name`, which
274 * the spec scopes to identifier
275 * use; `title` is what UIs show */
276 const char *description; /* optional */
277 const char *mime_type; /* optional, e.g. "text/plain" */
278 /* Optional icons (MCP 2025-11-25 SEP-973). Same shape as on tools —
279 * JSON-text array, parsed eagerly, echoed in resources/list. */
280 const char *icons;
282 void *userdata;
284
285/* Register a resource. Strings are deep-copied. Duplicate URIs rejected
286 * with CMCP_EPROTOCOL.
287 *
288 * MUST be called BEFORE cmcp_server_run(). */
290
291/* Convenience: build a contents-array containing a single text item.
292 * mime_type may be NULL. Returns NULL on allocation failure. */
293cmcp_json_t *cmcp_resource_text_contents(const char *uri,
294 const char *mime_type,
295 const char *text);
296
297/* ====================================================================== */
298/* Prompt registry */
299/* ====================================================================== */
300
301/* Handler for a `prompts/get` invocation.
302 *
303 * `arguments` The parsed `params.arguments` object from the
304 * request. May be NULL. Borrowed.
305 * `userdata` Whatever was passed at registration time.
306 * `hctx` Per-call handle — cancellation + progress. See
307 * cmcp_handler_cancelled / cmcp_handler_progress.
308 * `out_messages` OUT. Owned cmcp_json_t array of message objects:
309 * [{"role":"user|assistant", "content":{...}}]. The
310 * library takes ownership on success. NULL is treated
311 * as an empty array.
312 *
313 * Return CMCP_OK on success. Any non-zero return is treated as an
314 * INTERNAL_ERROR (-32603). */
315typedef int (*cmcp_prompt_handler_fn)(const cmcp_json_t *arguments,
316 void *userdata,
317 cmcp_handler_ctx_t *hctx,
318 cmcp_json_t **out_messages);
319
320/* Prompt descriptor (caller-owned, copied by add_prompt). */
321typedef struct {
322 const char *name; /* required, unique per server */
323 const char *title; /* optional, human display name */
324 const char *description; /* optional */
325 /* JSON array text describing arguments, each: {name, description?,
326 * required?}. May be NULL. Server validates required fields are
327 * present at prompts/get time; full schema validation is the
328 * handler's responsibility. */
329 const char *arguments;
330 /* Optional icons (MCP 2025-11-25 SEP-973). Same shape as on tools —
331 * JSON-text array, parsed eagerly, echoed in prompts/list. */
332 const char *icons;
334 void *userdata;
336
338
339/* Convenience: build a single-element messages array containing one
340 * text-content message. role is "user" or "assistant". */
341cmcp_json_t *cmcp_prompt_text_messages(const char *role, const char *text);
342
343/* ====================================================================== */
344/* Run loop */
345/* ====================================================================== */
346
347/* Drive the server on a transport until the transport closes.
348 *
349 * The server reads frames in a loop, parses them as JSON-RPC, and
350 * dispatches them. The handshake (`initialize` request, `initialized`
351 * notification), `tools/list` and `tools/call` are built in. Other
352 * request methods get -32601.
353 *
354 * Does NOT take ownership of the transport — caller closes it after
355 * cmcp_server_run() returns. Returns CMCP_OK on clean shutdown
356 * (transport closed), or a negative cmcp_err_t on misuse. */
357int cmcp_server_run(cmcp_server_t *s, cmcp_transport_t *t);
358
359/* Sugar: open a stdio transport over the calling process's stdin/stdout,
360 * run the server, then close the transport. Equivalent of:
361 *
362 * cmcp_transport_t *t = cmcp_transport_stdio_new();
363 * cmcp_server_run(s, t);
364 * cmcp_transport_close(t);
365 *
366 * Returns CMCP_ENOMEM if the transport can't be allocated; otherwise
367 * propagates the cmcp_server_run() return. */
369
370/* ====================================================================== */
371/* Negotiated peer state */
372/* ====================================================================== */
373
374/* Negotiated client capabilities and identity, valid after the
375 * handshake completes. Pointers returned are owned by the server. */
379
380/* ====================================================================== */
381/* Server-initiated notifications */
382/* ====================================================================== */
383
384/* Emit a JSON-RPC notification on the active transport.
385 *
386 * Valid only between cmcp_server_run() entry and exit; calling before
387 * or after returns CMCP_EINVAL. May be called from a tool/resource/
388 * prompt handler (runs on the run-loop thread) OR from a background
389 * thread; both paths are serialised by the transport's writer mutex.
390 *
391 * For HTTP transports, notifications are routed to held-open SSE
392 * connections; if no client has opened the SSE channel, the
393 * notification is dropped on the floor (the spec allows this — a
394 * client that wants to receive notifications is expected to open
395 * `GET /mcp` first).
396 *
397 * `params` is consumed (may be NULL). */
399 const char *method,
400 cmcp_json_t *params);
401
402/* Capability-gated convenience wrappers for the standard MCP
403 * list-changed and updated notifications.
404 *
405 * Each wrapper checks the corresponding capability flag was opted in
406 * via cmcp_server_set_capabilities(); if not, returns CMCP_EPROTOCOL
407 * (you said you wouldn't emit this — peers may not even be listening).
408 * Otherwise emits the spec-defined method with the spec-defined
409 * (empty or single-key) params shape. */
413
414/* Emit `notifications/resources/updated` for the given URI. Requires
415 * `caps.resources_subscribe = 1` (CMCP_EPROTOCOL otherwise). Silently
416 * no-ops (returns CMCP_OK) if no peer has subscribed to this URI —
417 * keeps the wire quiet for resources nobody cares about. */
419
420/* ====================================================================== */
421/* Structured logging */
422/* ====================================================================== */
423
424/* Emit a `notifications/message` carrying `{level, logger?, data}`.
425 *
426 * Cap-gated: requires `caps.logging = 1` (CMCP_EPROTOCOL otherwise).
427 * Filter-gated: messages below the floor most recently set by the
428 * client's `logging/setLevel` request are silently dropped (returns
429 * CMCP_OK). Pre-setLevel the floor is CMCP_LOG_LEVEL_DEBUG, so
430 * everything passes — the host is expected to dial it down.
431 *
432 * `logger` may be NULL (the field is then omitted from the wire).
433 * `data` may be NULL → empty object on the wire; otherwise it is
434 * consumed (ownership transferred). Forwards the underlying
435 * cmcp_server_notify rc (CMCP_EINVAL pre-run, CMCP_OK if dropped, etc.).
436 *
437 * Thread-safe: may be called from any tool/resource/prompt handler
438 * (on a worker) or from the run-loop thread. */
440 cmcp_log_level_t level,
441 const char *logger,
442 cmcp_json_t *data);
443
444/* ====================================================================== */
445/* Server → client requests */
446/* ====================================================================== */
447
448/* Send a JSON-RPC request from the server to the client and block the
449 * calling thread until the response arrives.
450 *
451 * Intended to be called from a tool/resource/prompt handler running on
452 * the worker pool — the run-loop thread reads the response off the
453 * transport and routes it to this caller's completion record. Calling
454 * from the run-loop thread itself would deadlock (the loop would never
455 * get back to reading frames) so don't do that.
456 *
457 * Valid only between cmcp_server_run() entry and exit. `params` is
458 * consumed (may be NULL).
459 *
460 * On success, *out_response is initialised and owns its fields —
461 * caller must cmcp_rpc_message_clear() it. Inspect ->result vs
462 * ->error to distinguish a successful peer response from a peer-side
463 * JSON-RPC error.
464 *
465 * If `hctx` is non-NULL, this call polls its cancellation flag on a
466 * ~50ms tick and returns CMCP_ECANCELLED if the handler has been
467 * cancelled — so a server-initiated request inside a cancellable tool
468 * call doesn't strand the worker on a peer that's no longer answering.
469 *
470 * Returns:
471 * CMCP_OK response received (success or peer error)
472 * CMCP_EINVAL bad args, or no active transport
473 * CMCP_ENOMEM allocation failure
474 * CMCP_EIO transport closed before the response arrived
475 * CMCP_ECANCELLED hctx was cancelled while waiting */
477 cmcp_handler_ctx_t *hctx,
478 const char *method,
479 cmcp_json_t *params,
480 cmcp_rpc_message_t *out_response);
481
482/* Convenience: ask the peer (the host) for structured input via the
483 * `elicitation/create` request.
484 *
485 * `message` Human-readable prompt (required).
486 * `requested_schema` A flat JSON object describing the shape of the
487 * answer per the MCP spec (string/number/boolean/
488 * enum properties only — no nesting). Consumed on
489 * success; freed on failure. May be NULL — the
490 * library then sends an empty `{"type":"object"}`.
491 * `out_result` OUT. Owned cmcp_json_t object shaped
492 * {"action": "accept"|"decline"|"cancel",
493 * "content"?: ...}. Caller frees via
494 * cmcp_json_free.
495 *
496 * Cap-gated: returns CMCP_EUNSUPPORTED if the peer didn't advertise
497 * `elicitation` in its initialize capabilities.
498 *
499 * On CMCP_OK, `*out_result` is set. On any other return, `*out_result`
500 * is NULL. Forwards the underlying CMCP_ECANCELLED / CMCP_EIO /
501 * CMCP_EINVAL semantics from cmcp_server_send_request. A peer-side
502 * JSON-RPC error response is surfaced as CMCP_EPROTOCOL. */
504 const char *message,
505 cmcp_json_t *requested_schema,
506 cmcp_json_t **out_result);
507
508/* URL-mode elicitation (MCP 2025-11-25 SEP-1036). Instead of a JSON
509 * Schema, the server asks the host to send the user to `url` (e.g.
510 * an OAuth consent screen). The host's reply still has shape
511 * {"action": "accept"|"decline"|"cancel", "content"?: ...}.
512 *
513 * `message` Human-readable prompt explaining why the user should
514 * open the URL (required).
515 * `url` Absolute URL the host should surface (required).
516 * `out_result` OUT. Owned cmcp_json_t object. Caller frees via
517 * cmcp_json_free.
518 *
519 * Cap-gated: returns CMCP_EUNSUPPORTED if the peer didn't advertise
520 * `elicitation.url` (MCP 2025-11-25 added the form/url sub-cap
521 * split — a peer that advertises plain `elicitation` without sub-caps
522 * is treated as form-only for safety, since URL-redirect elicitations
523 * are a meaningfully different trust ask). */
525 const char *message,
526 const char *url,
527 cmcp_json_t **out_result);
528
529#endif
Hand-rolled JSON value tree, parser, and emitter.
int cmcp_server_add_tool(cmcp_server_t *s, const cmcp_tool_t *tool)
int cmcp_server_notify_resources_changed(cmcp_server_t *s)
const char * cmcp_server_client_version(const cmcp_server_t *s)
int cmcp_server_notify_prompts_changed(cmcp_server_t *s)
int cmcp_server_add_resource(cmcp_server_t *s, const cmcp_resource_t *r)
int(* cmcp_prompt_handler_fn)(const cmcp_json_t *arguments, void *userdata, cmcp_handler_ctx_t *hctx, cmcp_json_t **out_messages)
const cmcp_client_capabilities_t * cmcp_server_client_caps(const cmcp_server_t *s)
int cmcp_server_run(cmcp_server_t *s, cmcp_transport_t *t)
struct cmcp_handler_ctx cmcp_handler_ctx_t
Definition cmcp_server.h:67
int cmcp_handler_cancelled(const cmcp_handler_ctx_t *hctx)
int(* cmcp_tool_handler_fn)(const cmcp_json_t *arguments, void *userdata, cmcp_handler_ctx_t *hctx, cmcp_json_t **out_content, int *out_is_error)
int cmcp_server_run_stdio(cmcp_server_t *s)
int cmcp_server_notify(cmcp_server_t *s, const char *method, cmcp_json_t *params)
cmcp_server_t * cmcp_server_new(const char *name, const char *version)
int cmcp_server_notify_tools_changed(cmcp_server_t *s)
int cmcp_server_log(cmcp_server_t *s, cmcp_log_level_t level, const char *logger, cmcp_json_t *data)
struct cmcp_server cmcp_server_t
Definition cmcp_server.h:31
int cmcp_handler_elicit(cmcp_handler_ctx_t *hctx, const char *message, cmcp_json_t *requested_schema, cmcp_json_t **out_result)
void cmcp_server_free(cmcp_server_t *s)
void cmcp_server_set_capabilities(cmcp_server_t *s, const cmcp_server_capabilities_t *caps)
cmcp_json_t * cmcp_prompt_text_messages(const char *role, const char *text)
int(* cmcp_resource_read_fn)(const char *uri, void *userdata, cmcp_handler_ctx_t *hctx, cmcp_json_t **out_contents, int *out_is_error)
int cmcp_server_set_description(cmcp_server_t *s, const char *description)
int cmcp_server_notify_resource_updated(cmcp_server_t *s, const char *uri)
const char * cmcp_handler_get_header(const cmcp_handler_ctx_t *hctx, const char *name)
cmcp_json_t * cmcp_tool_resource_link_content(const char *uri, const char *name, const char *description, const char *mime_type)
int cmcp_handler_progress(cmcp_handler_ctx_t *hctx, double progress, double total, const char *message)
const char * cmcp_server_client_description(const cmcp_server_t *s)
int cmcp_handler_elicit_url(cmcp_handler_ctx_t *hctx, const char *message, const char *url, cmcp_json_t **out_result)
cmcp_json_t * cmcp_tool_text_content(const char *text)
int cmcp_server_send_request(cmcp_server_t *s, cmcp_handler_ctx_t *hctx, const char *method, cmcp_json_t *params, cmcp_rpc_message_t *out_response)
int cmcp_server_add_prompt(cmcp_server_t *s, const cmcp_prompt_t *p)
const char * cmcp_server_client_name(const cmcp_server_t *s)
void cmcp_handler_set_structured(cmcp_handler_ctx_t *hctx, cmcp_json_t *value)
cmcp_json_t * cmcp_resource_text_contents(const char *uri, const char *mime_type, const char *text)
Transport vtable + stdio/HTTP constructors.
JSON-RPC 2.0 message shapes, capability structs, dispatch types.
cmcp_log_level_t
Definition cmcp_types.h:56
const char * name
const char * arguments
const char * description
const char * title
cmcp_prompt_handler_fn handler
const char * icons
const char * mime_type
cmcp_resource_read_fn read
const char * title
const char * name
const char * uri
const char * icons
const char * description
const char * icons
cmcp_tool_handler_fn handler
const char * output_schema
const char * name
void * userdata
const char * description
const char * input_schema
const char * title