> ## Documentation Index
> Fetch the complete documentation index at: https://developers.semji.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure Semji MCP server toolsets and read-only scope

> Scope the Semji MCP server URL to specific toolsets like planning, content-generation, and knowledge-base, with an optional read-only mode.

The Semji MCP server exposes a growing catalogue of tools. You can scope a
connection to just the toolsets you need — and optionally make it read-only —
directly from the server URL. This keeps the assistant's tool list focused and
lets you hand out narrower connections for governance.

The scope lives in the URL, so it is read on every request. To change scope,
update the connector URL and reconnect (see [Connect to Semji](/mcp/connecting)).
You can also register several connectors, each with a different scope.

## Build your URL

export const McpUrlBuilder = () => {
  const TOOLSETS = [{
    name: "planning",
    label: "Planning",
    desc: "Drafts, folders, keywords"
  }, {
    name: "content-generation",
    label: "Content Generation",
    desc: "Generate content (Atomic Content)"
  }, {
    name: "content",
    label: "Content Hub",
    desc: "Pages & performance"
  }, {
    name: "geo",
    label: "Intelligence Hub GEO",
    desc: "Prompts, prompt responses & sources"
  }, {
    name: "seo",
    label: "Intelligence Hub SEO",
    desc: "Pages Data Explorer"
  }, {
    name: "ideas",
    label: "Content Ideas",
    desc: "Search & results"
  }, {
    name: "brand-voice",
    label: "Brand Voices",
    desc: "Tone & style"
  }, {
    name: "editor",
    label: "Editor",
    desc: "Comments"
  }, {
    name: "agents",
    label: "Agents",
    desc: "Runs & outputs"
  }, {
    name: "settings",
    label: "Settings",
    desc: "Users, roles & statuses"
  }, {
    name: "knowledge-base",
    label: "Knowledge Base",
    desc: "Entries & content"
  }];
  const ALL_NAMES = TOOLSETS.map(t => t.name);
  const [selected, setSelected] = useState(() => Object.fromEntries(ALL_NAMES.map(n => [n, true])));
  const [readOnly, setReadOnly] = useState(false);
  const [open, setOpen] = useState(false);
  const [copied, setCopied] = useState(false);
  const chosen = TOOLSETS.filter(t => selected[t.name]);
  const chosenNames = chosen.map(t => t.name);
  const isAll = chosenNames.length === ALL_NAMES.length;
  const params = [];
  if (chosenNames.length > 0 && !isAll) params.push("toolsets=" + chosenNames.join(","));
  if (readOnly) params.push("read_only=true");
  const url = "https://mcp.semji.com/mcp" + (params.length ? "?" + params.join("&") : "");
  const toggle = name => setSelected(s => ({
    ...s,
    [name]: !s[name]
  }));
  const copy = () => {
    navigator.clipboard.writeText(url);
    setCopied(true);
    setTimeout(() => setCopied(false), 1500);
  };
  return <div className="mcpb">
      <div className="mcpb-row">
        <div style={{
    flex: "0 0 auto"
  }}>
          <div className="mcpb-label">Read-only</div>
          <button className="mcpb-toggle" role="switch" aria-checked={readOnly} aria-label="Read-only" onClick={() => setReadOnly(v => !v)}>
            <span className="mcpb-knob" />
          </button>
        </div>

        <div className="mcpb-toolsets">
          <div className="mcpb-label">Toolsets</div>
          <button className="mcpb-control" aria-haspopup="listbox" aria-expanded={open} onClick={() => setOpen(o => !o)}>
            <span className="mcpb-chips">
              {chosen.length === 0 ? <span className="mcpb-placeholder">all toolsets (default)</span> : chosen.map(t => <span key={t.name} className="mcpb-chip">
                    {t.label}
                    <span className="mcpb-chip-x" role="button" aria-label={"Remove " + t.label} onClick={e => {
    e.stopPropagation();
    toggle(t.name);
  }}>
                      ×
                    </span>
                  </span>)}
            </span>
            <svg className="mcpb-caret" width="14" height="14" viewBox="0 0 256 256">
              <path d="M80 176l48 48 48-48M80 80l48-48 48 48" fill="none" stroke="currentColor" strokeWidth="20" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </button>

          {open && <>
              <div className="mcpb-backdrop" onClick={() => setOpen(false)} />
              <div className="mcpb-pop" role="listbox">
                {TOOLSETS.map(t => <label key={t.name} className="mcpb-opt" data-selected={selected[t.name] ? "true" : "false"}>
                    <span className="mcpb-opt-title">
                      <input type="checkbox" checked={!!selected[t.name]} onChange={() => toggle(t.name)} />
                      <strong>{t.label}</strong>
                    </span>
                    <span className="mcpb-opt-desc">{t.desc}</span>
                  </label>)}
              </div>
            </>}
        </div>
      </div>

      <div className="mcpb-block">
        <div className="mcpb-label">Server URL</div>
        <div className="mcpb-urlrow">
          <input className="mcpb-input" readOnly value={url} />
          <button className="mcpb-copy" onClick={copy}>
            {copied ? "Copied" : "Copy"}
          </button>
        </div>
        {chosen.length === 0 && <p className="mcpb-note">
            No toolset selected — the URL exposes the full catalogue (every toolset).
          </p>}
      </div>
    </div>;
};

<McpUrlBuilder />

## Query parameters

| Param       | Values                                                                                                                                               | Default               | Behaviour                                                                                                                                                                                                 |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `toolsets`  | CSV of `planning`, `content-generation`, `content`, `geo`, `seo`, `ideas`, `brand-voice`, `editor`, `agents`, `settings`, `knowledge-base`, or `all` | `all` (every toolset) | Only the tools of the listed toolsets appear in the tool list and are callable. Unknown names are ignored. A bare URL, an empty value, and `all` are equivalent — every toolset is exposed (the default). |
| `read_only` | `true` / `false`                                                                                                                                     | `false`               | When `true`, every write tool is removed and refused. Orthogonal to `toolsets`. Any value other than `true` means `false`.                                                                                |

The URL can only restrict access — it never grants more than your Semji account
already allows. Identity, organization, and permissions come from sign-in, not
from the URL.

## Examples

```text Default (all toolsets) theme={null}
https://mcp.semji.com/mcp
```

```text GEO + SEO analytics theme={null}
https://mcp.semji.com/mcp?toolsets=geo,seo
```

```text Everything, read-only theme={null}
https://mcp.semji.com/mcp?toolsets=all&read_only=true
```

<Note>
  Changing scope means updating the connector URL and reconnecting. Connections
  do not re-prompt on their own. You can keep several connectors side by side,
  each scoped differently.
</Note>

Use the URL above wherever [Connect to Semji](/mcp/connecting) tells you to paste
`https://mcp.semji.com/mcp` — for example in Claude Code:

```bash theme={null}
claude mcp add --transport http semji "https://mcp.semji.com/mcp?toolsets=geo,seo"
```
