feat(mcp): mcp 独立应用与 /mcp Streamable HTTP 端点(官方 SDK + PSR-7 桥接)

This commit is contained in:
augushong
2026-08-16 22:15:19 +08:00
parent 1ab276b1e9
commit c21bf9f240
9 changed files with 489 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
<?php
declare(strict_types=1);
namespace base\mcp\service;
use Psr\SimpleCache\CacheInterface;
use think\cache\Driver;
use think\facade\Cache;
/**
* think Cache 驱动的 PSR-16 薄适配器.
*
* mcp/sdk 的 Psr16SessionStore 需要 Psr\SimpleCache\CacheInterface 实现,
* think cache Driver 方法集与 PSR-16 同形get/set/delete/clear/has/*Multiple
* 本类只做签名收紧与 TTL 归一int|DateInterval|null → 秒),全部转发给
* defaultStore() 指定的 think 缓存 store。
*
* 子类app 壳)覆写 defaultStore() 返回 'mcp_session' 等具体 store 名。
*/
class Psr16ThinkCacheBase implements CacheInterface
{
protected Driver $driver;
public function __construct(?Driver $driver = null)
{
$this->driver = $driver ?? Cache::store($this->defaultStore());
}
/**
* 默认 think 缓存 store 名(子类覆写).
*/
protected function defaultStore(): string
{
return 'file';
}
public function get(string $key, mixed $default = null): mixed
{
return $this->driver->get($key, $default);
}
public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool
{
return (bool) $this->driver->set($key, $value, $this->normalizeTtl($ttl));
}
public function delete(string $key): bool
{
return (bool) $this->driver->delete($key);
}
public function clear(): bool
{
return (bool) $this->driver->clear();
}
public function getMultiple(iterable $keys, mixed $default = null): iterable
{
$keys = is_array($keys) ? $keys : iterator_to_array($keys, false);
$result = [];
foreach ($keys as $key) {
$result[$key] = $this->driver->get($key, $default);
}
return $result;
}
public function setMultiple(iterable $values, null|int|\DateInterval $ttl = null): bool
{
$ttl = $this->normalizeTtl($ttl);
$result = true;
foreach ($values as $key => $value) {
if (!$this->driver->set((string) $key, $value, $ttl)) {
$result = false;
}
}
return $result;
}
public function deleteMultiple(iterable $keys): bool
{
$result = true;
foreach ($keys as $key) {
if (!$this->driver->delete($key)) {
$result = false;
}
}
return $result;
}
public function has(string $key): bool
{
return (bool) $this->driver->has($key);
}
/**
* PSR-16 TTL 归一为秒DateInterval 折算秒数null 视为 0think 驱动默认有效期0=永久).
*/
protected function normalizeTtl(null|int|\DateInterval $ttl): int
{
if ($ttl instanceof \DateInterval) {
$now = new \DateTimeImmutable('@' . time());
return max(0, $now->add($ttl)->getTimestamp() - $now->getTimestamp());
}
return max(0, (int) ($ttl ?? 0));
}
}