Přeskočit na obsah

Tato stránka byla automaticky přeložena z angličtiny, jediného jazyka, ve kterém se tento web píše. Číst originál.

mcp.projection

Kdo odpovídá na `initialize` a s jakými verzemi protokolu; transporty a relace připojené přes každý; obsluhované metody a to, že prompty a notifikace ne; každý nástroj (nebo jen ty s jedním efektem) s jeho schopností, efektem a nápovědami, z nichž se odvozují jeho anotace; nástroje, které zapisují do repozitáře; zdroje; a zda každý klient, kterého distribuce deklaruje, má zde konfiguraci, která spouští server tohoto repozitáře. Čte registr a jeden soubor na deklarovaného klienta; nic nezapisuje.

Kdo odpovídá na `initialize` a s jakými verzemi protokolu; transporty a relace připojené přes každý; obsluhované metody a to, že prompty a notifikace ne; každý nástroj (nebo jen ty s jedním efektem) s jeho schopností, efektem a nápovědami, z nichž se odvozují jeho anotace; nástroje, které zapisují do repozitáře; zdroje; a zda každý klient, kterého distribuce deklaruje, má zde konfiguraci, která spouští server tohoto repozitáře. Čte registr a jeden soubor na deklarovaného klienta; nic nezapisuje.

  • query
  • experimentální
  • modul mcp
  • #mcp
  • #introspection
  • #projections

Zpřístupnění

Kde je tato jedna definice dosažitelná. Absence je explicitní: povrch, který není uveden, ji nenese.

povrchjako
MCPnástroj majordomus_mcp
zdroj majordomus://mcp
HTTPGET /api/v1/mcp operationId mcp.projection
příkazová řádka—

Schémata

Kanonický vstup a výstup z typů Rustu; schéma nástroje MCP a parametry a odpovědi OpenAPI se odvozují z nich.

input · McpProjectionInput

Vstup mcp.projection: které nástroje vypsat. Vše ostatní v odpovědi se týká projekce jako celku a je dáno vždy.

use majordomus_cli::capability::builtin::mcp::McpProjectionInput;
use majordomus_cli::capability::Effect;
let all: McpProjectionInput = serde_json::from_str("{}").unwrap();
assert!(all.effect.is_none());
let writers: McpProjectionInput =
    serde_json::from_str(r#"{"effect":"repository_mutation"}"#).unwrap();
assert_eq!(writers.effect, Some(Effect::RepositoryMutation));
vlastnosttyppovinnépopis
účinek jedno ze 2 ne Vypíše jen nástroje s tímto efektem: read, process_state nebo repository_mutation. Bez hodnoty vypíše každý nástroj.
JSON Schema
{
  "$defs": {
    "ExecutionEffect": {
      "description": "What running a capability changes outside the caller.\n\nClassified, never declared: it follows from the kind, which is the field a declaration\nalready carries. A projection reads this to decide whether to ask before running\nsomething — the Cockpit's confirmation is derived from it — instead of naming\ncapabilities it must treat carefully, which is a list that goes stale the day after it\nis written.",
      "oneOf": [
        {
          "const": "read",
          "description": "Nothing changes. Every query and every resource of this executable.",
          "type": "string"
        },
        {
          "const": "process_state",
          "description": "This process's own memory changes, and nothing outside it.",
          "type": "string"
        },
        {
          "const": "repository_mutation",
          "description": "The repository changes.\n\nFor most of this executable's life nothing classified to this, because no capability\nof any kind wrote to the repository. That day arrived with [ADR 0040]: development\nsemantics are capabilities of this runtime, and the first of them — `plan.transition`\n— stamps a field into an issue's own tracked record. The variant was put on the model\nin advance so that when one did, it would say so *here*, where a projection already\nreads it and a client already asks before running it, rather than in whichever page\nhappens to render its button.\n\nIt is not classified from the kind, because the kind cannot know it: a command that\nannounces a peer and a command that writes a tracked file are the same kind. A\nhandler that writes the repository says so with\n`ExecutionPolicy::writes_repository`, the way one that stops says so with\n`ExecutionPolicy::stoppable`.\n\n[ADR 0040]: https://github.com/korczis/prismatic-majordomus/blob/master/.ai/repo/adrs/0040-development-semantics-are-capabilities-of-one-runtime.md",
          "type": "string"
        }
      ]
    }
  },
  "additionalProperties": false,
  "description": "The input of `mcp.projection`: which tools to list. Everything else in the answer is\nabout the projection as a whole and is always given.\n\n```\nuse majordomus_cli::capability::builtin::mcp::McpProjectionInput;\nuse majordomus_cli::capability::Effect;\nlet all: McpProjectionInput = serde_json::from_str(\"{}\").unwrap();\nassert!(all.effect.is_none());\nlet writers: McpProjectionInput =\n    serde_json::from_str(r#\"{\"effect\":\"repository_mutation\"}\"#).unwrap();\nassert_eq!(writers.effect, Some(Effect::RepositoryMutation));\n```",
  "properties": {
    "effect": {
      "anyOf": [
        {
          "$ref": "#/$defs/ExecutionEffect"
        },
        {
          "type": "null"
        }
      ],
      "description": "List only the tools with this effect: `read`, `process_state` or\n`repository_mutation`. Absent lists every tool."
    }
  },
  "title": "McpProjectionInput",
  "type": "object"
}

výstup · McpProjection

Projekce tohoto registru do MCP v tomto repozitáři.

use majordomus_cli::capability::builtin::mcp::McpProjection;
let p: McpProjection = serde_json::from_value(serde_json::json!({
    "server": { "name": "majordomus", "title": "Majordomus", "version": "0.14.0" },
    "protocol_versions": ["2025-06-18"],
    "transports": [{ "id": "stdio", "reached_by": "majordomus mcp", "attached": 0 }],
    "serving": { "methods": ["initialize"], "tools": true, "resources": true, "prompts": false, "notifications": false },
    "tool_count": 2,
    "tools": [],
    "effects": [{ "effect": "read", "tools": 1 }, { "effect": "repository_mutation", "tools": 1 }],
    "writers": ["majordomus_plan_transition"],
    "resources": { "builtin": 1, "objects": 0, "template": "majordomus://<kind>/<identity>" },
    "launcher_in_repository": false,
    "clients": [],
    "findings": [],
})).unwrap();
// the count is of every tool, whatever the `effect` filter narrowed `tools` to
assert_eq!(p.tool_count, p.effects.iter().map(|e| e.tools).sum::<usize>());
assert!(p.tools.is_empty() && p.writers.len() == 1);
vlastnosttyppovinnépopis
klienti array ano Klienti, pro které distribuce deklaruje konfiguraci, a v jakém stavu každý je.
efekty array ano Nástroje spočítané podle účinku, přítomný je každý účinek.
zjištění array ano Na co by měl člověk reagovat. Prázdné znamená, že není co dělat.
launcher_in_repository boolean ano Zda tento repozitář nese launcher na bin/majordomus-mcp. Kde ho nenese, konfigurace pojmenovává nainstalovaný příkaz téhož jména.
protocol_versions array ano Přijímané verze protokolu, nejnovější první.
zdroje reference ano Zdroje.
server reference ano Kdo odpovídá na initialize.
obsluhuje reference ano Co z protokolu se obsluhuje.
tool_count integer ano Kolik nástrojů registr promítá, ať se filtr ptal na cokoli.
nástroje array ano Požadované nástroje v pořadí registru.
transporty array ano Jak se klient k serveru dostane.
zapisovatelé array ano Nástroje, které zapisují do repozitáře, jménem. Instrukce initialize jmenují tytéž.
JSON Schema
{
  "$defs": {
    "ExecutionEffect": {
      "description": "What running a capability changes outside the caller.\n\nClassified, never declared: it follows from the kind, which is the field a declaration\nalready carries. A projection reads this to decide whether to ask before running\nsomething — the Cockpit's confirmation is derived from it — instead of naming\ncapabilities it must treat carefully, which is a list that goes stale the day after it\nis written.",
      "oneOf": [
        {
          "const": "read",
          "description": "Nothing changes. Every query and every resource of this executable.",
          "type": "string"
        },
        {
          "const": "process_state",
          "description": "This process's own memory changes, and nothing outside it.",
          "type": "string"
        },
        {
          "const": "repository_mutation",
          "description": "The repository changes.\n\nFor most of this executable's life nothing classified to this, because no capability\nof any kind wrote to the repository. That day arrived with [ADR 0040]: development\nsemantics are capabilities of this runtime, and the first of them — `plan.transition`\n— stamps a field into an issue's own tracked record. The variant was put on the model\nin advance so that when one did, it would say so *here*, where a projection already\nreads it and a client already asks before running it, rather than in whichever page\nhappens to render its button.\n\nIt is not classified from the kind, because the kind cannot know it: a command that\nannounces a peer and a command that writes a tracked file are the same kind. A\nhandler that writes the repository says so with\n`ExecutionPolicy::writes_repository`, the way one that stops says so with\n`ExecutionPolicy::stoppable`.\n\n[ADR 0040]: https://github.com/korczis/prismatic-majordomus/blob/master/.ai/repo/adrs/0040-development-semantics-are-capabilities-of-one-runtime.md",
          "type": "string"
        }
      ]
    },
    "ExecutionHints": {
      "description": "What a caller may assume about a call before making it: the four facts MCP names tool\nannotations, held once on the model so that no projection states its own.\n\nClassified by `ExecutionPolicy::hints`, never declared.\n\n```\nuse majordomus_cli::capability::{CapabilityKind, ExecutionPolicy, Hints};\nlet read: Hints = ExecutionPolicy::classify(CapabilityKind::Query).hints();\nassert_eq!(\n    serde_json::to_value(read).unwrap(),\n    serde_json::json!({ \"read_only\": true, \"destructive\": false, \"idempotent\": true, \"open_world\": false })\n);\n```",
      "properties": {
        "destructive": {
          "description": "The call may overwrite or remove something that outlives this process.",
          "type": "boolean"
        },
        "idempotent": {
          "description": "A second identical call changes nothing the first did not.",
          "type": "boolean"
        },
        "open_world": {
          "description": "The call reaches beyond this machine. No handler of this executable does: observing\nthe forge and talking to an advisor are commands a person runs, not capabilities.",
          "type": "boolean"
        },
        "read_only": {
          "description": "The call changes nothing, anywhere.",
          "type": "boolean"
        }
      },
      "required": [
        "read_only",
        "destructive",
        "idempotent",
        "open_world"
      ],
      "type": "object"
    },
    "McpClient": {
      "description": "One client the distribution declares a project-scoped configuration for.\n\n```\nuse majordomus_cli::capability::builtin::mcp::{McpClient, McpClientStanding};\nlet mut clients: Vec<McpClient> = serde_json::from_value(serde_json::json!([\n    { \"id\": \"gemini\", \"title\": \"Gemini CLI\", \"config\": \".gemini/settings.json\", \"standing\": \"absent\" },\n    { \"id\": \"claude-code\", \"title\": \"Claude Code\", \"config\": \".mcp.json\", \"standing\": \"wired\" },\n])).unwrap();\n// ordered by the provider's id, whatever order the distribution declared them in\nmajordomus_cli::order::canonical(&mut clients);\nassert_eq!(clients[0].id, \"claude-code\");\nassert_eq!(clients[0].standing, McpClientStanding::Wired);\n```",
      "properties": {
        "config": {
          "description": "The file it reads, repository-relative.",
          "type": "string"
        },
        "id": {
          "description": "The provider id.",
          "type": "string"
        },
        "standing": {
          "$ref": "#/$defs/McpClientStanding",
          "description": "Where that file stands here."
        },
        "title": {
          "description": "The name a person knows it by.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "title",
        "config",
        "standing"
      ],
      "type": "object"
    },
    "McpClientStanding": {
      "description": "Where a client's project-scoped configuration stands in this repository.\n\n```\nuse majordomus_cli::capability::builtin::mcp::McpClientStanding;\n// the words a caller reads, as they are written on every surface\nassert_eq!(serde_json::to_value(McpClientStanding::Wired).unwrap(), \"wired\");\nassert_eq!(serde_json::to_value(McpClientStanding::Foreign).unwrap(), \"foreign\");\nassert_eq!(serde_json::to_value(McpClientStanding::Absent).unwrap(), \"absent\");\n```",
      "oneOf": [
        {
          "const": "wired",
          "description": "The file exists and names the launcher: this client starts this repository's server.",
          "type": "string"
        },
        {
          "const": "foreign",
          "description": "The file exists and does not name the launcher: the client reads it and starts\nsomething else, or nothing.",
          "type": "string"
        },
        {
          "const": "absent",
          "description": "The file does not exist: this client starts no server here until it is written.",
          "type": "string"
        }
      ]
    },
    "McpEffectCount": {
      "description": "How many tools have one effect.\n\n```\nuse majordomus_cli::capability::builtin::mcp::McpEffectCount;\nuse majordomus_cli::capability::Effect;\nlet c: McpEffectCount =\n    serde_json::from_value(serde_json::json!({ \"effect\": \"read\", \"tools\": 149 })).unwrap();\nassert_eq!((c.effect, c.tools), (Effect::Read, 149));\n```",
      "properties": {
        "effect": {
          "$ref": "#/$defs/ExecutionEffect",
          "description": "The effect."
        },
        "tools": {
          "description": "How many tools have it.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "effect",
        "tools"
      ],
      "type": "object"
    },
    "McpFinding": {
      "description": "Something about the projection a person should act on.\n\n```\nuse majordomus_cli::capability::builtin::mcp::McpFinding;\nlet f: McpFinding = serde_json::from_value(serde_json::json!({\n    \"code\": \"mcp_client_config_foreign\",\n    \"message\": \".mcp.json exists and does not name majordomus-mcp\",\n    \"remedy\": \"add a `majordomus` server to .mcp.json whose command is majordomus-mcp\",\n})).unwrap();\n// a finding always says what to do, not only what is wrong\nassert!(!f.code.is_empty() && !f.remedy.is_empty());\n```",
      "properties": {
        "code": {
          "description": "The stable code.",
          "type": "string"
        },
        "message": {
          "description": "What is wrong.",
          "type": "string"
        },
        "remedy": {
          "description": "What to do about it.",
          "type": "string"
        }
      },
      "required": [
        "code",
        "message",
        "remedy"
      ],
      "type": "object"
    },
    "McpResourceSummary": {
      "description": "The resources a client can read.\n\n```\nuse majordomus_cli::capability::builtin::mcp::McpResourceSummary;\nlet r: McpResourceSummary = serde_json::from_value(serde_json::json!({\n    \"builtin\": 54, \"objects\": 1742, \"template\": \"majordomus://<kind>/<identity>\",\n})).unwrap();\n// the two counts together are the length of `resources/list`\nassert_eq!(r.builtin + r.objects, 1796);\n```",
      "properties": {
        "builtin": {
          "description": "Resources a builtin capability answers.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "objects": {
          "description": "Objects of this repository's layer, each one more resource.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "template": {
          "description": "The URI shape of an object's resource.",
          "type": "string"
        }
      },
      "required": [
        "builtin",
        "objects",
        "template"
      ],
      "type": "object"
    },
    "McpServerIdentity": {
      "description": "Who answers `initialize`, as it answers.\n\n```\nuse majordomus_cli::capability::builtin::mcp::McpServerIdentity;\nlet s: McpServerIdentity = serde_json::from_value(serde_json::json!({\n    \"name\": \"majordomus\", \"title\": \"Majordomus\", \"version\": \"0.14.0\",\n})).unwrap();\n// the version is the executable's: the protocol adapter has none of its own to drift\nassert_eq!((s.name.as_str(), s.version.as_str()), (\"majordomus\", \"0.14.0\"));\n```",
      "properties": {
        "name": {
          "description": "The server name.",
          "type": "string"
        },
        "title": {
          "description": "The name a person reads.",
          "type": "string"
        },
        "version": {
          "description": "The version: this executable's, never one of the protocol adapter's own.",
          "type": "string"
        }
      },
      "required": [
        "name",
        "title",
        "version"
      ],
      "type": "object"
    },
    "McpServing": {
      "description": "What the server serves of the protocol, and what it does not.\n\n```\nuse majordomus_cli::capability::builtin::mcp::McpServing;\nlet s: McpServing = serde_json::from_value(serde_json::json!({\n    \"methods\": [\"initialize\", \"tools/call\"], \"tools\": true, \"resources\": true,\n    \"prompts\": false, \"notifications\": false,\n})).unwrap();\n// what is not served is stated, so a client does not learn it from a refusal\nassert!(s.tools && !s.prompts && !s.notifications);\nassert!(!s.methods.iter().any(|m| m.starts_with(\"prompts/\")));\n```",
      "properties": {
        "methods": {
          "description": "The methods a request may name. Anything else is answered `-32601`.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "notifications": {
          "description": "Subscriptions and list-change notifications. Not served: this server sends nothing\nunasked.",
          "type": "boolean"
        },
        "prompts": {
          "description": "Prompts. Not served: the repository's prompt assets are resources, because a prompt\nserved unrendered would read as finished.",
          "type": "boolean"
        },
        "resources": {
          "description": "Resources: every capability that declares one, and every object of the layer.",
          "type": "boolean"
        },
        "tools": {
          "description": "Tools: every capability that declares one.",
          "type": "boolean"
        }
      },
      "required": [
        "methods",
        "tools",
        "resources",
        "prompts",
        "notifications"
      ],
      "type": "object"
    },
    "McpToolEntry": {
      "description": "One tool, as the registry projects it.\n\n```\nuse majordomus_cli::capability::builtin::mcp::McpToolEntry;\nuse majordomus_cli::capability::Effect;\nlet t: McpToolEntry = serde_json::from_value(serde_json::json!({\n    \"name\": \"majordomus_plan_transition\", \"capability\": \"plan.transition\",\n    \"module\": \"plan\", \"title\": \"Move an issue\", \"effect\": \"repository_mutation\",\n    \"hints\": { \"read_only\": false, \"destructive\": true, \"idempotent\": false, \"open_world\": false },\n})).unwrap();\nassert_eq!(t.effect, Effect::RepositoryMutation);\n// the hints are the effect's classification, carried beside it rather than restated\nassert!(t.hints.destructive && !t.hints.read_only && !t.hints.idempotent);\n```",
      "properties": {
        "capability": {
          "description": "The capability it projects; `capabilities.describe` answers its schemas.",
          "type": "string"
        },
        "effect": {
          "$ref": "#/$defs/ExecutionEffect",
          "description": "What a call changes."
        },
        "hints": {
          "$ref": "#/$defs/ExecutionHints",
          "description": "What a caller may assume before calling; the tool's annotations are this value."
        },
        "module": {
          "description": "The module that composes the capability.",
          "type": "string"
        },
        "name": {
          "description": "The name a client calls.",
          "type": "string"
        },
        "title": {
          "description": "The title.",
          "type": "string"
        }
      },
      "required": [
        "name",
        "capability",
        "module",
        "title",
        "effect",
        "hints"
      ],
      "type": "object"
    },
    "McpTransportEntry": {
      "description": "One way a client reaches the server.\n\n```\nuse majordomus_cli::capability::builtin::mcp::McpTransportEntry;\nlet t: McpTransportEntry = serde_json::from_value(serde_json::json!({\n    \"id\": \"stdio\", \"reached_by\": \"majordomus mcp\", \"attached\": 1,\n})).unwrap();\n// a count of sessions at the moment of asking, not a claim that a server is running\nassert_eq!((t.id.as_str(), t.attached), (\"stdio\", 1));\n```",
      "properties": {
        "attached": {
          "description": "Sessions attached to this process over it right now.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "id": {
          "description": "`stdio` or `http`.",
          "type": "string"
        },
        "reached_by": {
          "description": "How it is reached: the command a client starts, or the path on the shared server.",
          "type": "string"
        }
      },
      "required": [
        "id",
        "reached_by",
        "attached"
      ],
      "type": "object"
    }
  },
  "description": "The MCP projection of this registry in this repository.\n\n```\nuse majordomus_cli::capability::builtin::mcp::McpProjection;\nlet p: McpProjection = serde_json::from_value(serde_json::json!({\n    \"server\": { \"name\": \"majordomus\", \"title\": \"Majordomus\", \"version\": \"0.14.0\" },\n    \"protocol_versions\": [\"2025-06-18\"],\n    \"transports\": [{ \"id\": \"stdio\", \"reached_by\": \"majordomus mcp\", \"attached\": 0 }],\n    \"serving\": { \"methods\": [\"initialize\"], \"tools\": true, \"resources\": true, \"prompts\": false, \"notifications\": false },\n    \"tool_count\": 2,\n    \"tools\": [],\n    \"effects\": [{ \"effect\": \"read\", \"tools\": 1 }, { \"effect\": \"repository_mutation\", \"tools\": 1 }],\n    \"writers\": [\"majordomus_plan_transition\"],\n    \"resources\": { \"builtin\": 1, \"objects\": 0, \"template\": \"majordomus://<kind>/<identity>\" },\n    \"launcher_in_repository\": false,\n    \"clients\": [],\n    \"findings\": [],\n})).unwrap();\n// the count is of every tool, whatever the `effect` filter narrowed `tools` to\nassert_eq!(p.tool_count, p.effects.iter().map(|e| e.tools).sum::<usize>());\nassert!(p.tools.is_empty() && p.writers.len() == 1);\n```",
  "properties": {
    "clients": {
      "description": "The clients the distribution declares a configuration for, and where each stands.",
      "items": {
        "$ref": "#/$defs/McpClient"
      },
      "type": "array"
    },
    "effects": {
      "description": "The tools counted by effect, every effect present.",
      "items": {
        "$ref": "#/$defs/McpEffectCount"
      },
      "type": "array"
    },
    "findings": {
      "description": "What a person should act on. Empty is nothing to do.",
      "items": {
        "$ref": "#/$defs/McpFinding"
      },
      "type": "array"
    },
    "launcher_in_repository": {
      "description": "Whether this repository carries the launcher at `bin/majordomus-mcp`. Where it does\nnot, the installed command of the same name is what a configuration names.",
      "type": "boolean"
    },
    "protocol_versions": {
      "description": "The protocol versions accepted, newest first.",
      "items": {
        "type": "string"
      },
      "type": "array"
    },
    "resources": {
      "$ref": "#/$defs/McpResourceSummary",
      "description": "The resources."
    },
    "server": {
      "$ref": "#/$defs/McpServerIdentity",
      "description": "Who answers `initialize`."
    },
    "serving": {
      "$ref": "#/$defs/McpServing",
      "description": "What of the protocol is served."
    },
    "tool_count": {
      "description": "How many tools the registry projects, whatever the filter asked for.",
      "format": "uint",
      "minimum": 0,
      "type": "integer"
    },
    "tools": {
      "description": "The tools asked for, in registry order.",
      "items": {
        "$ref": "#/$defs/McpToolEntry"
      },
      "type": "array"
    },
    "transports": {
      "description": "How a client reaches the server.",
      "items": {
        "$ref": "#/$defs/McpTransportEntry"
      },
      "type": "array"
    },
    "writers": {
      "description": "The tools that write the repository, by name. The `initialize` instructions name the\nsame ones.",
      "items": {
        "type": "string"
      },
      "type": "array"
    }
  },
  "required": [
    "server",
    "protocol_versions",
    "transports",
    "serving",
    "tool_count",
    "tools",
    "effects",
    "writers",
    "resources",
    "launcher_in_repository",
    "clients",
    "findings"
  ],
  "title": "McpProjection",
  "type": "object"
}

Politiky

benchmark
povinné — cíl na každém transportu, který expozice deklaruje; případy jsou ty ze vstupního typu
cache
vypnuto — každé volání spustí handler

Cíle benchmarku

Odvozeno z registru pro tento repozitář: jeden požadavek na transport a případy, které poskytuje typ vstupu. Celá matice je na stránce měření výkonu.

transportstatepřípadytargets
directpokryto2every-tool
zapisovatelé
mcppokryto2every-tool
zapisovatelé
httppokryto2every-tool
zapisovatelé

Prohledává názvy a popisy všech stránek, které tento web publikuje.